本文介绍了使用 Apache POI 读取 Excel .XLSX 时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Apache POI 3.8 库来读取 Web 应用程序中的 XLSX 文件.以下代码在 Java 控制台应用程序中运行良好:

I am using Apache POI 3.8 libraries to read an XLSX file in a web application. The following code works perfectly fine from a Java console app:

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

但在 Web 应用程序中使用时会引发读取错误".下面粘贴了堆栈跟踪的相关摘录:

but throws a "read error" when used in the web application. A relevant extract of the stack trace is pasted below:

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(按相同顺序):

The following JARs are included in the classpath (in the same order):

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.

There does not seem to be an memory related issues since I gathered some heap utilization stats just before invoking the above code. The XLSX file is 1.15 MB in size.

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

推荐答案

使用上述代码的方法只有一个参数 - FileInputStream.代码片段中的第一行是代码的很大一部分,但也是调用方法的一部分.由于所讨论的方法不了解 Excel 格式,甚至不了解文件扩展名以进行有根据的猜测,因此我决定首先尝试使用 HSSF API 读取 FileInputStream,如下所示:

The method using the above code has a single parameter - FileInputStream. The first line in the code snippet is very much part of the code, but part of the invoking method. Since the method in question did not have knowledge of the Excel format or even a file extension to make an educated guess, I decided that I would first try to read the FileInputStream using HSSF API as below:

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 对象的状态是未知的.这产生了读取错误.我用下面的代码替换了上面的代码,它工作正常,问题似乎得到了解决:

The problem with the above code is that the state of the inputFS object during the second attempt of opening it via the XSSF API is unknown. And this yielded a read error. I replaced the above with the following code, which works fine and the issue appears to be resolved:

Sheet sheet = null;
try {

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

我使用 XLS(旧的,二进制)和 XLSX(新的,基于 XML)格式对此进行了测试,并且可以正常工作.感谢大家的帮助和投入!

I tested this with both XLS (older, binary) and XLSX (newer, XML-based) formats and it works. Thanks for everyone's help and input!

这篇关于使用 Apache POI 读取 Excel .XLSX 时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-26 16:17
查看更多