一、前置准备阶段:环境准备与参数配置
-
依赖引入 在
pom.xml
中添加 EasyExcel 和线程池相关依赖,确保版本兼容(easyexcel 建议 2.2.10+,避免避免池使用 Spring 自带的ThreadPoolTaskExecutor
-
线程池 参数定制化配置 针对 Excel 导入的 IO 密集型特性,配置线程池(核心线程数 = CPU 核心数 ×2,最大线程数 = CPU 核心数 ×4,队列容量 = 100),并通过
@Configuration
注入 Spring 容器 -
业务模型与 Excel 映射类定义创建与 Excel 列对应的实体类,通过 easyexcel 注解指定表头映射和数据转换规则(如日期格式化、字段校验)
二、文件上传与预处理
-
接收前端上传的文件 通过 SpringMVC 的
MultipartFile
接收 Excel 文件,保存到临时目录(如/tmp/excel-import/
),并生成唯一任务 ID(用于后续进度查询) -
文件合法性校验 校验文件格式(必须为
.xlsx
或.xls
)、大小(如不超过 100MB)、表头是否匹配(通过 easyexcel 的headRowNumber
解析表头并对比预期字段)
三、任务拆分与分发
-
按文件 / Sheet 页拆分任务 主线程读取 Excel 的 Sheet 数量,为每个 Sheet 创建独立任务(若 Sheet 行数超过 5 万,进一步按 5 万行 / 片拆分),通过
@Async
注解提交到线程池 -
多任务并行调度 主线程收集所有子任务的
CompletableFuture
,通过CompletableFuture.allOf()
等待所有任务完成,最终汇总结果
四、EasyExcel 流式解析与数据处理
-
自定义 ReadListener 处理解析逻辑 通过 easyexcel 的
ReadListener
逐行解析数据,实现 "读一行处理一行",避免内存堆积 -
启动 EasyExcel 解析任务 在子任务中调用 easyexcel 的
read
方法,传入自定义监听器和解析范围(startRow、endRow)
五、数据库批量写入优化
-
使用 MyBatis 批处理 减少 IO 在业务层开启
ExecutorType.BATCH
模式,累积 SQL 后一次性执行,降低数据库连接开销 -
控制并发写入 线程数通过 Redis 分布式锁限制同时写入数据库的线程数(如最多 5 个线程),避免数据库连接池耗尽
六、进度追踪与异常处理
-
实时更新任务进度在 Redis 中存储任务进度(总条数、成功数、失败数),前端通过任务 ID 轮询查询
-
错误数据收集与重试对解析或入库失败的行,记录行号和错误原因,导入完成后生成 "错误 Excel" 供用户下载修正
七、资源清理与任务归档
-
临时文件清理导入完成后(无论成功 / 失败),通过定时任务删除临时目录的 Excel 文件(保留 7 天备份)
-
任务结果归档将导入结果(总条数、成功数、错误信息)存入数据库归档,便于后续审计和问题追溯