java - Apache poi 文件损坏且无法写入现有工作簿

标签 java excel apache-poi

我正在尝试使用以下代码来读取和写入工作簿:

public static void main(String args[]) {
    String absoluteFilePath = System.getProperty("user.dir") + File.separator + "abc.xlsx";
    System.out.println("Readin file : " + absoluteFilePath);

    Workbook workbook = null;

    try {
        workbook = WorkbookFactory.create(new File(absoluteFilePath));

        //reading and writing on sheets of workbook


        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            System.out.println("Writing to workbook and Closing the file");
            FileOutputStream fileOutputStream = new FileOutputStream(
                    new File(absoluteFilePath));
            workbook.write(fileOutputStream);
            fileOutputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

当我第一次运行代码时,我在 workbook.write(fileOutputStream);

处收到此异常
Exception in thread "main" org.apache.poi.POIXMLException: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
    at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:148)
    at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:199)
    at NewNewDriver.main(NewNewDriver.java:129)
Caused by: java.io.IOException: Can't obtain the input stream from /docProps/app.xml
    at org.apache.poi.openxml4j.opc.PackagePart.getInputStream(PackagePart.java:500)
    at org.apache.poi.POIXMLProperties.<init>(POIXMLProperties.java:75)
    at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:146)
    ... 2 more

此后,工作簿被损坏,大小减少到 0kb,并且在 WorkbookFactory.create() 上出现此异常:

org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature; read 0x0000000000000000, expected 0xE11AB1A1E011CFD0 - Your file appears not to be a valid OLE2 document
    at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:167)
    at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:117)
    at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:225)
    at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:164)
    at org.apache.poi.poifs.filesystem.NPOIFSFileSystem.<init>(NPOIFSFileSystem.java:145)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:105)
    at NewNewDriver.main(NewNewDriver.java:27)
Closing the file
Exception in thread "main" java.lang.NullPointerException
    at NewNewDriver.main(NewNewDriver.java:129)

我应该在哪里以及如何使用 FileOutputStream、workbook.write(),即使我使用 WorkbookFactory,我也应该使用 FileInputStream 吗?

------------编辑----------------------我的代码工作了 我使用 FileInputStream 而不是 WorkbookFactory 来创建工作簿,并在关闭 FileOutputStream 后关闭它。这有效。

最佳答案

我想我已经发现了你的问题:

workbook = WorkbookFactory.create(new File(absoluteFilePath));

....

FileOutputStream fileOutputStream = new FileOutputStream(
                new File(absoluteFilePath));
workbook.write(fileOutputStream);

您正在打开一个文件,然后在文件仍处于打开和使用状态时尝试覆盖它,但这是不受支持的

您需要做的是将更新后的文件写入不同的文件名。如果您想替换它,则需要在关闭原始文件后执行第二步。

就目前情况而言,您已经开始覆盖该文件,然后 POI 尝试将原始文件的某些部分复制到新文件,但失败了,因为它尝试读取的原始文件已被破坏!

(底层封装代码NPOIFSFileSystem和OPCPackage都支持就地写入和就地更新,但HSSFWorkbook/XSSFWorkbook/XWPFDocument等更高级别的代码仅支持写入新文件,而且还不够社区对就地写入感兴趣,致力于添加支持)

关于java - Apache poi 文件损坏且无法写入现有工作簿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27956535/

相关文章:

R - 检查文件是否打开/关闭以及由哪个用户打开/关闭

javascript - 在 Excel 中打开 UTF-8 CSV 文件,无需强制用户设置编码

excel - 复制表格范围并粘贴为值

java - Excel读取错误: Invalid header signature.如何解决?

java - 在java spring mvc中发送电子邮件

java - 对数螺旋

java - Cordova 无法为 2097152KB 对象堆保留足够的空间

java - Swagger代码生成: Inheritance and Composition not working as expected

android - 在 Android 中读取 Excel

java - 使用java在ms word文件中创建任何一年的日历