2015-01-15 111 views
1

我想寫讀取和使用下面的代碼寫入到工作簿:的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(),並且我也應該使用FileInputStream,即使我正在使用WorkbookFactory?

------------編輯----------------------我得到我的代碼工作 我用FileInputStream而不是WorkbookFactory創建工作簿並在關閉FileOutputStream後關閉它。這工作。

+0

這是什麼版本的Apache POI?如果不是3.11最終版(最新版),升級時會發生什麼? – Gagravarr

+0

該版本是最新版本 - 3.11 – tanvi

回答

3

我想我已經發現了你的問題:

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

.... 

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

你打開一個文件,然後試圖後來覆蓋它,同時它還是開放的,在使用中,這是不支持

你需要做的是將更新後的文件寫入不同的文件名。如果要替換它,則在關閉原始文件後需要執行第二步。

現在,您已經開始覆蓋文件,然後POI嘗試將原始文件的某些部分複製到新文件中,並失敗,因爲它試圖讀取的原始文件已被刪除! (NPOIFSFileSystem和OPCPackage,底層包代碼,既支持就地寫入和就地更新,但更高級的代碼,如HSSFWorkbook/XSSFWorkbook/XWPFDocument只支持寫入新文件,並且還沒有足夠的社區關注在就地編寫工作以增加支持)

+0

好的。但是,爲什麼FileInputStream不會出現類似的問題? – tanvi

+0

因爲這樣,你可以在內存中緩衝整個文件,關閉底層文件,然後允許你在不再使用原始文件的情況下垃圾回收。 – Gagravarr

+0

明白了。非常感謝 :) – tanvi

0

在哪裏,我應該如何使用FileOutputStream中,workbook.write()

不是在finally塊。如果您有任何異常情況,您肯定不希望將可能的垃圾寫入文件。 workbook甚至可以在finally塊中爲null

將該代碼移動到try塊的末尾。

+0

實際上這是一個包含測試案例的文件。如果發生一些未處理的異常,我如何獲得「失敗」打印? – tanvi

+0

抓住例外並打印「失敗」,或撥打任何你必須打電話打印它? – EJP

+0

但是失敗的發生是因爲我無法打印「失敗」到Excel。 – tanvi

相關問題