jExcelApi – 单元格date格式重用不起作用

我创build了一个jExcelApi类的包装器来轻松地将对象列表导出到Excel。 为了最小化对象创build,单元格格式创build为静态字段,并在连续调用中重复使用以导出。 但我有date格式的问题 – 第一个调用工作正常,但在所有连续导出date单元格具有数字格式,而不是date格式。 如果我为date格式创build一个新的对象,而不是使用静态字段,一切都很好。 对于不同的工作表或工作簿使用相同的格式对象是否有任何原因?
这里是代码,exception处理简化,其他数据types省略,可能一些import缺less:

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的回答是有帮助的,说明这是一个function,而不是一个错误,但没有给予任何常见问题或文档的链接。 所以我做了一些研究,发现了一个FAQ :

另外, 不要将单元格格式声明为静态 。 由于单元格格式被添加到工作表,因此会为其分配一个内部索引编号。

所以答案是:格式不能在不同的表格中重复使用,因为它们不能被重复使用。

在jxl格式中,对象不能在多个工作簿中重复使用。 我不知道为什么。

实际上比这更糟糕。 字体和格式隐含地依赖于“工作簿”。 哪个工作手册说明问题的问题。 他们似乎需要在创build后续工作簿后重新分配。

  final WritableWorkbook workbook = Workbook.createWorkbook(response .getOutputStream()); // We have to assign this every time we create a new workbook. bodyText = new WritableCellFormat(WritableWorkbook.ARIAL_10_PT); ... 

API应该被改变,以便构造函数需要作为它们相关的工作簿的参数,或者构造函数应该是私有的,字体和格式应该从工作簿中获得。

  WritableCellFormat bodyText = new WritableCellFormat(workbook, WritableWorkbook.ARIAL_10_PT); 

要么

  WritableCellFormat bodyText = workbook.getCellFormat( WritableWorkbook.ARIAL_10_PT); 

你可以试试SmartXLS ,单元格格式可以在你想要的任何地方重复使用。