Excel数据导入
使用easyexcel和hutool-poi实现excel导入
1、pom依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-poi</artifactId>
<version>5.8.21</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
2、导入流程描述
2.1、读取excel
读取excel中的源数据
2.2、数据校验
2.2.1 对源数据进行数据校验
2.2.2 将满足校验规则的数据放入normalList中
2.2.3 将不满足校验规则的数据放入errorList中
2.2.4 将最后的成功、失败数量结果放入importResult中
2.2.5 将校验结果返回给前端
将校验后的数据normalList、errorList、importResult返回给前端,如果存在错误数据(及errorList不为空)则提示用户更改,用户更改后重新对更改后的excel文件执行数据校验操作,直达所有的数据都是正确数据(及errorList为空)则执行数据入库操作
2.3 数据入库
将数据校验完成后的normalList拿到(此时的errorList一定是空的),直接进行入库操作,如果存在入库失败的数据则放入errorList中直接返给前端展示出来错误原因,不另外做其他操作
3、代码示例
3.1 excel导入返回VO
/**
* @author: yc
* @des: excel导入vo
* @date: 2024/07/17 20:57
*/
@Data
public class ExcelImportVO {
@ApiModelProperty("错误的数据")
private List<?> errorList;
@ApiModelProperty("正常的数据")
private List<?> normalList;
@ApiModelProperty("导入结果")
private String importResult;
}
3.2 用户导入模板
/**
* @author: yc
* @des: 用户导入模板
* @date: 2024/07/18 13:35
*/
@Data
public class UserImportTemplate {
/**
* 行号
*/
private Integer rowNumber;
/**
* 姓名
*/
@ExcelProperty("姓名")
@ColumnWidth(20)
private String realName;
/**
* 手机号
*/
@ExcelProperty("手机号")
@ColumnWidth(20)
private String mobile;
/**
* 组织名称
*/
@ExcelProperty("组织名称")
@ColumnWidth(20)
private String organizeName;
private String organizeId;
/**
* 部门名称
*/
@ExcelProperty("部门名称")
@ColumnWidth(20)
private String departmentName;
private String departmentId;
/**
* 校验信息
*/
private String verifyMsg;
/**
* @author: yc
* @des: 校验
* @date: 2024/07/18 14:00
*/
public void verify(List<BaseDepartment> departmenList, BaseDepartService baseDepartService){
StringBuilder msg = new StringBuilder();
// 姓名
if(StringUtils.isBlank(this.realName)){
msg.append("姓名不能为空");
}
// 手机号
if(StringUtils.isBlank(this.mobile)){
msg.append("姓名不能为空");
}else{
if (!Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$").matcher(this.mobile).matches()) {
msg.append("手机号不正确");
}
}
// 组织名称
if(StringUtils.isBlank(this.organizeName)){
msg.append("组织名称不能为空");
}
// 部门名称
if(StringUtils.isBlank(this.departmentName)){
msg.append("部门名称不能为空");
}else{
BaseDepartment department = baseDepartService.getDepartmentByName(this.departmentName, departmenList);
if(Objects.isNull(department)){
msg.append("部门不存在");
}else{
this.departmentId = department.getDepartmentId();
}
}
this.verifyMsg = msg.toString();
}
/**
* @author: yc
* @des: 模板转实体
* @date: 2024/07/18 14:09
*/
public BaseUser template2entity(){
BaseUser baseUser = new BaseUser();
baseUser.setUserId(IdUtil.simpleUUID());
baseUser.setAccount(this.mobile);
baseUser.setPassword("8e00646ca539d84f41e085c6ee9a54ba");
baseUser.setSecretkey("f240625eb8a38ae1");
baseUser.setRealName(this.realName);
baseUser.setMobile(this.mobile);
baseUser.setOrganizeId(this.organizeId);
baseUser.setDepartmentId(this.departmentId);
baseUser.setDeleteMark(0);
baseUser.setEnabledMark(1);
baseUser.setModifyDate(new Date());
baseUser.setCreateDate(new Date());
return baseUser;
}
}
3.3 excel文件数据读取、校验
/**
* @author: yc
* @des: excel导入前检验
* @date: 2024/07/18 10:56
*/
@Override
public Result<ExcelImportVO> excelImportVerify(MultipartFile file) {
ExcelImportVO excelImportVO = new ExcelImportVO();
if(Objects.isNull(file)){
return Result.fail(ResultCode.GLOBAL_PARAM_ERROR.getCode(),"上传文件不能为空");
}
String fileName = file.getOriginalFilename();
//文件名
String name = fileName.substring(0,fileName.lastIndexOf("."));
//文件类型
String type = fileName.substring(fileName.lastIndexOf("."));
if(StringUtils.isBlank(type) || (!type.equals(".xlsx") && !type.equals(".xls"))){
return Result.fail(ResultCode.FAILURE.getCode(),"文件名格式不正确,请上传.xlsx或.xls文件");
}
//判断文件名长度是否小于3,解决 临时文件 too short问题
fileName = name.length() <= 3 ? name + (new Random().nextInt(900)+100) + type : fileName;
// 从excel中拿到数据
List<UserImportTemplate> dataList = new ArrayList<>();
try {
ExcelReader excelReader = ExcelUtil.getReader(file.getInputStream());
List<List<Object>> excelDataList = excelReader.read(1);
if(CollectionUtils.isEmpty(excelDataList)){
return Result.fail(ResultCode.FAILURE.getCode(),"无数据导入");
}
AtomicInteger rowNumber = new AtomicInteger(1);
excelDataList.forEach(i -> {
Object[] rowData = i.toArray(new Object[10]);
UserImportTemplate template = new UserImportTemplate();
template.setRealName(null == rowData[0] ? "" : String.valueOf(rowData[0]));
template.setMobile(null == rowData[1] ? "" : String.valueOf(rowData[1]));
template.setOrganizeName(null == rowData[2] ? "" : String.valueOf(rowData[2]));
template.setDepartmentName(null == rowData[3] ? "" : String.valueOf(rowData[3]));
template.setRowNumber(rowNumber.getAndAdd(1));
dataList.add(template);
});
// 数据校验
// 部门信息
List<BaseDepartment> departmenList = baseDepartService.list();
dataList.forEach(i -> {
i.verify(departmenList,baseDepartService);
});
StringBuilder resultMsg = new StringBuilder();
// 正常数据
excelImportVO.setNormalList(dataList.stream().filter(i -> StringUtils.isBlank(i.getVerifyMsg())).collect(Collectors.toList()));
// 错误数据
excelImportVO.setErrorList(dataList.stream().filter(i -> StringUtils.isNotBlank(i.getVerifyMsg())).collect(Collectors.toList()));
resultMsg.append("成功" + excelImportVO.getNormalList().size() + "条");
if(!CollectionUtils.isEmpty(excelImportVO.getErrorList())){
resultMsg.append(",失败" + excelImportVO.getErrorList().size() + "条");
}
excelImportVO.setImportResult(resultMsg.toString());
} catch (Exception e) {
return Result.fail(ResultCode.FAILURE.getCode(),e.getMessage());
}
return Result.data(excelImportVO);
}
3.4 数据入库
/**
* @author: yc
* @des: excel导入
* @date: 2024/07/18 10:57
*/
@Override
public Result<ExcelImportVO> excelImport(List<UserImportTemplate> successList) {
ExcelImportVO excelImportVO = new ExcelImportVO();
if(CollectionUtils.isEmpty(successList)){
return Result.fail(ResultCode.FAILURE.getCode(),"导入数据不存在");
}
List<UserImportTemplate> errorList = new ArrayList<>();
for(UserImportTemplate template : successList){
try {
super.save(template.template2entity());
}catch (Exception e){
template.setVerifyMsg("当前数据已存在");
errorList.add(template);
}
}
successList.removeAll(errorList);
excelImportVO.setNormalList(successList);
excelImportVO.setErrorList(errorList);
StringBuilder resultMsg = new StringBuilder();
resultMsg.append("成功" + excelImportVO.getNormalList().size() + "条");
if(!CollectionUtils.isEmpty(excelImportVO.getErrorList())){
resultMsg.append(",失败" + excelImportVO.getErrorList().size() + "条");
}
excelImportVO.setImportResult(resultMsg.toString());
return Result.data(excelImportVO);
}