基于EasyExcel多线程分页导出excel

  • Maven依赖
  • 线程池配置
  • 导出代码

第七更,基于EasyExcel 多线程分页导出excel
在项目中,BA要求全量导出表中数据,估计有十几万条,同事使用的是EasyPoi导致内存泄漏,我帮他优化,使用阿里的EasyExcel,解决了内存泄漏问题,但是导出17万数据仍需要84秒(本地测试),于是想到了多线程优化,最终测试时间为40秒,服务器上速度会更快,代码如下

Maven依赖

 <dependencies><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.3</version></dependency></dependencies>

线程池配置

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;import java.util.concurrent.*;@Configuration
public class ThreadPoolConfig {@Bean("excelThreadPool")public ExecutorService buildExcelThreadPool() {int cpuNum = Runtime.getRuntime().availableProcessors();BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(1000);ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("excel-pool-%d").build();return new ThreadPoolExecutor(10 * cpuNum, 30 * cpuNum,1, TimeUnit.MINUTES, workQueue, threadFactory);}
}

导出代码

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.write.metadata.WriteSheet;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;@Component
public class MultiThreadExcelExport {@Autowired@Qualifier("excelThreadPool")private ExecutorService executorService;@SuppressWarnings("unchecked")public void exportExcel() {String fileName = "D:\\demo.xlsx";ExcelWriter writer = EasyExcel.write(fileName, User.class).build();WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();// 根据数据读写速度来调整,一般来说读的逻辑复杂,比较慢,如果读比写快,这里设为1int N = 2;// 大小设置为2就可以,作为缓冲BlockingQueue<List<User>> queue = new ArrayBlockingQueue<>(2);AtomicInteger start = new AtomicInteger(0);// 分页大小可以适当调整int pageSize = 10000;//开启多个线程分页查数据for (int i = 0; i < N; i++) {executorService.submit(() -> {while (true) {//自增int startNum= start.getAndAdd(pageSize);try {List<User> list = findPage(startNum, pageSize);if (CollectionUtils.isEmpty(list)) {//读到没数据也要放入空集合queue.put(Collections.EMPTY_LIST);break;}queue.put(list);} catch (Exception e) {//异常情况也要放入空集合,防止写线程无法退出循环queue.put(Collections.EMPTY_LIST);throw new RuntimeException(e);}}});}Future<?> submit = executorService.submit(() -> {int count = 0;while (true) {List<User> list = null;try {list = queue.take();} catch (InterruptedException e) {Thread.interrupted();}if (CollectionUtils.isEmpty(list)) {count++;// 当获取到两次空集合时,说明已经读完if (count == N) {break;}continue;}writer.write(list, writeSheet);}writer.finish();});try {// 阻塞等待完成,异步处理也可以去掉这段代码submit.get();} catch (Exception e) {throw new RuntimeException(e);}}private List<User> findPage(int startNum, int pageSize) {// todo 实现分页查询return new ArrayList<>();}public static class User {private Long id;@ExcelProperty("姓名")private String name;@ExcelProperty("编号")private String number;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}}}

基于EasyExcel多线程分页导出excel相关推荐

  1. 阿里easyexcel通过模板导出excel

    easyexcel通过模板导出excel 之前使用其他方式进行excel的导出,像poi或者freemarker或者Beetl,效果都还行,但是总是有一些小问题.许多的解决思路都是:通过制作excel ...

  2. Java分页导出Excel文件

    Java分页导出Excel文件 1.开发微信小程序接入广告获取收益 技术: Springboot + mongodb + maven +Layui + thymeleaf 上一篇博客已经讲解了Java ...

  3. 基于EasyPOI的使用导出Excel

    基于EasyPoi的使用导出Excel文件步骤记录 首先导入pom依赖 <!--easy poi依赖--><dependency><groupId>cn.after ...

  4. EasyExcel(二) 导入导出excel的数据格式转换

