问题 如何读取大小> 40MB的XLSX文件


我在用 XSSF 的 apache-POI 阅读XLSX文件。我收到了一个错误 java.lang.OutOfMemoryError: Java heap space。之后,使用增加堆大小 -Xmx1024m 对于java类仍然重复相同的错误。

码:

String filename = "D:\\filename.xlsx";
FileInputStream fis = null;
try {
   fis = new FileInputStream(filename);
   XSSFWorkbook workbook = new XSSFWorkbook(fis);

在上面的代码段中,执行停止在 XSSFWorkbook 并抛出指定的错误。 有人可以建议更好的方法来读取大型XLSX文件。


11956
2017-07-05 13:16


起源

你像IDE一样从IDE运行它?你是如何设置内存选项的?我认为您的设置可能无法正常生效。 - RP-
是的,我正在使用eclipse IDE并对其进行了以下更改... 1)在eclipse.ini中将-Xmx256M编辑为-Xmx-1024M 2)在IDE窗口中 - > prefrences->已安装的JRE->已添加-Xms256M默认VM参数中的-Xmx1024M。我想它可能已经反映在eclipse IDE中 - Avinash


答案:


POI允许您以流方式读取Excel文件。 API几乎是SAX的包装器。确保使用带有String的构造函数以正确的方式打开OPC包。否则你可能会立即耗尽内存。

OPCPackage pkg = OPCPackage.open(file.getPath());
XSSFReader reader = new XSSFReader(pkg);

现在,读者可以让你获得 InputStreams 对于不同的部分。如果您想自己进行XML解析(使用SAX或StAX),可以使用它们。但它需要非常熟悉格式。

更容易的选择是使用 XSSFSheetXMLHandler。这是一个读取第一张表的示例:

StylesTable styles = reader.getStylesTable();
ReadOnlySharedStringsTable sharedStrings = new ReadOnlySharedStringsTable(pkg);
ContentHandler handler = new XSSFSheetXMLHandler(styles, sharedStrings, mySheetContentsHandler, true);

XMLReader parser = XMLReaderFactory.createXMLReader();
parser.setContentHandler(handler);
parser.parse(new InputSource(reader.getSheetsData().next()));

其中mySheetsContentHandler应该是你自己的实现 XSSFSheetXMLHandler.SheetContentsHandler。这个类将被输入行和单元格。

但是请注意,如果您的共享字符串表很大(如果您的巨大工作表中没有任何重复的字符串,则会发生这种情况,这可能会适度占用内存)。如果内存仍然存在问题,我建议使用原始XML流(也由XSSFReader提供)。


15
2017-07-05 13:56



惊人的答案,非常感谢! - Ondrej Tokar
也许你可以帮我解决这个问题: stackoverflow.com/questions/31939669/... - Ondrej Tokar