Apache POI到Excel – 零date

在回答之前,请确保您了解我的问题,但并不像看起来那么简单。 请不要只是做一个谷歌search和链接的结果; 我已经看了。

我有一个VB.Net应用程序,我们用一个Java应用程序来取代。 该应用程序的目的是编写一个Excel表(.xls)。 该文件然后被发送到第二方,并处理其中的数据。 我正在使用APACHE POI来编写文件。

最终的产品被第二方拒绝,因为两个时间字段是“无效的”。 抓了我一会儿之后,我注意到Java生成的文件和VB.Net生成的文件正在处理0date值不同。 假设时间是军事时间的下午3点30分,两个文件的数据显示为15点30分。 问题是该字段的date部分:
VB.Net生成:1/0/1900 15:30
Java生成:1/1/1970 15:30

我似乎无法find一种方法来使apache POI模仿excel处理0date的方式。 以下是我尝试的一些事情。
我在java应用程序中将我的date/时间variables设置为1/0/1900 15:30。 这给我在应用程序中的错误。
我将我的variables设置为一个string,并将其传递给工作表,然后设置单元格的格式。 我没有得到一个错误,但数据保持“一般”,直到我双击单元格,然后按Enter键。 这个过程假定是自动的,所以这不是一个选项。
我将单元格的公式设置为= TIMEVALUE(“15:30”),但是这不被第二方接受。

有没有人遇到这个问题? 任何人都可以想办法解决这个问题吗? 让第二方改变他们阅读文件的方式不是一种select。

您需要知道的是, Excel将date时间值存储为浮点双精度值。 有0 = 00:00:00和1 = 24:00:00 = 01/01/1900 00:00:00。 另外0.5 = 12:00:00和1.5 = 36:00:00 = 01/01/1900 12:00:00。 换句话说, Excel的date时间值是从0开始的,1是1天,并且是01/01/1900。 1/24是1小时,1/24/60是1分钟,1/24/60/60是1秒。

使用Java Date的问题是Calendar构造函数中的月份是基于0的。 因此,0月份是1月, new GregorianCalendar(1900, 0, 1, 15, 30, 0) 1900,0,1,15,30,0 new GregorianCalendar(1900, 0, 1, 15, 30, 0)将是01/01/1900 15:30:00。 而且没有第0天,所以new GregorianCalendar(1900, 0, 0, 15, 30, 0) 1900,0,0,15,30,0 new GregorianCalendar(1900, 0, 0, 15, 30, 0)将是12/31/1899 15:30:00,这将是Excel的-1。

由于Exceldate行为的问题是已知的,所以apache poi提供了DateUtil 。

使用这个我们可以这样做:

 import java.io.*; import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.util.Calendar; import java.util.GregorianCalendar; class XSSFNullDateTest { public static void main(String[] args) { try { Workbook wb = new XSSFWorkbook(); Sheet sheet = wb.createSheet("Sheet1"); CreationHelper creationHelper = wb.getCreationHelper(); CellStyle cellStyleTime = wb.createCellStyle(); cellStyleTime.setDataFormat(creationHelper.createDataFormat().getFormat("hh:mm:ss")); //using a Calendar: Calendar calendar = new GregorianCalendar(1900, 0, 1, 15, 30, 0); System.out.println(calendar.getTime()); //01/01/1900 15:30:00 double doubleTime = DateUtil.getExcelDate(calendar, false); System.out.println(doubleTime); //1.6458333333333335 Cell cell = sheet.createRow(0).createCell(0); cell.setCellValue(doubleTime-1); //subtract 1 so we have day 0 cell = sheet.getRow(0).createCell(1); cell.setCellValue(doubleTime-1); //subtract 1 so we have day 0 cell.setCellStyle(cellStyleTime); //using a string: doubleTime = DateUtil.convertTime("15:30:00"); System.out.println(doubleTime); //0.6458333333333334 = day 0 already cell = sheet.createRow(1).createCell(0); cell.setCellValue(doubleTime); cell = sheet.getRow(1).createCell(1); cell.setCellValue(doubleTime); cell.setCellStyle(cellStyleTime); OutputStream out = new FileOutputStream("XSSFNullDateTest.xlsx"); wb.write(out); wb.close(); } catch (Exception ex) { ex.printStackTrace(); } } }