2012-06-21 197 views
7

我正在使用Apache POI 3.8庫來讀取Web應用程序中的XLSX文件。以下代碼完全適用於Java控制檯應用程序:使用Apache POI讀取Excel .XLSX時出錯

InputStream inputFS = new FileInputStream("test.xlsx"); 
Workbook workbook = new XSSFWorkbook(inputFS); // below exception is thrown on this line 
Sheet sheet = workbook.getSheetAt(0); 

但在Web應用程序中使用時會拋出「讀取錯誤」。堆棧跟蹤的相關提取物粘貼如下:

java.io.IOException: Read error 
at java.io.FileInputStream.readBytes(Native Method) ~[na:1.6.0_31] 
at java.io.FileInputStream.read(Unknown Source) ~[na:1.6.0_31] 
at java.io.FilterInputStream.read(Unknown Source) ~[na:1.6.0_31] 
at java.io.PushbackInputStream.read(Unknown Source) ~[na:1.6.0_31] 
at java.util.zip.ZipInputStream.readFully(Unknown Source) ~[na:1.6.0_31] 
at java.util.zip.ZipInputStream.readLOC(Unknown Source) ~[na:1.6.0_31] 
at java.util.zip.ZipInputStream.getNextEntry(Unknown Source) ~[na:1.6.0_31] 
at org.apache.poi.openxml4j.util.ZipInputStreamZipEntrySource.<init>(ZipInputStreamZipEntrySource.java:51) ~[poi-ooxml-3.8-20120326.jar:3.8] 
at org.apache.poi.openxml4j.opc.ZipPackage.<init>(ZipPackage.java:83) ~[poi-ooxml-3.8-20120326.jar:3.8] 
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:228) ~[poi-ooxml-3.8-20120326.jar:3.8] 
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:39) ~[poi-ooxml-3.8-20120326.jar:3.8] 
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:187) ~[poi-ooxml-3.8-20120326.jar:3.8] 
at com.corp.ReportManager.parseExcelReport(ReportManager.java:575) [ReportManager.class:na] 

以下JAR文件包含在類路徑中(以相同的順序):

poi-3.8-20120326.jar 
poi-ooxml-3.8-20120326.jar 
poi-ooxml-schemas-3.8-20120326.jar 
xbean.jar 
dom4j-1.6.1.jar 

似乎沒有成爲一個記憶相關的問題因爲我在調用上述代碼之前收集了一些堆利用率統計信息。 XLSX文件大小爲1.15 MB。

##### Heap utilization statistics [MB] ##### 
Used Memory:13 MB 
Free Memory:9 MB 
Total Memory:23 MB 
Max Memory:247 MB 
+1

可以從你的web應用程序查看/修改該文件的閱讀? –

+0

網頁應用程序可以訪問該文件,如果這是你要求的。它只讀(不修改)。在相關說明中,Web應用程序處理XLS(較舊的二進制格式)文件沒有問題。只有XLSX文件纔會遇到問題。 –

+0

是否使用了它不支持的新功能? http://poi.apache.org/spreadsheet/index.html –

回答

5

使用上述代碼的方法有一個參數 - FileInputStream。代碼片段中的第一行是代碼的一部分,但是調用方法的一部分。由於問題的方法沒有足夠的Excel格式,甚至一個文件擴展名的知識來做出一個猜測,我決定,我將首先嚐試讀取的FileInputStream使用HSSF API如下:

Sheet sheet = null; 
try { 

    POIFSFileSystem poifs = new POIFSFileSystem(inputFS); 
    Workbook workbook = new HSSFWorkbook(poifs); 
    sheet = workbook.getSheetAt(0); 
} 
catch (Exception e) { 
} 

if (sheet == null) { 

    try { 

     Workbook workbook = new XSSFWorkbook(inputFS); 
     sheet = workbook.getSheetAt(0); 
    } 
    catch (Exception e) { 
    } 
} 

問題與上面的代碼是第二次嘗試通過XSSF API打開它的inputFS對象的狀態是未知的。這產生了read error。我取代了上述用下面的代碼,它工作正常,問題似乎得到解決:

Sheet sheet = null; 
try { 

    Workbook workbook = WorkbookFactory.create(inputFS); 
    sheet = workbook.getSheetAt(0); 
} 
catch (Exception e) { 
} 

我既XLS(舊的,二進制)和XLSX(較新的,基於XML)格式,並測試了這個作品。感謝大家的幫助和投入!

1

它看起來像你需要使用他們XSSF API

+0

我正在通過SS API使用他們的XSSF API。就像我之前所說的,完全相同的代碼在控制檯應用程序中工作得很好。這是在執行代碼中的第二行時出現問題的Web應用程序。 –

+0

你可以使用Web應用程序的舊格式嗎?它似乎不得不是無論出於什麼原因都無法訪問該文件,或者您無法讀取它正在使用的格式。 –

+1

看起來他們在他們的示例代碼中使用了XSSFReader,而您並沒有這樣做。但是,這並不能解釋爲什麼它可以在控制檯應用程序中工作......這就更能支持它成爲許可問題。也許試着看看你的應用程序是否可以看到/閱讀它? –

2

異常表明有什麼東西與您的InputStream。但是,如果您有文件,則直接將其傳遞給POI!使用InputStream需要將所有內容緩存到內存中,這會佔用空間。既然你不需要做那個緩衝,不要!避免緩衝應該可以解決你的問題無論如何

如果你正在運行POI的最新每晚構建,那麼它很容易。您的代碼變成:

File file = new File("test.xlsx"); 
OPCPackage opcPackage = OPCPackage.open(file); 
XSSFWorkbook workbook = new XSSFWorkbook(opcPackage); 

否則,它是非常相似:

File file = new File("test.xlsx"); 
OPCPackage opcPackage = OPCPackage.open(file.getAbsolutePath()); 
XSSFWorkbook workbook = new XSSFWorkbook(opcPackage); 

如果你不知道,如果你的文件是一個HSSFWorkbook或XSSFWorkbook,那麼你可以使用WorkbookFactory打開相應的一個爲你:

File file = new File("test.xlsx"); 
Workbook workbook = WorkbookFactory.create(file); 
+0

是的,我最終使用'WorkbookFactory.create(...)',因爲我不知道該文件是HSSFWorkbook還是XSSFWorkbook。 –

+1

如果您有一個真實的File對象,請確保使用File版本而不是InputStream版本 - 它會更快更低的內存! – Gagravarr

+0

當我擁有lib中的所有jar時,爲什麼會得到'java.lang.ClassNotFoundException:org.apache.poi.ss.usermodel.WorkbookFactory'? (NetBeans) – victorio

-3

使用這個jar

<dependency> 
    <groupId>org.apache.xmlbeans</groupId> 
    <artifactId>xmlbeans</artifactId> 
    <version>2.3.0</version> 
</dependency> 
相關問題