我为jExcelApi类创建了一个包装器,以轻松地将对象列表导出到Excel。为了最大程度地减少对象创建,单元格格式将创建为静态字段,并在连续的导出调用中重用。但是我在使用日期格式时遇到了问题-
第一个调用的效果很好,但是在所有连续的导出中,日期单元格都使用数字格式而不是日期格式。如果我为日期格式创建了一个新对象而不是使用静态字段,那么一切都很好。是否有理由将相同格式的对象用于不同的工作表或工作簿失败?
这是代码,简化了异常处理,省略了其他数据类型,并且可能缺少一些导入:
ExcelCellGenerator.java:
import jxl.write.WritableCell;
public interface ExcelCellGenerator<T> {
WritableCell getCell(int col, int row, T arg);
}
ExcelCellGeneratorFactory.java:
import jxl.write.DateFormat;
import jxl.write.DateTime;
import jxl.write.Label;
import jxl.write.NumberFormat;
import jxl.write.NumberFormats;
import jxl.write.WritableCell;
import jxl.write.WritableCellFormat;
import ExcelExporter.DateTimeExtractor;
final class ExcelCellGeneratorFactory {
private ExcelCellGeneratorFactory() {}
private static final WritableCellFormat DATE_FORMAT = new WritableCellFormat ( new DateFormat ("dd MMM yyyy hh:mm:ss")); // reusing this field fails
static public <T> ExcelCellGenerator<T> createDateCellGenerator(final DateTimeExtractor<T> extractor) {
return new ExcelCellGenerator<T>() {
public WritableCell getCell(int col, int row, T arg) {
return new DateTime(col, row, extractor.extract(arg), DATE_FORMAT);
// if there is new WritableCellFormat(new DateFormat(...)) instead of DATE_FORMAT, works fine
}
};
}
}
ExcelExporter.java:
import jxl.Workbook;
import jxl.write.DateFormat;
import jxl.write.DateTime;
import jxl.write.Label;
import jxl.write.NumberFormat;
import jxl.write.WritableCellFormat;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
public class ExcelExporter<T> {
// describe a column in Excel sheet
private static class ColumnDescription<T> {
public ColumnDescription() {}
// column title
private String title;
// a way to generate a value given an object to export
private ExcelCellGenerator<T> generator;
}
// all columns for current sheet
private List<ColumnDescription<T>> columnDescList = new ArrayList<ColumnDescription<T>>();
// export given list to Excel (after configuring exporter using addColumn function
// in row number rowStart starting with column colStart there will be column titles
// and below, in each row, extracted values from each rowList element
public byte[] exportList(int rowStart, int colStart, List<? extends T> rowList) {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
WritableWorkbook workbook;
try {
workbook = Workbook.createWorkbook(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
final WritableSheet sheet = workbook.createSheet("Arkusz1", 0);
int currRow = rowStart;
try {
int currCol = colStart;
for (ColumnDescription<T> columnDesc : columnDescList) {
final Label label = new Label(currCol, currRow, columnDesc.title);
sheet.addCell(label);
currCol++;
}
currRow++;
for (T object : rowList) {
currCol = colStart;
for (ColumnDescription<T> columnDesc : columnDescList) {
sheet.addCell(columnDesc.generator.getCell(currCol, currRow, object));
currCol++;
}
currRow++;
}
workbook.write();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
workbook.close();
} catch (Exception e) {
e.printStackTrace();
}
}
return outputStream.toByteArray();
}
// configure a Date column
public ExcelExporter<T> addColumn(String title, DateTimeExtractor<T> extractor) {
final ColumnDescription<T> desc = new ColumnDescription<T>();
desc.title = title;
desc.generator = ExcelCellGeneratorFactory.createDateCellGenerator(extractor);
columnDescList.add(desc);
return this;
}
// and test that shows the problem
public static void main(String []args) {
final ExcelExporter<Date> exporter = new ExcelExporter<Date>();
exporter.addColumn("Data", new DateTimeExtractor<Date>() {
public Date extract(Date date) {
return date;
}});
// this file looks OK
FileOutputStream ostream = new FileOutputStream("C:\\tmp\\test1.xls");
try {
ostream.write(exporter.exportList(0, 0, Collections.singletonList(new Date())));
} finally {
ostream.close();
}
// but in this file date is shown in cell with numeric format
final ExcelExporter<Date> exporter2 = new ExcelExporter<Date>();
exporter2.addColumn("Data", new DateTimeExtractor<Date>() {
public Date extract(Date date) {
return date;
}});
ostream = new FileOutputStream("C:\\tmp\\test2.xls");
try {
ostream.write(exporter2.exportList(0, 0, Collections.singletonList(new Date())));
} finally {
ostream.close();
}
}
}
Telcontar的回答很有帮助,因为它说明它是一项功能,而不是错误,但还不足以提供任何指向FAQ或doc的链接。因此,我进行了一些研究,发现了一个常见问题解答,内容如下:
同样, 不要 将单元格格式声明为 static 也是很重要的。当单元格格式添加到工作表时,将为其分配一个内部索引号。
因此,答案是-格式不能在不同的工作表中重复使用,因为它们并非设计为可以这种方式重复使用。
我正在尝试将字符串转换为日期,我希望该日期的格式为“yyyy-MM-d HH:MM:ss”,我不知道如何将该格式转换为字符串。我的问题是,我希望以上述格式获取日期,而不是字符串,而是“date”? 我是这样做的 通过使用上述代码,我以以下格式获取日期 但我希望日期格式为 注意:我希望此结果作为日期而不是字符串 请给我解决方案谢谢......
我正在尝试将时间戳值转换为twig文件中的日期格式,但出现以下错误。 错误: 在呈现模板期间引发了异常(“DateTime::\构造():无法分析时间字符串(
我正在尝试将DatePicker日期格式化为简单的数据格式(“yyyy-MM-dd HH: mm: ss Z”)。有人告诉我,我需要使用简单的数据格式将其解析为日期对象-简单的数据格式(“yyyy-MM-dd”),然后将其格式化为我需要的内容,如下所示。但是,我在尝试捕捉块中收到错误“重复局部变量eDate”。任何专家都可以查看我的代码并提出建议吗? 已更新
我有下面这样的jaxb类,我希望我的xmlAdapter格式化日期值,我得到了异常? 原因:java。lang.RuntimeException:com。太阳xml。绑定v2。运行时。IllegalAnnotationsException:1 IllegalAnnotationExceptions计数无效@XmlElementRef:Type“class java.lang.String”或其任何
我已经尝试在表视图单元格中硬编码行高。运行程序后,它看起来只有一行。我怀疑这是因为表视图的行的高度。 你能告诉我这里出了什么问题吗?
设定年月日的排列顺序。