excle导入复杂表头:校验表头和数据
校验表头和数据
ExcelListener:
import cn.com.fsg.common.exception.ErrorCode;
import cn.com.fsg.ihro.pay.excel.exceldata.PaySipfDtlTmpUploadExcelVO2;
import cn.com.fsg.ihro.pay.pojo.entity.PaySipfDtlTmpDO;
import cn.com.fsg.ihro.pay.support.util.BigDecimalUtils;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelDataConvertException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;import java.util.ArrayList;
import java.util.List;
import java.util.Map;import static cn.com.fsg.common.exception.util.ServiceExceptionUtil.exception;@Slf4j
@Data
public class PaySipfDtlTmpExcelListener2 extends AnalysisEventListener<PaySipfDtlTmpUploadExcelVO2> {private final List<PaySipfDtlTmpUploadExcelVO2> excelList = new ArrayList<>();private final List<PaySipfDtlTmpDO> list = new ArrayList<>();// 表头行数int n = 0;// 数据行数Integer count = 3;// 金额计数long amountCount = 0;/*** 这个每一条数据解析都会来调用invoke()方法** @param data 数据* @param context context*/@Overridepublic void invoke(PaySipfDtlTmpUploadExcelVO2 data, AnalysisContext context) {// 它会按照你提供的实体对象一行一行的对应赋值,每读取一行就会进入一次这个方法,所以这个方法可以处理单行的数据逻辑,最后添加到list中// 校验数据String s = this.checkData(data);if (StringUtils.isNotBlank(s)) {PaySipfDtlTmpDO tmpDO = new PaySipfDtlTmpDO();tmpDO.setRownum(count);tmpDO.setErrMsg(s.substring(0, s.length() - 1));list.add(tmpDO);}excelList.add(data);count++;}/*** 校验数据** @param data 数据*/private String checkData(PaySipfDtlTmpUploadExcelVO2 data) {StringBuilder s = new StringBuilder();if (StringUtils.isBlank(data.getBelongDept())) {s.append("部门编码不能为空").append(",");}if (StringUtils.isBlank(data.getAmount1())) {amountCount++;// s.append("养老保险-单位不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount1())) {s.append("养老保险-单位格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount2())) {amountCount++;// s.append("养老保险-个人不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount2())) {s.append("养老保险-个人格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount3())) {amountCount++;// s.append("医疗保险-单位不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount3())) {s.append("医疗保险-单位格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount4())) {amountCount++;// s.append("医疗保险-个人不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount4())) {s.append("医疗保险-个人格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount5())) {amountCount++;// s.append("地方附加医疗险-单位不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount5())) {s.append("地方附加医疗险-单位格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount6())) {amountCount++;// s.append("失业保险-单位不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount6())) {s.append("失业保险-单位格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount7())) {amountCount++;// s.append("失业保险-个人不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount7())) {s.append("失业保险-个人格式填写错误").append(",");}if (StringUtils.isBlank(data.getAmount8())) {amountCount++;// s.append("工伤保险-单位不能为空").append(",");} else if (!BigDecimalUtils.isBigDecimal(data.getAmount8())) {s.append("工伤保险-单位格式填写错误").append(",");}return s.toString();}// 读取表头时调用@Overridepublic void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {System.out.println("表头:" + headMap);String s = null;if (n == 0) {s = checkHead1(headMap);} else if (n == 1) {s = checkHead2(headMap);}n++;if (StringUtils.isNotBlank(s)) {throw exception(new ErrorCode(500, s));}}/*** 表头校验** @param headMap 表头* @return 结果*/private String checkHead1(Map<Integer, String> headMap) {StringBuilder s = new StringBuilder();if (StringUtils.isBlank(headMap.get(0)) || !headMap.get(0).equals("部门")) {s.append("第" + 1 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(1)) || !headMap.get(1).equals("养老保险")) {s.append("第" + 2 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(3)) || !headMap.get(3).equals("医疗保险")) {s.append("第" + 4 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(5)) || !headMap.get(5).equals("地方附加医疗险")) {s.append("第" + 6 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(6)) || !headMap.get(6).equals("失业保险")) {s.append("第" + 7 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(8)) || !headMap.get(8).equals("工伤保险")) {s.append("第" + 9 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(9)) || !headMap.get(9).equals("部门编码")) {s.append("第" + 10 + "列表头错误,请参照模板填写").append(",");}return s.toString();}/*** 表头校验** @param headMap 表头* @return 结果*/private String checkHead2(Map<Integer, String> headMap) {StringBuilder s = new StringBuilder();if (StringUtils.isBlank(headMap.get(1)) || !headMap.get(1).equals("单位")) {s.append("第" + 2 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(2)) || !headMap.get(2).equals("个人")) {s.append("第" + 3 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(3)) || !headMap.get(3).equals("单位")) {s.append("第" + 4 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(4)) || !headMap.get(4).equals("个人")) {s.append("第" + 5 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(5)) || !headMap.get(5).equals("单位")) {s.append("第" + 6 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(6)) || !headMap.get(6).equals("单位")) {s.append("第" + 7 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(7)) || !headMap.get(7).equals("个人")) {s.append("第" + 8 + "列表头错误,请参照模板填写").append(",");}if (StringUtils.isBlank(headMap.get(8)) || !headMap.get(8).equals("单位")) {s.append("第" + 9 + "列表头错误,请参照模板填写").append(",");}return s.toString();}// 读取完成后调用@Overridepublic void doAfterAllAnalysed(AnalysisContext context) {System.out.println("所有数据解析完成!");}// 如果读取Excel时出现异常,则会调用这个方法@Overridepublic void onException(Exception exception, AnalysisContext context) {if (exception instanceof ExcelDataConvertException) {ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;// 对于ExcelDataConvertException异常,可以获取到有问题的数据和转换的目标类型System.out.println("数据转换异常:" + excelDataConvertException.getRowIndex() + " -> " + excelDataConvertException.getMessage());}throw exception(new ErrorCode(500, exception.getMessage()));}
}
用法:
public List<PaySipfDtlTmpDO> uploadExcelFile2(MultipartFile file, PaySipfDtlTmpUploadVO result) {List<PaySipfDtlTmpDO> list = new ArrayList<>();PaySipfDtlTmpExcelListener2 excelListener = new PaySipfDtlTmpExcelListener2();try {// 解析excel 从第二行读取数据EasyExcel.read(file.getInputStream(), PaySipfDtlTmpUploadExcelVO2.class, excelListener).sheet().headRowNumber(2).doRead();} catch (Exception e) {log.error("======uploadExcelFile1======上传文件存在格式或信息错误,无法解析");throw exception(new ErrorCode(500, "文件无法解析:" + e.getMessage()));}// 获取excel数据List<PaySipfDtlTmpUploadExcelVO2> excelList = excelListener.getExcelList();if (CollectionUtils.isEmpty(excelList)) {throw exception(new ErrorCode(500, "文件不能为空"));}// 获取错误信息List<PaySipfDtlTmpDO> tmpDOList = excelListener.getList();if (CollectionUtils.isNotEmpty(tmpDOList)) {result.setFlag(YesOrNo.NO.getCode());return tmpDOList;} else {// 判断金额是否全部为空long size = excelList.size() * 8L;long amountCount = excelListener.getAmountCount();if (amountCount == size) {throw exception(new ErrorCode(500, "所有金额不能都为空"));}result.setFlag(YesOrNo.YES.getCode());// 数据转换for (PaySipfDtlTmpUploadExcelVO2 excelVO : excelList) {// 金额 行转列PaySipfDtlTmpDO tmpDO1 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO1.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount1()));tmpDO1.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_17.getKey());list.add(tmpDO1);PaySipfDtlTmpDO tmpDO2 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO2.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount2()));tmpDO2.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_23.getKey());list.add(tmpDO2);PaySipfDtlTmpDO tmpDO3 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO3.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount3()));tmpDO3.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_18.getKey());list.add(tmpDO3);PaySipfDtlTmpDO tmpDO4 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO4.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount4()));tmpDO4.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_24.getKey());list.add(tmpDO4);PaySipfDtlTmpDO tmpDO5 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO5.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount5()));tmpDO5.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_19.getKey());list.add(tmpDO5);PaySipfDtlTmpDO tmpDO6 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO6.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount6()));tmpDO6.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_20.getKey());list.add(tmpDO6);PaySipfDtlTmpDO tmpDO7 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO7.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount7()));tmpDO7.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_26.getKey());list.add(tmpDO7);PaySipfDtlTmpDO tmpDO8 = PaySipfDtlTmpConvert.INSTANCE.convertExcel(excelVO);tmpDO8.setAmount(BigDecimalUtils.strToBigDecimal(excelVO.getAmount8()));tmpDO8.setPersPremType(PersPremTypeEnum.PERS_PREM_TYPE_21.getKey());list.add(tmpDO8);}// 设置条数result.setCount(excelList.size());}return list;}