spring boot+easyExcel+多线程导出excel文件

1.先把数据查询出来,进行分页查询,比如一次查询出来1W条,处理一万条

// 创建一个对象
List cusOrderInfoList = new ArrayList<>();
// 
List cusOrderInfoData1 = Collections.synchronizedList(cusOrderInfoList);

int j = 0
while (true) {
    // 进行查询数据库,分页查询,防止一下查询十几万数据出来
    // 比如一次只查询出1W条数据
    // ...

    TaskDisposeUtils.dispose(orderInfoListList, OrderInfoLog -> {
        // 进行拼接对象
        CusOrderInfoData cusOrderInfoData = new CusOrderInfoData();
        cusOrderInfoData.setA("a");
        cusOrderInfoData.setB("B")
        cusOrderInfoData1.add(cusOrderInfoData)
    });

    // 进行分页写入
    WriteSheet writeSheet = EasyExcel.writerSheet(j, "Sheet" + j).head(CusOrderInfoData.class)
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
            excelWriter.write(list, writeSheet);
}

2.进行浏览器下载

excelWriter.finish();

String fileName ="文件名称";
// 下载EXCEL,返回给前段stream流
response.setContentType("application/octet-stream;charset=ISO8859_1");
fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
outputStream.flush();
outputStream.close();

3.工具类


import com.alibaba.fastjson.JSONObject;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 多线程任务处理工具类
 */
public class TaskDisposeUtils {
    //并行线程数
    public static final int POOL_SIZE = 8;

    /**
     * 并行处理,并等待结束
     *
     * @param taskList 任务列表
     * @param consumer 消费者
     * @param 
     * @throws InterruptedException
     */
    public static  void dispose(List taskList, Consumer consumer) throws InterruptedException {
        dispose(true, POOL_SIZE, taskList, consumer);
    }

    /**
     * 并行处理,并等待结束
     *
     * @param moreThread 是否多线程执行
     * @param poolSize   线程池大小
     * @param taskList   任务列表
     * @param consumer   消费者
     * @param 
     * @throws InterruptedException
     */
    public static  void dispose(boolean moreThread, int poolSize, List taskList, Consumer consumer) throws InterruptedException {
        if (CollectionUtils.isEmpty(taskList)) {
            return;
        }
        //如果是多线程且核心线程数大于一则进入方法
        if (moreThread && poolSize > 1) {
            poolSize = Math.min(poolSize, taskList.size());
            ExecutorService executorService = null;
            try {
                //新建一个固定大小的线程池 核心线程数为poolSize
                executorService = Executors.newFixedThreadPool(poolSize);
                //juc工具类 用于让必须所有任务都处理完后才进行下一步
                CountDownLatch countDownLatch = new CountDownLatch(taskList.size());
                for (T item : taskList) {
                    executorService.execute(() -> {
                        try {
                            //消费任务
                            consumer.accept(item);
                        } finally {
                            //处理完后减一
//                            System.out.println("子线程:" + Thread.currentThread().getName() + "执行完成");
                            countDownLatch.countDown();
                        }
                    });
                }
                //在此等待 当countDownLatch变成0后才继续进行下一步
                countDownLatch.await();
            } finally {
                if (executorService != null) {
                    executorService.shutdown();
                }
            }
        } else {
            for (T item : taskList) {
                consumer.accept(item);
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //生成1-10的10个数字,放在list中,相当于10个任务
        List list = Stream.iterate(1, a -> a + 1).limit(10).collect(Collectors.toList());
        JSONObject object = new JSONObject();
        object.put("name", "sss");
        //启动多线程处理list中的数据,每个任务休眠时间为list中的数值
        // Consumer c= item -> {
        // try {
        // long startTime = System.currentTimeMillis();
        // object.put("s",item);
        // TimeUnit.SECONDS.sleep(item);
        // long endTime = System.currentTimeMillis();
        // System.out.println(object.toJSONString());
        // System.out.println(System.currentTimeMillis() + ",任务" + item + "执行完毕,耗时:" + (endTime - startTime));
        // } catch (InterruptedException e) {
        // e.printStackTrace();
        // }
        // };
        TaskDisposeUtils.dispose(list, item -> {
            try {
                long startTime = System.currentTimeMillis();
                object.put("s", item);
                TimeUnit.SECONDS.sleep(item);
                long endTime = System.currentTimeMillis();
                System.out.println(object.toJSONString());
                System.out.println(System.currentTimeMillis() + ",任务" + item + "执行完毕,耗时:" + (endTime - startTime));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        //上面所有任务处理完毕完毕之后,程序才能继续
        System.out.println(list + "中的任务都处理完毕!");
    }
}

你可能感兴趣的:(java,spring,boot)