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";
}
}