spring boot easyexcel

1.pom

  <!-- easyexcel 依赖 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>

2.ExcelListener

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.example.springbootexcel.eneity.ExcelEntity;
import com.example.springbootexcel.thread.ExcelThread;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

@Slf4j
public class ExcelListener extends AnalysisEventListener<ExcelEntity> {

    /**
     * 多线程集合
     */
    private List<ExcelEntity> list = Collections.synchronizedList(new ArrayList<>());

    /**
     * 创建线程
     */
    private static final int CORE_POOL_SIZE = 5; //核心线程数
    private static final int MAX_POOL_SIZE = 10; //最大线程数

    private static final int QUEUE_CAPACITY = 100; //队列大小

    private static final Long KEEP_ACTIVE_TIME= 1L; //存活时间


    public ExcelListener(){

    }

    public List<ExcelEntity> getList() {
        return list;
    }

    public void setList(List<ExcelEntity> list) {
        this.list = list;
    }

    @Override
    public void invoke(ExcelEntity excelEntity, AnalysisContext analysisContext) {
        log.info("接收到excel数据");
        if(excelEntity!=null){
            list.add(excelEntity);
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        log.info("解析结束,开始保存数据");

        //创建线程池
        ExecutorService executorService = new ThreadPoolExecutor(CORE_POOL_SIZE,
                MAX_POOL_SIZE,
                KEEP_ACTIVE_TIME,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(QUEUE_CAPACITY),
                new ThreadPoolExecutor.CallerRunsPolicy());

        //指定每个线程处理的导入数量,暂定1000
        int singleThreadDealCount = 1000;

        //每个线程需要处理的数量以及总数,计算需要提交到线程池的线程数量
        int threadSize = (list.size() / singleThreadDealCount) + 1;

        //计算需要导入的数据总数
        int rowSize = list.size() + 1;

        //开始时间
        long startTime = System.currentTimeMillis();

        //线程开始处理的位置
        int startPosition = 0;

        //线程结束位置
        int endPosition = 0;

        CountDownLatch countDownLatch = new CountDownLatch(threadSize);

        for(int i=0;i<threadSize;i++){
            if((i+1) == threadSize){
                startPosition = (i * singleThreadDealCount);
                endPosition = rowSize - 1;
            }else {
                startPosition = (i * singleThreadDealCount);
                endPosition = (i + 1) * singleThreadDealCount;
            }

            //多线程处理list数据
            ExcelThread excelThread = new ExcelThread(startPosition,endPosition,list,countDownLatch);

            executorService.execute(excelThread);
        }

        try{
            countDownLatch.await();
        }catch (Exception e){
            log.error("多线程执行失败");
        }

        executorService.shutdown();

        long endTime = System.currentTimeMillis();

        log.info("总耗时:{}",(endTime - startTime));
    }
}

3.thread

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;

@Slf4j
@Component
public class ExcelThread implements Runnable{
    //线程开始处理的位置
    private int startPosition;

    //线程结束位置
    private int endPosition;

    /**
     * 多线程集合
     */
    private List<ExcelEntity> list = Collections.synchronizedList(new ArrayList<>());

    private CountDownLatch count;

    public ExcelThread(){

    }

    public ExcelThread(int startPosition, int endPosition, List<ExcelEntity> list, CountDownLatch count) {
        this.startPosition = startPosition;
        this.endPosition = endPosition;
        this.list = list;
        this.count = count;
    }

    @Override
    public void run() {
        List<ExcelEntity> entityList = list.subList(startPosition,endPosition);
        //处理list数据集合

        count.countDown();
    }
}

4.ExcelEntity

import lombok.Data;

@Data
public class ExcelEntity {
}

5.ExcelController

import com.alibaba.excel.EasyExcel;
import com.example.springbootexcel.eneity.ExcelEntity;
import com.example.springbootexcel.listener.ExcelListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

@Slf4j
@RestController
@RequestMapping(value = "/excel")
public class ExcelController {

    @GetMapping(value = "/import")
    public String importExcel(@RequestParam("file")MultipartFile file){
        try {
            EasyExcel.read(file.getInputStream(), ExcelEntity.class,new ExcelListener()).sheet().doRead();
        } catch (IOException e) {
            log.info("读取excel失败");
        }

        return "test";
    }
}
相关推荐
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭11 分钟前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
AskHarries2 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion3 小时前
Springboot的创建方式
java·spring boot·后端
Yvemil74 小时前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务
星河梦瑾5 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
计算机学长felix6 小时前
基于SpringBoot的“交流互动系统”的设计与实现(源码+数据库+文档+PPT)
spring boot·毕业设计
.生产的驴6 小时前
SpringBoot 对接第三方登录 手机号登录 手机号验证 微信小程序登录 结合Redis SaToken
java·spring boot·redis·后端·缓存·微信小程序·maven
顽疲6 小时前
springboot vue 会员收银系统 含源码 开发流程
vue.js·spring boot·后端
撒呼呼7 小时前
# 起步专用 - 哔哩哔哩全模块超还原设计!(内含接口文档、数据库设计)
数据库·spring boot·spring·mvc·springboot
因我你好久不见7 小时前
springboot java ffmpeg 视频压缩、提取视频帧图片、获取视频分辨率
java·spring boot·ffmpeg