为什么Apache POI OPCPackage close()方法不能保存/写入打开可写文件的内容?

Dan*_*eid 6 java excel apache-poi xssf

使用以下代码,不会保存对Excel电子表格所做的单元格值更改:

OPCPackage pkg = OPCPackage.open(inputFile);
XSSFWorkbook wb = new XSSFWorkbook(pkg);

ModifyWorkbook();

pkg.close();
Run Code Online (Sandbox Code Playgroud)

以下是我写的解决方法,但我不明白为什么这是必要的.

OPCPackage pkg = OPCPackage.open(inputFile);
XSSFWorkbook wb = new XSSFWorkbook(pkg);

ModifyWorkbook();

File tmp = File.createTempFile("tempSpreadsheet", ".xlsx");
FileOutputStream newExcelFile = new FileOutputStream(tmp);
wb.write(newExcelFile);
newExcelFile.close();
tmp.deleteOnExit();
pkg.close();
Run Code Online (Sandbox Code Playgroud)

关于主题的javadoc和指南表明.close()方法应该保存并关闭.在关闭之前检查已修改的单元格的值是否表示已进行更改,但单独使用pkg.close()方法不足以在关闭时将这些更改写入文件.

小智 1

调用close(XSSF)Workbook 将调用 OPCP.close,javadoc 指出:

调用myWorkbook.close()应将更改写入从中打开的文件。

然而,当前版本(3.15)似乎这样做有问题。我不知道原因本身,但我发现调用myWorkbook.write()不仅会提交对输出流的更改,还会在调用 close 后提交到当前实例。

因此,合理的解决方法可能是:

try (OutputStream bos = ByteStreams.nullOutputStream()){
    workbook.write(bos);
    workbook.close();
} catch (IOException e) {
    log.error("Could not write Output File", e);
}
Run Code Online (Sandbox Code Playgroud)

这里用Guavas ByteStreams完成。请随意使用其他空输出流实现。