Apache的POI:无法写入到现有的工作簿(Apache-POI: Unable to write

2019-07-17 18:40发布

我正在这需要读取Excel工作簿项目,调用所需的Web服务,然后采取从web服务的响应并进入到被读取相同的Excel工作簿的信息。

这是试图写入Excel工作簿时,我看到的错误:

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:141)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:177)
at ext.ExcelProcessor.main(ExcelProcessor.java:197)
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:139)
    ... 2 more

这里是我的文件/读取的开放代码:

pkg = OPCPackage.open(xslFile);
    theWorkbook = new XSSFWorkbook(pkg);

在此之后我读每一行和提取每个单元格的值。

一旦做到这一点,我会创建标题为成功和结果消息下的单元格,然后执行以下操作:

String sessionData = sessionKey[1];
                String[] cellValCurrRow = rowCellVals.get(r-1);
                String attachmentData[] = WQSServices.uploadAttachment(sessionData, cellValCurrRow);

                XSSFCell cell = xslRows[r].getCell(7);

                if(cell == null)
                {
                    cell = xslRows[r].createCell(7);
                }

                System.out.println("The Cell: "+cell.getStringCellValue());

                XSSFCell cell2 = xslRows[r].getCell(8);

                if(cell2 == null)
                {
                    cell2 = xslRows[r].createCell(8);
                }

                System.out.println("The Cell: "+cell2.getStringCellValue());

                cell.setCellType(Cell.CELL_TYPE_STRING);
                cell2.setCellType(Cell.CELL_TYPE_STRING);
                cell.setCellValue(attachmentData[0]);
                cell2.setCellValue(attachmentData[1]);

                System.out.println("New Cell Data: 1-"+cell.getStringCellValue()+" 2-"+cell2.getStringCellValue());

                FileOutputStream fos = new FileOutputStream(xslFile);
                theWorkbook.write(fos);
                fos.close();

有没有人跑了类似的问题?

Answer 1:

我得到了同样的错误信息,但使用了不同的类。 我使用当前版本的POI兴趣点是,OOXML 3.9,但它仍然有问题。 现在我固定我的问题,我认为当你第一次获得工作簿实例出现这类问题。

当我写数据到这个文件,我不喜欢这样(与实际规则的例外和关闭):

    FileOutputStream fos = new FileOutputStream(filePath);
    wb.write(fos);
    fos.close();

我得到“无法获得/docProps/app.xml输入流”错误消息,当我获得工作簿实例是这样的:

    Workbook wb = WorkbookFactory.create(new File(filePath));

当我解决了这一问题,修改后的代码是

    Workbook wb = WorkbookFactory.create(new FileInputStream(filePath));

在我的情况下,它并不重要是否开启以及读取和写入同一个文件,或者从一个文件中读取然后写入到另一个。 如果你读了POI的源代码,你可以看到工厂方法我用了可能调用OPCPackage类的open()方法。 尝试使用该方法获得的InputStream作为参数。



Answer 2:

我觉得这里的问题是,您使用的是相同的文件路径xslFile打开和保存文件。

打开该文件,

pkg = OPCPackage.open(xslFile);
    theWorkbook = new XSSFWorkbook(pkg);

保存文件,

FileOutputStream fos = new FileOutputStream(xslFile);
theWorkbook.write(fos);
fos.close();

你需要读的InputStream和支持您的文件,但是当你创建在相同的路径和文件名的OutputStream此流becames不可访问。



Answer 3:

列出当前的问题是,已经出现自2010年以来,可以发现@错误https://issues.apache.org/bugzilla/show_bug.cgi?id=49940

在一种变通方法下面的计算器房源发现,如果关闭做是另一回事之前再次重新打开这本书写出到文件时,它会没有问题的工作。 这是不以任何方式有效,但它确实解决这个问题,直到Apache的POI Dev Team的数字出来的问题。

https://stackoverflow.com/a/9792406/1231715



Answer 4:

该解决方案,我发现这一点,我一直在寻找了一段时间,是确保你不打开WorkbookFile您可以使用它打开FileOutputStream保存Workbook 。 相反,使用FileInputStream打开Workbook

像这样的东西都会工作得很好

        File inputFile = new File("Your-Path");
        this.inputStream = new FileInputStream(inputFile);
        this.opc = OPCPackage.open(this.inputStream);
        this.workbook = WorkbookFactory.create(opc);

...

        this.outputStream = new FileOutputStream(inputFile);
        this.workbook.write(this,outputStream);

不要忘记关闭每个打开的流和OPCPackage



Answer 5:

下面是这可以通过使用OPCPackage读(的try / catch /终于ommitted为了可读性)时做到:

OPCPackage pkg = OPCPackage.open("existingFile.xlsx");
XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(pkg);

使修改... XSSFSheet片= wb.getSheetAt(0); ...

fos = new FileOutputStream("outputFileName.xlsx");
wb.write(fos);
pkg.close();
fos.close();
Faces.sendFile(new File(outputFileName)

从上面的Jayamohan评论帮助我今天解决这个问题(使用不同的文件路径,输入和输出)。 谢谢!



文章来源: Apache-POI: Unable to write to an existing workbook