2013-01-02 67 views
8

我正在研究需要讀取Excel工作簿,調用必需的Web服務,然後從Web服務接收響應並將該信息輸入到讀取了相同的Excel工作簿。Apache-POI:無法寫入現有工作簿

這是試圖寫入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(); 

有沒有人跑了類似的問題?

+0

你添加什麼jar文件?你是否也有包含在類路徑OOXML jar文件? –

+0

在Eclipse中我引用的庫我有以下幾點: POI-3.8-20120326.jar POI-例子,3.8-20120326.jar POI-excelant-3.8-2012032.jar POI-OOXML-3.8-2.jar POI-OOXML-架構 - 20120326.jar –

+0

ķ怎麼樣的dom4j-1.6.1.jar星級API-1.0.1.jar和XMLBeans的-2.3.0.jar文件?我相信這些都是poi-ooxml jar文件的依賴關係 –

回答

1

我認爲這裏的問題是,您正在使用相同的文件路徑xslFile爲 打開並保存該文件。

打開文件,

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

保存文件,

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

您需要讀取的InputStream和支持您的文件,但是當你創建一個 的OutputStream此 流becames不可訪問在相同的路徑和文件名下。

+0

不,它的工作。我試過了。根據我的知識,OP的代碼沒有問題。打開文件進行讀取不舔它,任何程序都可以寫它,即使它是由其他程序讀取模式 –

+2

這被張貼在Apache的POI組管理員打開: 如果工作簿是從實例創建OPCPackage類的OPCPacakge實例在寫入工作簿之前不得丟棄。這改變了代碼,徹底解決了問題; org.apache.poi.openxml4j.opc.OPCPackage OPC = org.apache.poi.openxml4j.opc.OPCPackage.open(文件名); org.apache.poi.xssf.usermodel.XSSFWorkbook WB = 新org.apache.poi.xssf.usermodel.XSSFWorkbook(OPC); java.io.FileOutputStream fileOut = new java.io.FileOutputStream(filename); wb.write(fileOut); opc.close(); fileOut.close(); –

+0

你能給我們鏈接嗎? –

1

的解決方案,我已經找到了這一點,我一直在尋找了一段時間,是確保你不打開你的Workbook與您用來打開FileOutputStreamFile保存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

+0

這會增加內存佔用的缺點 – Gagravarr

10

我得到了同樣的錯誤信息,但使用了不同的類。目前我使用的poi版本是poi-ooxml 3.9,但它仍然存在問題。現在我解決了我的問題,並且我認爲當您首先獲取Workbook實例時會出現此問題。

當我將數據寫入到文件,我不喜歡這樣(與實際規則的例外和關閉):

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作爲參數的方法。

+0

好極了!最糟糕的是我有工作代碼,然後我讀了WorkbookFactory.create()與File相比資源密集程度低於Stream,所以我改變了,並得到了這個奇怪的錯誤...... – PhiLho

1

下面是這可以通過使用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評論幫助我今天解決這個問題(使用輸入和輸出不同的文件路徑)。謝謝!

相關問題