一、excel 文件的导入:
1、介绍:
使用alibaba 的 easyExcel 组建实现。
2、实现过程:
1)pom文件引入jar包依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>LATEST</version>
</dependency>
2)根据要导入的excel的内容,写一个接收数据的对象。
注意,@ExcelProperty 注解内的值要和excel的列头一模一样,最好是粘贴复制,否则读出来的数据有可能是null。
@Data
public class ExcelImpCsDetailDto {
@ExcelProperty(value = "A")
private String csCode;
@ExcelProperty(value = "B")
private String code;
@ExcelProperty(value = "C")
private String name;
}
3)利用刚建立的对象写一个监听类实现 AnalysisEventListener<T> 类,(解析出的每条数据的返回)
@Slf4j
public class ExcelImpCsDetailListener extends AnalysisEventListener<ExcelImpCsDetailDto> {
private List<ExcelImpCsDetailDto> importList = new ArrayList<>();
@Autowired
private StdTestDetailMapper stdTestDetailMapper;
//返回结果
private List<StdTestDetail> dtoList = new ArrayList<>();
public ExcelImpCsDetailListener(StdTestDetailMapper stdTestDetailMapper) {
this.stdTestDetailMapper = stdTestDetailMapper;
}
@Override
public void invoke(ExcelImpCsDetailDto importCs, AnalysisContext analysisContext) {
importList.add(importCs);
}
@SneakyThrows
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
for (ExcelImpCsDetailDto impModel : importList) {
StdTestDetail det = new StdTestDetail();
det.setId(ScUtil.getUUID());
det.setCode(impModel.getCode());
det.setName(impModel.getName());
det.setDes(impModel.getName());
det.setCsCode(impModel.getCsCode());
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
det.setStartDate(f.parse("2022-01-01 00:00:00"));
det.setEndDate(f.parse("2022-12-31 23:59:59"));
dtoList.add(det);
}
}
//返回导入结果 交互
public List<StdTestDetail> getImportResult() {
return dtoList;
}
}
这个监听类需要写一个 ExcelImpCsDetailListener 构造函数,便于把保存数据的mapper注入进来。还要重写该父类的 invoke 以及 doAfterAllAnalysed 方法,把识别到的excel行数据转化为我们熟系的 ExcelImpCsDetailDto 对象集合。拿到数据之后就可以进行保存,筛选等操作。
4)可以在监听类里写保存数据的代码。此处没保存是因为由于excel数据量过多,mybatis的动态sql一次性导入过多的数据会报sql太长,需要分步执行,我选择把解析的数据返回到server层,由注入到server层的mybatis的 SqlSessionTemplate 类里,利用这个类可以分步执行。
/**
*导入excel数据
*/
@Override
@Transactional(propagation= Propagation.REQUIRED,rollbackFor= Exception.class)
public void importExcel(MultipartFile file) throws IOException {
//实例化EASYEXCEL监听器
ExcelImpCsDetailListener impListener = new ExcelImpCsDetailListener(stdTestDetailMapper);
//执行导入过程
EasyExcel.read(file.getInputStream(), ExcelImpCsDetailDto.class, impListener).sheet().doRead();
List<StdTestDetail> list = impUserListener.getImportResult();
batchInsert(list);
}
//大批量插入数据
private int batchInsert( List<StdTestDetail> list) {
SqlSession session = null;
//通过新的session获取mapper
int result=0;
try {
session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
int num = 50;//每次提交50条
int loop = (int) Math.ceil(list.size() / (double) num);
List<StdTestDetail> tempList = new ArrayList<StdTestDetail>(num);
int start, stop=0;
for (int i = 0; i < loop; i++) {
tempList.clear();
start = i * num;
stop = Math.min(i * num + num - 1, list.size() - 1);
for (int j = start; j <= stop; j++) {