4.1 KiB
4.1 KiB
Proposal: Replace Apache POI with Alibaba EasyExcel
Summary
将若依框架中的 Apache POI 替换为 Alibaba EasyExcel,以解决大文本量 Excel 导入导出时的内存占用和性能问题。当前使用 POI 的 SXSSFWorkbook 虽然支持流式写入,但在处理大量数据时仍然存在性能瓶颈,且不支持真正的流式读取。
Motivation
问题分析
-
当前 POI 实现的限制:
ExcelUtil.java:112-sheetSize硬编码为 65536,这是 Excel 2003 的限制ExcelUtil.java:1682- 使用 SXSSFWorkbook 进行流式写入,但内存优化有限ExcelUtil.java:325-525-importExcel方法一次性加载整个 Sheet 到内存,无法处理大文件- POI 的 DOM 解析模式导致大文件内存占用过高
-
业务需求:
- 需要支持导入导出超过 10 万行数据
- 需要支持单元格内容超过 32767 字符(POI STRING 类型限制)
- 需要降低内存占用,避免 OOM
-
EasyExcel 优势:
- 基于 SAX 解析,真正的流式读写
- 内存占用仅与行数据大小相关,与文件大小无关
- API 设计简洁,注解驱动
- 官方维护活跃,社区成熟
Proposed Solution
技术方案
-
保持 API 兼容性:
- 保留
@Excel和@Excels注解接口 - 保留
ExcelUtil<T>的公共方法签名 - 保留
ExcelHandlerAdapter接口(适配 EasyExcel 的写处理器)
- 保留
-
核心实现变更:
- 使用
EasyExcel.write()替代 POI 的 Workbook/Sheet 操作 - 使用
EasyExcel.read()替代 POI 的 Workbook 解析 - 实现自定义的
HeadGenerator和ContentStyleStrategy以支持样式
- 使用
-
依赖变更:
- 移除
poi-ooxml依赖 - 添加
easyexcel依赖(版本 3.3.4,支持 Spring Boot 3)
- 移除
影响范围
修改的文件:
ruoyi-common/pom.xml- 更新依赖ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java- 重写实现ruoyi-common/src/main/java/com/ruoyi/common/annotation/Excel.java- 调整注解属性ruoyi-common/src/main/java/com/ruoyi/common/utils/poi/ExcelHandlerAdapter.java- 适配新接口
无需修改的文件(向后兼容):
- 所有 Controller 层代码(13 个文件使用 ExcelUtil)
- 实体类上的
@Excel注解
Alternatives Considered
方案 1:升级 POI 版本
- 优点:代码改动最小
- 缺点:无法从根本上解决内存问题,POI 的架构限制依然存在
方案 2:使用 Hutool 的 Excel 工具
- 优点:API 简洁
- 缺点:底层仍使用 POI,内存问题未解决
方案 3:使用 EasyExcel(选定方案)
- 优点:真正的流式处理,内存占用低,社区成熟
- 缺点:需要适配现有注解和 API
Compatibility Notes
破坏性变更
-
样式支持:EasyExcel 的样式支持有限,以下功能可能需要简化:
- 合并单元格(
needMerge) - 图片插入(
ColumnType.IMAGE) - 数据验证(
combo,comboReadDict) - 自定义颜色(
headerBackgroundColor,color等)
- 合并单元格(
-
Sheet 分割:EasyExcel 自动处理大文件,无需手动分割 Sheet
-
统计行:
isStatistics需要通过监听器实现
保留的功能
- ✅ 注解驱动配置
- ✅ 字典类型转换(
dictType) - ✅ 表达式转换(
readConverterExp) - ✅ 日期格式化(
dateFormat) - ✅ 导入/导出模板生成
- ✅ 字段筛选(
includeFields,excludeFields)
Success Criteria
-
性能指标:
- 导出 10 万行数据,内存占用 < 500MB
- 导入 100MB Excel 文件,内存占用 < 200MB
-
功能完整性:
- 所有现有 Controller 的导入导出功能正常工作
- 支持超过 65536 行数据
-
兼容性:
- 现有实体类注解无需修改
- 现有业务代码无需修改
Timeline
阶段划分(具体任务见 tasks.md):
- 依赖更新与环境准备
- 核心 ExcelUtil 重写
- 注解与接口适配
- 集成测试与验证
- 文档更新
Related Changes
- 无前置依赖
- 可能影响:所有使用 Excel 导入导出的模块