线程池导入大数据量excel
一、前置准备阶段:环境准备与参数配置
依赖引入在
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 天备份)
任务结果归档将导入结果(总条数、成功数、错误信息)存入数据库归档,便于后续审计和问题追溯