EasyExcel 分Sheet实现大数据量导出
EasyExcel 分 Sheet 实现大数据量导出
【场景】平台用户导出数据量达 w 级别的数据时界面白屏或按钮无响应。
【解决方案】做异步导出,用户触发点击时创建导出消息并开启单独线程处理导出,处理成功以后将文件下载路径更新到消息中心提醒用户下载。
【注意的问题】As we all knew, everything has its limits,Excel 也是(03 版本 Excel 单张 Sheet 容量是 65536 行 ,07 版本单张 Sheet 容量是 1048575 行),超过了容量则 api 报错。invalid row number (1048576) outside allowable range (0..1048575)
【解决办法】分 Sheet 导出,如果导出的数据量超过单一张 Sheet 的容量就创建一个新 Sheet 进行存放
实现步骤如下:
引入依赖
<dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>2.2.10</version> </dependency>
具体方式(参考代码)
【总结】
1. 创建代办消息,提示告诉用户要耐心等待处理完成;与此通过线程池启动线程处理导出。
2. 处理过程:
(1)根据当前用户点击导出时的查询条件,获取当前目标导出数据的最小 ID 和最大 ID;
(2)再统计最小 ID~ 最大 ID 范围内所有的数据总数 totalCount(用于下一步计算要多少个 Sheet 来装)
(3)判断 totalCount 没有超过 Sheet 容量就一次性导出,如果超过则分 Sheet
(4)根据数据总数 totalCount 计算 Sheet 张数,每张 Sheet 存储 100w 条数据;
Integer pageSize = Constants.EXPORT_MAX_SHEET_PAGE_SIZE; // 设置的单个 Sheet 的数据量,必须小于 1048576,在此设置(Constants.EXPORT_MAX_SHEET_PAGE_SIZE=100,0000)
long sheetCount = (totalCount + Constants.EXPORT_MAX_SHEET_PAGE_SIZE - 1) / pageSize;
(5)循环 Sheet 数量进行分页查询和加载到 Excel 中,加载每一页后要清空 List,否则服务器内存容易会被消耗完而导致服务器崩溃重启。
(6)将生成 Excel 存储到 Linux / 本地服务器空间比较大的文件路径,将其读取并上传到云存储,上传完成后得到下载 url,删除 Linux / 本地服务器文件释放磁盘空间。
最近在工作中遇到用户反馈说导出功能不好用,就单独抽出时间来优化平台中导出的功能,之前把导出优化的任务分给同事来搞,写的代码看起来就重写,导出的数据都不对,最后还是要我出马。
积硅步以致千里
--------------------------------------------------------------------->>[Every problem has its solutions]