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";
    }
}
相关推荐
悟空码字5 小时前
Spring Boot 整合 MongoDB 最佳实践:CRUD、分页、事务、索引全覆盖
java·spring boot·后端
皮皮林5512 天前
拒绝写重复代码,试试这套开源的 SpringBoot 组件,效率翻倍~
java·spring boot
用户908324602734 天前
Spring AI 1.1.2 + Neo4j:用知识图谱增强 RAG 检索(上篇:图谱构建)
java·spring boot
用户8307196840825 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
Java水解5 天前
Spring Boot 视图层与模板引擎
spring boot·后端
Java水解5 天前
一文搞懂 Spring Boot 默认数据库连接池 HikariCP
spring boot·后端
洋洋技术笔记5 天前
Spring Boot Web MVC配置详解
spring boot·后端
初次攀爬者6 天前
Kafka 基础介绍
spring boot·kafka·消息队列
用户8307196840826 天前
spring ai alibaba + nacos +mcp 实现mcp服务负载均衡调用实战
spring boot·spring·mcp
Java水解6 天前
SpringBoot3全栈开发实战:从入门到精通的完整指南
spring boot·后端