You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用POI库加载大型XLSX文件并解决内存溢出问题

如何使用POI库加载大型XLSX文件并解决内存溢出问题

兄弟,我太懂你这种加载大Excel文件崩溃的痛苦了!你用的XSSFWorkbook是把整个XLSX文件全塞进内存里解析,你这30万行150列的数据,算下来总单元格数都快5亿了,内存不爆才怪。别慌,POI其实早就考虑到这种场景了,给你几个靠谱的解决方案:

1. 用SXSSFWorkbook做流式处理(推荐,适合读写操作)

SXSSF是POI专门为处理大型Excel文件设计的,它会把超出指定行数的数据写到临时磁盘文件里,只把最近的N行留在内存中,内存占用瞬间降下来。

举个简单的例子:

// 设置内存中保留100行数据,超出的写入临时文件
SXSSFWorkbook workbook = new SXSSFWorkbook(100);
// 读取目标文件
FileInputStream fis = new FileInputStream(EXCELFILEPATH);
workbook = new SXSSFWorkbook(new XSSFWorkbook(fis));

// 后续操作和XSSFWorkbook一致,比如获取工作表、遍历行数据
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
    // 处理每行的单元格数据
}

// 用完务必清理临时文件,避免磁盘空间浪费
workbook.dispose();
fis.close();

这种方法几乎不用改太多原有代码,就能大幅降低内存使用,适合需要对Excel进行修改或者写入的场景。

2. 用SAX事件驱动解析(适合仅读取数据的场景)

如果你的需求只是读取数据,不需要修改,那SAX解析是更极致的方案——它逐行逐单元格解析文件,完全不把整个文档加载到内存里,内存占用极低。

你需要自定义一个ContentHandler来处理解析事件,比如:

XMLReader reader = XMLReaderFactory.createXMLReader();
XSSFSheetHandler handler = new XSSFSheetHandler();
reader.setContentHandler(handler);

// 读取XLSX的核心内容文件(需先解压XLSX找到xl/worksheets/sheet1.xml)
InputStream is = new FileInputStream("xl/worksheets/sheet1.xml");
InputSource source = new InputSource(is);
reader.parse(source);

自定义的XSSFSheetHandler需要继承DefaultHandler,重写startElement、endElement等方法,在这些方法里捕捉行和单元格的开始/结束事件,提取所需数据。这种方法代码量稍大,但内存占用是最小的。

3. 临时应急:调整JVM堆内存参数

如果只是临时救急,你可以在启动Java程序时加大堆内存,比如:

java -Xmx20G YourMainClass

但这只是治标不治本,文件再大一点还是会爆内存,所以优先推荐前两种方法。

另外再提个小技巧:如果只需要处理文件中的特定列或者特定行,在解析的时候直接过滤掉不需要的数据,能进一步减少内存压力。

备注:内容来源于stack exchange,提问作者Lyrk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.13 17:53:09