2012-06-21 217 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); 

ウェブアプリケーションで使用すると「読み取りエラー」が発生します。スタックトレースの関連抽出物は、以下の貼り付けられます:

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アプリケーションは、ファイルにアクセスしている場合、そのファイルにアクセスしています。読み取りのみ(変更なし)。関連するノートでは、Webアプリケーションは問題なくXLS(古いバイナリ形式)ファイルを処理します。 XLSXファイルでのみ問題が発生します。 –

+0

は、サポートされていない新しい機能のどれですか? http://poi.apache.org/spreadsheet/index.html –

答えて

5

上記のコードを使用するメソッドには、1つのパラメータFileInputStreamがあります。コードスニペットの最初の行は、コードの大部分ですが、呼び出しメソッドの一部です。

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) { 
    } 
} 

問題:問題の​​方法は推測をするためにExcel形式、あるいはファイル拡張子の知識を持っていなかったので、私は私が最初に以下のようにFileInputStreamを使用してHSSF APIを読み取ろうとすることを決めました上記のコードでは、XSSF API経由で2回目の開けようとしたときの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を使用しています。先ほど述べたように、まったく同じコードはコンソールアプリケーションでうまく動作します。コード内で2行目を実行しているときに問題が発生するのは、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

はい、ファイルがHSSFWorkbookかXSSFWorkbookかわからないので、私は 'WorkbookFactory.create(...) 'を使ってしまいました。 –

+1

実際のFileオブジェクトを持っている場合は、InputStreamバージョンではなくFileバージョンを使用するようにしてください。より高速で低メモリになります! – 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> 
関連する問題