我正在开发一个项目,该项目需要读取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);
在此之后,我读取每一行并提取每个单元格值。
完成此操作后,我将在Success和Result Message的标题下创建单元格,然后执行以下操作:
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();
有没有人遇到类似的问题?
答案 0 :(得分:13)
我收到了相同的错误消息,但使用了不同的类。我正在使用的当前poi版本是poi-ooxml 3.9,但它仍然存在问题。现在我解决了我的问题,我认为当你首先获得Workbook实例时会出现这个问题。
当我将数据写入文件时,我喜欢这样(使用异常的实践规则并关闭):
FileOutputStream fos = new FileOutputStream(filePath);
wb.write(fos);
fos.close();
我得到“无法从/docProps/app.xml获取输入流”错误消息,当我获得这样的Workbook实例时:
Workbook wb = WorkbookFactory.create(new File(filePath));
当我修复问题时,修改后的代码是
Workbook wb = WorkbookFactory.create(new FileInputStream(filePath));
在我的情况下,无论是打开,读取和写入同一文件,还是从一个文件读取然后写入另一个文件都无关紧要。如果您阅读poi源代码,您可以看到我使用的工厂方法可能在OPCPackage类中调用open()方法。尝试使用获取InputStream作为参数的方法。
答案 1 :(得分:1)
我认为这里的问题是您使用相同的filePath xslFile
打开并保存文件。
打开文件
pkg = OPCPackage.open(xslFile);
theWorkbook = new XSSFWorkbook(pkg);
保存文件
FileOutputStream fos = new FileOutputStream(xslFile);
theWorkbook.write(fos);
fos.close();
你需要一个InputStream来读取和使用你的文件,但是这个 当你创建一个流时,流不可访问 OutputStream在相同的路径和文件名下。
答案 2 :(得分:1)
列出的当前问题是自2010年以来一直存在的错误,可以在https://issues.apache.org/bugzilla/show_bug.cgi?id=49940
找到在下面的stackoverflow列表中,发现了一种解决方法,如果您在再次写入文件之前关闭并重新打开该书,则它将正常运行。这无论如何都没有效率,但它确实解决了这个问题,直到Apache-POI开发团队找出问题为止。
答案 3 :(得分:1)
我为此找到的解决方案,我一直在寻找一段时间,是为了确保您没有使用Workbook
打开您的File
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
。
答案 4 :(得分:1)
以下是使用OPCPackage读取时的方法(尝试/捕获/最终省略了可读性):
OPCPackage pkg = OPCPackage.open("existingFile.xlsx");
XSSFWorkbook wb = (XSSFWorkbook) WorkbookFactory.create(pkg);
进行修改...... XSSFSheet sheet = wb.getSheetAt(0); ...
fos = new FileOutputStream("outputFileName.xlsx");
wb.write(fos);
pkg.close();
fos.close();
Faces.sendFile(new File(outputFileName)
Jayamohan上面的评论帮助我今天解决了这个问题(使用输入和输出的不同文件路径)。谢谢!
答案 5 :(得分:1)
确保在关闭之前再次打开相同的文件。
FileInputStream file1 = new FileInputStream("file.xlsx");
FileOutputStream file2 = new FileOutputStream("file.xlsx");
file2.close();
file1.close();
此代码将引发此错误。
解决方案:
FileInputStream file1 = new FileInputStream("file.xlsx");
file1.close();
FileOutputStream file2 = new FileOutputStream("file.xlsx");
file2.close();