7

我正在编写一个使用 Apache POI 事件模型(SAX/XSSF)导入 xlsx 文件的程序。我快完成了,但我无法得到正确的日期。

我正在解析具有日期值的单元格

<c r="D1" s="1">
    <v>41319.558333333334</v>
</c>

我正在使用org.apache.poi.ss.usermodel.DateUtil课程来获取日期:

DateUtil.getJavaCalendar(doble date, bool use1904windowing);

我应该通过什么use1904windowing来获得正确的日期?我暂时使用false,因为这为我的测试工作簿提供了正确的日期,但我知道我应该从某个地方读取该值。

有一条DateWindow1904Record二进制 xls 格式的记录,我使用 HSSF 读取。它在 XSSF 中的对应物是什么?还是我应该一直使用false

编辑:@rgettman 回答为我指出了解决方案,但它并不完整。在事件模型中,您没有 xssfWorkbook 对象,您不能只获取它的 getCTWorkbook()。

相反,您可以直接从 InputStream 创建 CTWorkbook:

OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
InputStream workbookXml = r.getWorkbookData();
CTWorkbook ctWorkbook = CTWorkbook.Factory.parse(workbookXml);
boolean isDate1904 = ctWorkbook.getWorkbookPr().getDate1904();
4

2 回答 2

5

编辑部分中描述的代码可以编译,但在 POI 3.9 中始终返回 null CTWorkbookPr 下面的代码实际上解析了工作簿前缀:

OPCPackage pkg = OPCPackage.open(filename);
XSSFReader r = new XSSFReader( pkg );
InputStream workbookXml = r.getWorkbookData();
WorkbookDocument doc = WorkbookDocument.Factory.parse(workbookXml);
CTWorkbook wb = doc.getWorkbook();
CTWorkbookPr prefix = wb.getWorkbookPr();
boolean isDate1904 = prefix.getDate1904();
pkg.close();
于 2013-08-12T17:54:29.900 回答
4

可以确定 XSSF 中是否设置了 1904 日期格式。不幸的isDate1904()protected,在XSSFWorkbook. 但是有一个变通方法,因为XSSFWorkbook使用该方法公开了其底层 XML bean,因此成为可能getCTWorkbook()

boolean isDate1904 = false;
CTWorkbook internalWorkbook = xssfWorkbook.getCTWorkbook();
CTWorkbookPr workbookPr = internalWorkbook.getWorkbookPr();
if (workbookPr != null)
{
    isDate1904 = workbookPr.getDate1904();
}

此代码检查底层 XML bean 以确定date1904它是否设置了属性。也可以CTWorkbookPr使用该方法使用相同的 XML bean ( )设置该标志setDate1904(boolean)

于 2013-04-18T17:17:38.713 回答