我使用的 xlsx 文件包含DATE(year, month, day)单元格内的公式。该单元格的格式为日期,因此 Excel/OpenOffice 显示正确的日期。例如,细胞内容'=DATE(2013;1;1)'产生:'01.01.2013'
到目前为止 - 很好。
当使用 poi 库读取此文件时,我会执行以下操作:
XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File("/home/detlef/temp/test.xlsx")));
XSSFSheet sheet = workbook.getSheet("Sheet A");
XSSFCell cell = sheet.getRow(0).getCell(0);
System.out.println(cell.getDateCellValue());
Run Code Online (Sandbox Code Playgroud)
这将打印出:
Sun Dec 31 00:00:00 CET 1899
Run Code Online (Sandbox Code Playgroud)
我使用的是 POI 3.9。
谁能告诉我为什么会发生这种情况?
找到了一种方法来做到这一点:
if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
CellValue evaluate = evaluator.evaluate(cell);
Date date = DateUtil.getJavaDate(evaluate.getNumberValue());
System.out.println(date);
}
Run Code Online (Sandbox Code Playgroud)
这会产生:
Tue Jan 01 00:00:00 CET 2013
Run Code Online (Sandbox Code Playgroud)
不管怎么说,还是要谢谢你。
您所描述的一切都是完全正确且符合预期的
当 Excel 在单元格中存储公式时,它不仅存储公式本身(.xlsx 中的字符串,或 .xls 的解析标记形式),还存储该公式的最后计算的答案。这意味着当 Excel 加载时,它不必花很长时间计算要显示的公式结果,它可以像任何其他单元格一样使用最后一个值来呈现它们。
这就是为什么当您使用 Apache POI 更改 Excel 文件时,您需要运行评估来更新所有这些缓存的公式值,以便在您转到该单元格之前它在 Excel 中看起来正确
然而,Excel中有一些特殊的公式函数,它们被定义为易失性的。这些函数每次总是返回不同的值,例如DATE这些函数,Excel 只是将虚拟值(例如 0 或 -1)写入单元格,并在加载时重新评估它
当您读取 POI 中公式单元格的数值时,它会返回缓存的值。如果您希望 POI 评估公式,您需要要求它,就像您正在做的那样
Excel 中的日期存储为自 1/1/1900 或 1/1/1904(取决于标志)以来的小数天数。值 -1 是 1899 年 12 月 31 日,因此这就是当 Excel 写入 -1 并且您请求将其作为日期时看到的结果
| 归档时间: |
|
| 查看次数: |
2392 次 |
| 最近记录: |