首页 > 解决方案 > 即使在执行 fileoutputstream.close() 之后,Apache-POI 也没有保存 excel 工作簿

问题描述

我正在尝试基于通用模板生成新的 excel 文件。我正在打开模板 excel 文件,对其进行编辑并将其保存在新位置。要写入文件,我正在使用 FileOutputStream 并且在写入后关闭流以保存它。整个过程正常,但是新创建的excel文件没有正确保存。我的模板文件为 35kb,而我新创建的 excel 文件仅显示 30kb。当我打开新创建的excel文件时,可以看到写入的数据,我需要保存并关闭它以反映正确的36kb大小。
新的excel需要上传到外部应用程序,直接上传30kb未保存的excel时显示“找不到数据”,而36kb保存的文件成功上传文件。

我尝试了互联网上建议的各种不同方法来做同样的事情,但它们都没有生成正确的 excel 文件。我正在使用 java 1.7 和 apache-poi 3.17 版。

以下是我的代码示例:-

public void createExcelFiles() throws ParseException, IOException {

    File file = new File(ExcelTemplatePath);
    FileInputStream fip = new FileInputStream(file);
    FileOutputStream fos = new FileOutputStream(excelOutputFile);

    XSSFWorkbook workbookOld = new XSSFWorkbook(fip);
    try (SXSSFWorkbook workbook = new SXSSFWorkbook(workbookOld, rowAccessWindowSize)) {

        if (makeLargeFiles) {
            SXSSFSheet sheet = (SXSSFSheet) workbook.getSheetAt(0);
            makeExcelFile.makeLargeFile(sheet);
            workbook.write(fos);
        } else {
            Sheet sheet = workbookOld.getSheetAt(0);
            makeExcelFile.makeNormalFile(sheet);
            workbookOld.write(fos);

        }
        fos.close();
        fip.close();
        workbook.close();
    }
    workbookOld.close();

}

标签: javaexcelapache-poi

解决方案


包装的 I/O 流XSSFWorkbook应该首先关闭,可能仍在向包装的 OutputStream 写入结尾。并且可能会关闭低级流。

请注意,一些包装类会在它们自己的内部关闭包装的流close

由于 try-with-resources 是理想的,在出现异常时也关闭,最终版本将是:

public void createExcelFiles() throws ParseException, IOException {
    File file = new File(ExcelTemplatePath);
    try (FileInputStream fip = new FileInputStream(file);
            FileOutputStream fos = new FileOutputStream(excelOutputFile);
            XSSFWorkbook workbookOld = new XSSFWorkbook(fip);
            SXSSFWorkbook workbook = new SXSSFWorkbook(workbookOld, rowAccessWindowSize)) {

        if (makeLargeFiles) {
            SXSSFSheet sheet = (SXSSFSheet) workbook.getSheetAt(0);
            makeExcelFile.makeLargeFile(sheet);
            workbook.write(fos);
        } else {
            Sheet sheet = workbookOld.getSheetAt(0);
            makeExcelFile.makeNormalFile(sheet);
            workbookOld.write(fos);

        }
    }
    // Doing in reverse order of declaration:
    // 1. workbook.close();
    // 2. workbookOld.close();
    // 3. fos.close();
    // 4. fip.close();
}

在您的代码中有一个逆转,并且通过 try-with-resources 明确地发生了关闭。


推荐阅读