Files
ccdi/openspec/changes/replace-poi-with-easyexcel/proposal.md
2026-01-27 17:55:53 +08:00

122 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 导入导出的模块