怎么通过 Apache POI 的事件驱动模式实现在极低内存下解析 GB 级的 Excel 报表
XSSFWorkbook 容易 OOM 是因为它构建了全量 DOM 树,而事件驱动(SAX)只做流式解析,内存占用只有几百 KB。必须要用 XSSFReader + SharedStringsTable + StylesTable 这三件套,而且顺序和初始化时机有严格的限制。 为什么 XSSFWor
XSSFWorkbook 容易 OOM 是因为它构建了全量 DOM 树,而事件驱动(SAX)只做流式解析,内存占用只有几百 KB。必须要用 XSSFReader + SharedStringsTable + StylesTable 这三件套,而且顺序和初始化时机有严格的限制。

为什么 XSSFWorkbook 一读就 OOM,而事件驱动能扛住 GB 文件
问题就出在这儿——XSSFWorkbook 会把整个 .xlsx 解压后,在内存里完整构建一棵 DOM 树。一个 200MB 的 Excel 文件,内存占用轻松突破 1.5GB,这谁顶得住?而事件驱动的 SAX 模式就不干这事儿,它不建树、不缓存全量数据,只在解析到某行或某个单元格的时候才触发回调,内存常驻只有几百 KB。本质上,它是把 Excel 当作 ZIP + XML 流来处理,靠 XSSFReader 和自定义 DefaultHandler 来驱动整个解析流程。
必须用 XSSFReader + SharedStringsTable + StylesTable 三件套
缺一个都不行。少一个,轻则文本错位、格式跑偏,重则直接崩掉。
XSSFReader是入口,负责打开 OPCPackage 并拿到 sheets.xml 和 sharedStrings.xml 的流SharedStringsTable存着所有字符串的字面值(Excel 为了省空间,会把重复的字符串统一索引),不传它,t标签里的内容根本拿不到真实值StylesTable提供单元格的样式和数据类型(比如日期、数字格式),少了它,所有单元格默认都当成字符串处理,像DateUtil.isCellDateFormatted(cell)这类判断直接失效
这里有个关键提醒:不要用 OPCPackage.open(file) 直接传文件路径,要传 FileInputStream,还得确保它没有被其他线程关闭。另外,SharedStringsTable 必须在 XSSFReader 实例化之后马上构建,顺序错了就会空指针异常。
解析时 cell 类型判断和值提取最容易出错
Excel 单元格的 s(style index)、t(type)、v(value)这三者组合决定了最终内容,常见的坑点如下:
- 数值型单元格没有
t属性,但v里存的是浮点数原始值(比如日期存为 44562.0),得用DateUtil.getJa vaDate(double)来转换 - 字符串型单元格带
t="s",这时v是 shared-strings 表的索引,必须去查SharedStringsTable才能拿到原文本 - 公式单元格带
t="str"或t="n",但v是计算结果,不是公式本身。如果想看原始公式,得额外监听f标签 - 空单元格可能没有
v标签,也没有t,这时候应该返回 null 或空字符串,千万别强行调用toString()
来看个实际代码片段:
if ("s".equals(nextDataType)) {
String s = stringsTable.getItemAt(Long.parseLong(value));
row.add(s != null ? s : "");
}
性能关键:禁用自动格式推断 + 关闭样式继承链
POI 默认会尝试从样式表向上追溯父样式,在大规模 sheet 里,这会引发大量无效对象的创建。所以必须显式关闭:
- 构造
XSSFReader后,调用reader.setStylesTable(null)是不对的——这会导致样式丢失。正确的做法是传入一个精简后的StylesTable,并确保它的内部没有启用isStyleInheritanceEnabled - 禁用数字格式自动识别:用
dataFormatter = new DataFormatter(Locale.ROOT); dataFormatter.setUseCachedValuesForFormulaCells(false);来避免缓存污染 - 不要在 handler 的
startElement里做任何 IO 或者复杂对象的构建,所有业务逻辑都延后到整行收尾(endElement触发row完整之后)再处理
真正压测下来,单核 CPU 处理 100 万行耗时大约 8–12 秒,内存峰值稳定在 30–60MB。最容易忽略的其实是 SharedStringsTable 的构建时机和 StylesTable 的裁剪粒度——这两点没控好,哪怕是用事件模式,照样 OOM。
WPS Office是一款面向macOS用户的综合办公套件,将文字处理、电子表格、演示文稿、PDF工具、模板与云协作整合在同一应用中。它兼容常见Microsoft Office格式,支持Intel及Apple芯片Mac,基础功能可免费使用,
Shapr3D是一款面向工业设计、机械工程、建筑概念和三维打印工作流的CAD软件。Mac版采用Parasolid建模内核,支持草图约束、实体建模、工程图、可视化渲染及常见CAD格式交换,并可通过账户在多台设备之间同步项目。
REAPER是Cockos开发的数字音频工作站,提供多轨音频与MIDI录制、剪辑、处理、混音和母带制作工具。Mac版兼容Intel与Apple芯片,支持AU、VST、VST3、CLAP等插件格式,并提供高度可定制的工作流程。
AutoCAD 是 Autodesk 推出的专业计算机辅助设计软件,Windows 版支持精确二维绘图、三维实体与曲面建模、图纸标注、布局发布和任务自动化,并包含多套行业专业化工具组合,适用于建筑、机械、电气、工程建设及制造设计人员。
SketchUp Pro 是面向建筑、室内、景观、施工和产品设计等专业场景的三维建模工具,提供桌面建模、LayOut 二维文档、模型资源库、扩展程序及云端协作能力。其操作逻辑直观,适合从概念推敲、空间规划到图纸表达和方案汇报的完整工作流程。
AutoCAD LT 是 Autodesk 推出的专业二维 CAD 软件,适合建筑师、工程师、施工人员和设计师完成精确绘图、标注及文档编制。它支持 DWG 工作流、智能块、图形比较、计数、表格和 AutoLISP 自动化,













