Files
ccdi/openspec/changes/replace-poi-with-easyexcel/proposal.md

122 lines
4.1 KiB
Markdown
Raw Normal View History

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