    EasyExcel(二) 导入导出excel的数据格式转换 关于easyExcel的基本用法我就不在多说了,有需要的可以自己点击该链接去学习基本的使用,主要对这里面经常用到的一些监听器和拦截器讲一下, ...

  5. 海量数据下如何使用多线程的导出 Excel

    今日推荐 推荐一个 Java 接口快速开发框架干掉Random:这个类已经成为获取随机数的王者Docker + Intellij IDEA,提升 10 倍生产力!笑出腹肌的注释,都是被代码耽误的诗人! ...

  6. EasyExcel导入和导出excel数据表格用法示例

    说明:平时项目中经常有需要把excel表格中的数据导入库中,或者需要把查询出来的数据导出到excel文件中,今天就来介绍阿里的 easyexcel 的用法 一.SpringBoot集成EasyExce ...

  7. 使用jxls分页导出excel

    项目有一个导出excel的功能使用的是2003版的,那2003版的excel单个sheet最多只能导出65535条数据,现在项目有一个导出的功能数据会超过65535条.所以需要导出到多个sheet里面 ...

  8. 海量数据下如何使用多线程的导出 Excel ?

    点击上方"码农突围",马上关注 这里是码农充电第一站,回复"666",获取一份专属大礼包 真爱,请设置"星标"或点个"在看&quo ...

  9. EasyExcel入门:导出Excel文件

    在开发过程中,我们经常需要导出Excel文件,一开始我使用的是Apache POI,通过创建XSSFWorkbook对象来导出Excel数据,但实际使用时发现需要占用较大的内存空间且导出时间较长,于是 ...

最新文章

  1. 使用钩子函数[3] - 建立一个全局的鼠标钩子
  2. SD-WAN如何简化企业网络并节省资金
  3. 2018全球大学AI排名发布,中国高校表现强势!
  4. 央视记者王冰冰为何走红?博导和研究生写了一篇论文进行了分析
  5. Linux基础自学记录六-引导流程解析2
  6. 大家好,我是谢公子,来自深信服—深蓝攻防实验室
  7. BS架构与CS架构的区别(最详细)
  8. pvs-stdio ue4_PVS-Studio –用于C,C ++,C#和Java的静态代码分析器
  9. Raspberry Pi Pico实践系列1-Windows环境下树莓派Pico迷你开发板MicroPython快速上手实践
  10. learn language Part-One
  11. leetcode刷题之 剑指offe 面试题05. 替换空格 犯傻记录
  12. Linux芯片级移植与底层驱动(基于3.7.4内核) --SMP多核启动以及CPU热插拔驱动
  13. TCP/IP协议中分包与重组原理介绍、分片偏移量的计算方法、IPv4报文格式
  14. php curl简单采集图片生成base64编码(并附curl函数参数说明)
  15. Android App Bundle 自动打包原理
  16. 盈世邮箱服务器pop3,iPhone (苹果手机)盈世邮箱POP3设置
  17. JavaScript基础总结(2)
  18. docker 部署 jetbrains license server
  19. unity网络实战开发(丛林战争)-前期知识准备(010-在服务器端解析数据)
  20. MECE法则-整理背景知识

热门文章

  1. (最详细)小米MIX 2的USB调试模式在哪里打开的步骤
  2. 王子走到公主代码java,迷宫营救公主算法
  3. 如何快速进入人工智能NLP/CV热门领域
  4. php 位运算符的实际应用(权限判断)
  5. 深度学习光学字符识别(OCR)
  6. c语言bmp图像YUV转化成RGB,RGB与YUV图像格式的相互转换
  7. 拿到腾讯 Offer ,经验分享!
  8. 用STM32F103读取JY62角度传感器的陀螺仪、加速度的数据
  9. Hadoop学习笔记(三):java操作Hadoop
  10. 深入浅出解析ChatGPT引领的科技浪潮【AI行研商业价值分析】