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

使用Apache POI读取超150MB大Excel文件时线程阻塞求助

大文件Excel读取异常:Apache POI无法生成Workbook

使用Apache POI进行Excel读写时,小文件处理正常,但读取150MB+、包含20万+条记录的文件时,线程持续运行却始终无法返回Workbook对象,无法执行后续操作。

调试日志

2022-11-29 17:04:33.541 DEBUG 33576 --- [ecutor-thread-8] o.a.p.o.o.PackageRelationshipCollection  : Parsing relationship: /xl/pivotCache/_rels/pivotCacheDefinition1.xml.rels
2022-11-29 17:04:33.604 DEBUG 33576 --- [ecutor-thread-8] o.a.p.o.o.PackageRelationshipCollection  : Parsing relationship: /xl/pivotTables/_rels/pivotTable1.xml.rels
2022-11-29 17:04:33.631 DEBUG 33576 --- [ecutor-thread-8] o.a.p.o.o.PackageRelationshipCollection  : Parsing relationship: /xl/_rels/workbook.xml.rels
2022-11-29 17:04:33.646 DEBUG 33576 --- [ecutor-thread-8] o.a.p.o.o.PackageRelationshipCollection  : Parsing relationship: /xl/worksheets/_rels/sheet1.xml.rels
2022-11-29 17:04:33.657 DEBUG 33576 --- [ecutor-thread-8] o.a.p.o.o.PackageRelationshipCollection  : Parsing relationship: /xl/worksheets/_rels/sheet2.xml.rels
2022-11-29 17:04:33.672 DEBUG 33576 --- [ecutor-thread-8] o.a.p.o.o.PackageRelationshipCollection  : Parsing relationship: /_rels/.rels
2022-11-29 17:04:47.661 DEBUG 33576 --- [ecutor-thread-8] org.apache.poi.ooxml.POIXMLFactory       : using default POIXMLDocumentPart for http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings
2022-11-29 17:04:47.666 DEBUG 33576 --- [ecutor-thread-8] org.apache.poi.ooxml.POIXMLFactory       : using default POIXMLDocumentPart for http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings

使用的依赖

<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>5.2.3</version>
</dependency>
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>5.2.3</version>
</dependency>
<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml-schemas</artifactId>
    <version>5.2.3</version>
</dependency>

已尝试的方案

  • 直接加载XSSFWorkbook:
Workbook workbook = new XSSFWorkbook(file);
  • 基于XSSF创建SXSSFWorkbook:
SXSSFWorkbook workbook = new SXSSFWorkbook(new XSSFWorkbook(file));
  • 使用WorkbookFactory创建:
Workbook workbook = WorkbookFactory.create(f);

不可用方案说明

以下方案因忽略空白单元格导致列读取异常,且受公司政策限制无法使用:

InputStream is = new FileInputStream(new File(uploadfilePath.toString()));
Workbook workbook = StreamingReader.builder().rowCacheSize(100).bufferSize(4096).open(is);

可行解决方案

1. 跳过透视表缓存加载

从日志可见,POI在处理透视表缓存(pivotCache),这是大文件读取卡顿的核心原因之一。通过配置POI参数跳过透视表相关内容:

// 方式1:直接通过OPCPackage配置
OPCPackage pkg = OPCPackage.open(file);
Map<String, Object> config = new HashMap<>();
// 禁用透视表缓存解析
config.put(XSSFWorkbook.SKIP_PIVOT_CACHE, true);
XSSFWorkbook workbook = new XSSFWorkbook(pkg, config);

// 方式2:使用WorkbookFactory
Map<String, Object> params = new HashMap<>();
params.put("XSSF_PARSE_PIVOT_CACHE", false);
Workbook workbook = WorkbookFactory.create(file, null, false, params);

2. 优化JVM内存参数

大文件读取需要足够的内存支撑,调整JVM启动参数(根据机器配置调整数值):

-Xms2G -Xmx4G -XX:+UseG1GC

-Xms设置初始内存,-Xmx设置最大内存,G1GC适合大内存场景的垃圾回收。

3. 正确使用SXSSF流式处理

避免先加载完整XSSFWorkbook,改用直接从流创建,并设置内存保留行数:

InputStream inputStream = new FileInputStream(file);
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
// 仅保留100行在内存,超出部分写入临时磁盘文件
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(xssfWorkbook, 100);

// 处理完成后必须清理临时文件,避免磁盘占用
sxssfWorkbook.dispose();

4. 预处理Excel文件(若允许)

手动或通过工具删除Excel中不必要的透视表、冗余格式、空白行等内容,大幅减小文件体积后再读取,能显著提升POI的处理速度。

内容的提问来源于stack exchange,提问作者tara kantheti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:25:54