easyExcel关于导入导出的用法及校验
引包:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.6</version>
</dependency>
一、导入
(一)controller层
@DataLog(operationName = "导入了因私出国", operationDesc = "", methodType = MethodTypeEnum.IMPORT_TYPE)
@ApiOperation(value = "因私出国-导入")
@ApiOperationSupport(order = 5)
@GetMapping(Urls.Abroad.importAbroad)
public JsonObject<Object> importAbroad(String fileName, HttpServletRequest request) {
List<String> list = csAbroadService.importAbroad(fileName, request);
return new JsonSuccessObject<>(list, "导入成功");
}
请求方式用post或get都行,这里使用get是为了做校验下载异常数据文件。fileName是前端通过公共组件上传后的文件名,后端可以获取上传路径,拼一下就能取得上传后文件的绝对路径。
也可以使用multipart/form-data的请求形式上传,这时后端需要改变下接收方式:
@DataLog(operationName = "导入了离任审计", operationDesc = "", methodType = MethodTypeEnum.IMPORT_TYPE)
@ApiOperation(value = "离任审计-导入")
@ApiOperationSupport(order = 12)
@PostMapping(Urls.OffAudit.importAudit)
public JsonObject<Object> importAudit(MultipartFile file, HttpServletRequest request) throws IOException {
List<String> list = csOffAuditService.importAudit(file, request);
return new JsonSuccessObject<>(list, "导入成功");
}
(二)service层
/**
* 因私出国-导入
*
* @param fileName
* @param request
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public List<String> importAbroad(String fileName, HttpServletRequest request) {
List<String> recordIds = new ArrayList<>();
String userId = userSessionService.getCurrentUserId(request);
String nodeId = userSessionService.getCurrentUserNodeId(request);
String upload = fileConfigProperties.getUpload();
String filePath = "";
filePath = upload + File.separator + fileName;
// 读Excel
EasyExcel.read(filePath, CsA12Do.class,
new AbroadListener(recordIds, userId, nodeId, upload, this))
.sheet().doRead();
// 控制同步功能
if (recordIds.size() == 0) {
return null;
}
// by hansc 12.10 调用人员库接口
LambdaQueryWrapper<CsA12> wrapper = Wrappers.lambdaQuery();
wrapper.in(CsA12::getRecordid, recordIds);
List<CsA12> list = list(wrapper);
for (CsA12 item : list) {
csA01Service.insertExportInPerson(item.geta00a(), item.geta1250(), item.geta1251(), request);
}
// 同步A00
Integer a00 = csRecordService.synA00("a12", "A1250", "RECORDID",
nodeId, recordIds);
// 同步现任职务
/*Integer job = csRecordService.synJob("a12", "A1251", "RECORDID",
nodeId, recordIds);*/
// 同步高管类别
csA12Mapper.synGrade(recordIds, nodeId);
// 删除文件
// boolean b = DownloadUtil.deleteFile(filePath);
return recordIds;
}
filePath即为上传的文件的绝对路径。EasyExcel的read方法可以读取Excel的sheet页的内容。三个参数,分别是文件绝对路径,一个Class类和一个自定义的监听器:
1、 Class类对应的是读取的Excel文件的模板类,它与Excel表格列对应:
index是从0开始,CsA12Do模板类的属性和Excel表格列一一对应。
2、 自定义的监听器类需要继承easyExcel的一个父类AnalysisEventListener,详情下面继续说
3、 sheet()方法为指定读取哪个sheet页,参数可以填sheet页的页名或者序号,不写的话默认就是Sheet1:
(三)监听器
1、 easyExcel的原理是按行读取,即每次读取一行时新建一个监听器类,在监听器类中对读取到的内容进行处理。因为是通过new关键字新建监听器类,因此不能使用sprinboot的注入功能注入我们的bean对象,所以可以考虑使用构造器,将我们需要的bean对象以及一些自定义变量传进监听器中。
package com.bdsoft.cs.controller.utils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.bdsoft.cs.entity.CodeValue;
import com.bdsoft.cs.entity.CsA12;
import com.bdsoft.cs.query.CsA12Do;
import com.bdsoft.cs.service.daily.CsAbroadService;
import com.bdsoft.cs.utils.ConvertUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* @author hanshaocong
* @since 2021-10-22
*/
public class AbroadListener extends AnalysisEventListener<CsA12Do> {
private static final int batchSize = 1000;
private LocalDateTime time = LocalDateTime.now();
private