How to read XLSX file of size >40MB
我正在使用 apache-POI 中的 XSSF 来读取 XLSX 文件。我收到一个错误 java.lang.OutOfMemoryError: Java heap space。后来,使用 -Xmx1024m 为 java 类增加了堆大小,仍然重复相同的错误。
代码:
1
2 3 4 5 |
String filename =“D:\\\\filename.xlsx”;
FileInputStream fis = null; try { fis = new FileInputStream(filename); XSSFWorkbook workbook = new XSSFWorkbook(fis); |
在上面的代码段中,执行在XSSFWorkbook处停止并抛出指定的错误。
有人可以建议更好的方法来读取大型 XLSX 文件。
- 你像eclipse一样从IDE运行它吗?你是如何设置内存选项的?我认为您的设置可能无法正常生效。
- 是的,我正在使用eclipse IDE并对其进行了以下更改…1)在eclipse.ini中将-Xmx256M编辑为-Xmx-1024M 2)在IDE窗口->首选项->安装的JRE->添加-默认 VM 参数中的 Xms256M -Xmx1024M。我认为它可能反映在 eclipse IDE 中
POI 允许您以流式方式读取 excel 文件。 API 几乎是 SAX 的package器。确保使用接受字符串的构造函数以正确的方式打开 OPC 包。否则你可能会立即耗尽内存。
1
2 |
OPCPackage pkg = OPCPackage.open(file.getPath());
XSSFReader reader = new XSSFReader(pkg); |
现在,阅读器将允许您获取不同部分的 InputStreams。如果您想自己进行 XML 解析(使用 SAX 或 StAX),您可以使用这些。但这需要对格式非常熟悉。
更简单的选择是使用 XSSFSheetXMLHandler。这是读取第一张纸的示例:
1
2 3 4 5 6 7 |
StylesTable styles = reader.getStylesTable();
ReadOnlySharedStringsTable sharedStrings = new ReadOnlySharedStringsTable(pkg); ContentHandler handler = new XSSFSheetXMLHandler(styles, sharedStrings, mySheetContentsHandler, true); XMLReader parser = XMLReaderFactory.createXMLReader(); |
mySheetsContentHandler 应该是您自己的 XSSFSheetXMLHandler.SheetContentsHandler 实现。这个类将被提供行和单元格。
但是请注意,如果您的共享字符串表很大(如果您的大表中没有任何重复的字符串,则会发生这种情况),这可能会适度消耗内存。如果内存仍然是个问题,我建议使用原始 XML 流(也由 XSSFReader 提供)。
- 也许你可以帮我解决这个问题:stackoverflow.com/questions/31939669/…
为了补充@waxwing 的答案,如果输入 XLS(X) 文件受密码保护,您将需要通过使用解密装饰器package原始文件来获取纯输入流。但首先,您需要将文件作为 POIFSFileSystem.
打开
简而言之:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
String pass =“secret”;
File file = new File(“data/1.xlsx”); try (POIFSFileSystem fs = new POIFSFileSystem(file); // wrap in org.apache.poi.poifs.filesystem.DocumentFactoryHelper.getDecryptedStream InputStream in = DocumentFactoryHelper.getDecryptedStream(fs, pass); OPCPackage pkg = OPCPackage.open(in)) { XSSFReader reader = new XSSFReader(pkg); StylesTable styles = reader.getStylesTable(); ReadOnlySharedStringsTable sharedStrings = new ReadOnlySharedStringsTable(pkg); SheetContentsHandler f = new SheetContentsHandler() { // … your implementation of SheetContentsHandler interface … }; ContentHandler handler = new XSSFSheetXMLHandler(styles, sharedStrings, f, true); XMLReader parser = XMLReaderFactory.createXMLReader(); parser.setContentHandler(handler); parser.parse(new InputSource(reader.getSheetsData().next())); } |
来源:https://www.codenong.com/11345146/