Bug 56745 - POIXMLException raised when saving workbook if workbook is opened with XSSFWorkbook(String) constructor
POIXMLException raised when saving workbook if workbook is opened with XSSFWo...
 Status: RESOLVED LATER None POI Unclassified XSSF (show other bugs) 3.10-FINAL PC All P2 normal (vote) --- POI Developers List

 Reported: 2014-07-18 23:53 UTC by Javen O'Neal 2015-02-10 15:58 UTC (History) 0 users

Attachments

 Note You need to log in before you can comment on or make changes to this bug.
 Javen O'Neal 2014-07-18 23:53:43 UTC I am getting the following exception when trying to write my workbook out to a file: org.apache.poi.POIXMLException: java.io.IOException: Can't obtain the input stream from /docProps/app.xml Here's the code to reproduce the problem (my best translation from Jython to Java) // open workbook String filename = "C:\\path\\to\\file.xlsx"; File file = new File(filename); Workbook wb = new XSSFWorkbook(filename); // save the workbook to disk FileOutputStream out = new FileOutputStream(file); wb.write(out); out.close(); The error occurs while writing the file (wb.write(out)). Additionally, after XSSFWorkbook(filename) has run, if I try to rename the file in Windows Explorer, I get a "File In Use: The application can't be completed because the file is open in Java(TM) Platform SE binary". I'm not sure if this is a related problem. The following code does not have this problem: // open workbook FileInputStream in = new FileInputStream(file); wb = WorkbookFactory.create(file); in.close(); // save the workbook to disk FileOutputStream out = new FileOutputStream(file); wb.write(out); out.close(); Related: bug #56537. Does the fix for 56537 also fix this bug? Nick Burch 2014-07-19 08:15:40 UTC Can you try with a recent svn checkout / nightly build + adding a Workbook.close() call? Javen O'Neal 2014-07-21 20:55:33 UTC Using POI 3.11 nightly (2014-07-21), I get the same behavior as 3.10-FINAL. // open workbook String filename = "C:\\path\\to\\New Microsoft Excel Worksheet.xlsx"; Workbook wb = new XSSFWorkbook(filename); // save workbook File file = new File(filename); // output and input filename are the same FileOutputStream out = new FileOutputStream(file); wb.write(out); out.close(); wb.close(); raises the following while trying to write to the FileOutputStream Traceback (most recent call last): File "", line 1, in POIXMLException: org.apache.poi.POIXMLException: java.io.IOException: Can't obtain the input stream from /docProps/app.xml It appears that if I read the file unbuffered (either via String or File), the file becomes write protected after calling XSSFWorkbook(String) or XSSFWorkbook(File). The only way to release the write protection after running the above code is to kill the application. Closing the workbook after reading it frees up the write protection (so the file can be renamed in Windows Explorer or edited in another application), however it causes a problem when trying to write the workbook. // open workbook String inFilename = "C:\\path\\to\\New Microsoft Excel Worksheet.xlsx"; Workbook wb = new XSSFWorkbook(inFilename); wb.close(); int sheetCount = wb.getNumberOfSheets(); //returns 3 // save workbook String outFilename = "C:\\path\\to\\output.xlsx"; File file = new File(outFilename); FileOutputStream out = new FileOutputStream(file); wb.write(out); out.close(); wb.close(); raises the following exception while trying to write to the FileOutputStream. Traceback (most recent call last): File "", line 1, in OpenXML4JRuntimeException: org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Rule M2.4 exception : this error should NEVER happen, if so please send a mail to the developers team, thanks ! It seems like the solution for this is to not read and write to the same file (or at least while the workbook hasn't been closed). Maybe this was my misunderstanding of the POI API, but it's possible there's something broken that I've discovered. The problem with this code is that I must keep the file locked for access from XSSFWorkbook(inFilename) to wb.close(). // open workbook String inFilename = "C:\\path\\to\\New Microsoft Excel Worksheet.xlsx"; wb = XSSFWorkbook(inFilename); // save workbook String outFilename = "C:\\path\\to\\output.xlsx"; File file = new File(outFilename); FileOutputStream out = new FileOutputStream(file); wb.write(out); out.close(); wb.close(); Javen O'Neal 2014-07-21 20:58:39 UTC Correction: no wb.close() after out.close() on the 2nd code example of comment #2. The workbook was already closed after XSSFWorkbook(inFilename). Nick Burch 2014-07-21 21:06:30 UTC Try any other operating system other than Windows, and it should work just fine... The underlying OpenXML code supports in-place write, but XSSF does not, so your options are: * Use another OS * Write to a different file * Write a pile of code to allow XSSF to do an in-place update of the OPCPakcage Historically, HSSF only supported writing to a new outputstream because POIFSFileSystem didn't support updating streams within the OLE2 structure. These days, the replacement NPOIFSFileSystem does support it, as does the OPC code, but no-one has been bothered to spend the not insignificant amount of time to update HSSF and XSSF to do in-place updates of streams within open packages Dominik Stadler 2015-02-10 15:58:13 UTC Based on the previous comments this is nothing that we plan to fix anytime soon unless someone can provide patches.