我正在编写一个用Apache POI eventmodel(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);
我应该以{{1}}传递什么才能获得正确的日期?
暂时我使用use1904windowing
,因为这给了我测试工作簿的正确日期,但我知道我应该从某处读取该值。
二进制xls格式有一个记录false
,我用HSSF读取。它与XSSF的对应关系是什么?
或者我应该始终使用DateWindow1904Record
?
修改: @rgettman回答指出了我的解决方案,但它并不完整。 在事件模型中,你没有xssfWorkbook对象,你不能只是获取它的CTWorkbook()。
相反,您可以直接从InputStream创建CTWorkbook:
false
答案 0 :(得分:4)
可以确定是否在XSSF中设置了1904日期格式。不幸的是,protected
在XSSFWorkbook
中为XSSFWorkbook
。但是有一种解决方法,因为boolean isDate1904 = false;
CTWorkbook internalWorkbook = xssfWorkbook.getCTWorkbook();
CTWorkbookPr workbookPr = internalWorkbook.getWorkbookPr();
if (workbookPr != null)
{
isDate1904 = workbookPr.getDate1904();
}
使用isDate1904()
方法公开其底层XML bean。
date1904
此代码检查基础XML bean以确定它是否设置了CTWorkbookPr
属性。也可以使用setDate1904(boolean)
方法使用相同的XML bean({{1}})设置该标志。
答案 1 :(得分:4)
编辑部分中描述的代码编译,但始终在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();