百万数据流导出Excel
编辑碰到需要导出大量数据的时候,通常需要做异步、分批、多线程处理,避免请求挂太久超时、占用资源太多、撑爆内存等等。
代码
其实很简单,一眼秒懂,不想看测试的可以直接跳过了
代码在这点我点我 https://gitee.com/heycm/online-heycm-excel-export/tree/master
思路
这里是一个小案例,使用 MyBatis + EasyExcel 实现一个流式导出的功能,并做了一些测试,做个参考,基本思路是这样:
设计一个
ExcelHanlder
文件导出处理器,实现ResultHandler
接口的handleResult
方法,该方法在流式查询时,每次从流中获取一行数据时被调用;设定一个批次的最大数量值,在
handleResult
方法中完成数据行对应导出数据的转换并收集到一个内存容器List
;当 List 达到批次容量时,或当
handleResult
返回最后一行数据时,触发写文件动作;MyBatis 使用流查询,并使用 ExcelHandler 作为处理器,就可以了。
一般我会将 ExcelHandler 设计成一个抽象类,将批次容量值和具体的数据转换过程交由子类实现,因为一套流程大体是不会改变的,使用模板方法是设计可以方便其他导出业务来复用。
一些测试
测试是按 10w 为一个批次,每个批次写一个 Sheet 页,导出一kun个百万行数据,主要是限制了 JVM 内存 250MB,然后观察 GC 情况,和导出耗时
耗时:45秒多点
JVM
YGC 吃了快 1.5 秒,没有 OGC ,勉勉强强,这还是没有什么业务逻辑的情况下的表现,如果需要在转换过程还要做一些数据清洗加解密还会慢很多。
其他想法
大量数据的导出,通常还需要配合异步任务来执行
做独立的线程池去专门处理异步任务,避免吃掉其他服务的资源
甚至于,给这个线程池分配单独的内存空间、硬件资源,不过这一块不是很了解,有机会学习学习。
- 0
- 0
-
分享