web-dev-qa-db-ja.com

ApachePOIでExcel.XLSXを読み取るときにエラーが発生しました

Apache POI 3.8ライブラリを使用して、WebアプリケーションでXLSXファイルを読み取ります。次のコードは、Javaコンソールアプリから完全に正常に機能します:

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.15MBです。

##### Heap utilization statistics [MB] #####
Used Memory:13 MB
Free Memory:9 MB
Total Memory:23 MB
Max Memory:247 MB
7
Web User

上記のコードを使用するメソッドには、FileInputStreamという単一のパラメーターがあります。コードスニペットの最初の行は、コードの大部分を占めていますが、呼び出しメソッドの一部です。問題のメソッドには、Excel形式や、知識に基づいた推測を行うためのファイル拡張子の知識がなかったため、最初に次のようにHSSFAPIを使用して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) {
    }
}

上記のコードの問題は、XSSFAPIを介して2回目に開いたときのinputFSオブジェクトの状態が不明であるということです。そして、これはread errorを生み出しました。上記を次のコードに置き換えました。これは正常に機能し、問題は解決されたようです。

Sheet sheet = null;
try {

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

これをXLS(古い、バイナリ)形式とXLSX(新しい、XMLベース)形式の両方でテストしましたが、機能します。みんなの助けとインプットに感謝します!

5
Web User

例外は、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);
3
Gagravarr

それらを使用する必要があるようです XSSF API

1
John Kane
I have same error, I have just updated the pom dependencies with same version. It worked.
        <!-- https://mvnrepository.com/artifact/org.Apache.poi/poi -->
        <dependency>
            <groupId>org.Apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.Apache.poi/poi-ooxml -->
        <dependency>
            <groupId>org.Apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.0</version>
        </dependency>
0
Shakti Pravesh