我需要读取大型 Excel 文件并将其数据导入到我的应用程序中。
由于 POI 需要占用大量堆来工作,因此经常抛出OutOfMemory
错误,我发现有一个流媒体用于以串行方式处理 Excel 数据的 API(而不是将文件完全加载到内存中)
我创建了一个xlsx
工作簿,带有一个工作表,并在单元格中输入了多个值,并提出以下代码来尝试读取它:
public static void main(String[] args) throws Throwable {
// keep 100 rows in memory, exceeding rows will be flushed to disk
SXSSFWorkbook wb = new SXSSFWorkbook(new XSSFWorkbook(new FileInputStream("C:\\test\\tst.xlsx")));
SXSSFSheet sheet = (SXSSFSheet) wb.getSheetAt(0);
Row row = sheet.getRow(0);
//row is always null
while(row.iterator().hasNext()){ //-> NullPointerException
System.out.println(row.getCell(0).getStringCellValue());
}
}
然而,尽管能够正确获取其工作表,但它总是带有空(null
) rows.
我在互联网上研究并找到了几个 Streaming API 的例子,但没有一个是关于reading现有的文件,它们都是关于生成excel文件的。
是否真的可以从现有的数据中读取数据.xlsx
流中的文件?
经过更多挖掘后,我发现了这一点library https://github.com/monitorjbl/excel-streaming-reader:
如果您过去使用过 Apache POI 来读取 Excel 文件,您可能会注意到它的内存效率不是很高。读取整个工作簿将导致严重的内存使用高峰,这可能会对服务器造成严重破坏。
Apache 必须阅读整个工作簿有很多充分的理由,但其中大多数都与该库允许您使用随机地址进行读写有关。如果(且仅当)您只想以快速且节省内存的方式读取 Excel 文件的内容,您可能不需要此功能。不幸的是,POI 库中唯一用于读取流工作簿的功能要求您的代码使用类似 SAX 的解析器。该 API 中缺少所有友好的类,例如 Row 和 Cell。
该库充当流 API 的包装器,同时保留标准 POI API 的语法。请继续阅读,看看它是否适合您。
InputStream is = new FileInputStream(new File("/path/to/workbook.xlsx"));
StreamingReader reader = StreamingReader.builder()
.rowCacheSize(100) // number of rows to keep in memory (defaults to 10)
.bufferSize(4096) // buffer size to use when reading InputStream to file (defaults to 1024)
.sheetIndex(0) // index of sheet to use (defaults to 0)
.sheetName("sheet1") // name of sheet to use (overrides sheetIndex)
.read(is); // InputStream or File for XLSX file (required)
还有SAX 事件 API http://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api,它读取文档并通过事件解析其内容。
如果内存占用是一个问题,那么对于 XSSF,您可以获取底层 XML 数据,并自行处理它。这适用于愿意学习一点 .xlsx 文件的低级结构并且乐于在 java 中处理 XML 的中级开发人员。它使用起来相对简单,但需要对文件结构有基本的了解。提供的优点是您可以读取内存占用相对较小的 XLSX 文件。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)