excle导入复杂表头:校验表头和数据

校验表头和数据

ExcelListener:

java 复制代码
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
     */
    @Override
    public 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();
    }

    // 读取表头时调用
    @Override
    public 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();
    }

    // 读取完成后调用
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
        System.out.println("所有数据解析完成!");
    }

    // 如果读取Excel时出现异常,则会调用这个方法
    @Override
    public 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()));
    }
}
 

用法:

java 复制代码
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;
    }

PaySiStaffUploadExcelVO

@Accessors(chain = false) // 设置 chain = false,避免导入数据解析不到

java 复制代码
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = false) // 设置 chain = false,避免导入数据解析不到
public class PaySiStaffUploadExcelVO implements Serializable {

    private static final long serialVersionUID = 1L;

    @Schema(description = "部门")
    @ExcelProperty(index = 0)
    private String belongDept1;

    @Schema(description = "养老保险-单位")
    @ExcelProperty(index = 1)
    private String amount1;

    @Schema(description = "养老保险-个人")
    @ExcelProperty(index = 2)
    private String amount2;

    @Schema(description = "医疗保险-单位")
    @ExcelProperty(index = 3)
    private String amount3;

    @Schema(description = "医疗保险-个人")
    @ExcelProperty(index = 4)
    private String amount4;

    @Schema(description = "地方附加医疗险-单位")
    @ExcelProperty(index = 5)
    private String amount5;

    @Schema(description = "失业保险-单位")
    @ExcelProperty(index = 6)
    private String amount6;

    @Schema(description = "失业保险-个人")
    @ExcelProperty(index = 7)
    private String amount7;

    @Schema(description = "工伤保险-单位")
    @ExcelProperty(index = 8)
    private String amount8;

    @Schema(description = "部门编码")
    @ExcelProperty(index = 9)
    private String belongDept;

}
相关推荐
为什么每天的风都这么大10 分钟前
Vscode/Code-server无网环境安装通义灵码
ide·vscode·阿里云·编辑器·ai编程·code-server
阿龟在奔跑1 小时前
引用类型的局部变量线程安全问题分析——以多线程对方法局部变量List类型对象实例的add、remove操作为例
java·jvm·安全·list
飞滕人生TYF1 小时前
m个数 生成n个数的所有组合 详解
java·递归
代码小鑫1 小时前
A043-基于Spring Boot的秒杀系统设计与实现
java·开发语言·数据库·spring boot·后端·spring·毕业设计
真心喜欢你吖1 小时前
SpringBoot与MongoDB深度整合及应用案例
java·spring boot·后端·mongodb·spring
激流丶1 小时前
【Kafka 实战】Kafka 如何保证消息的顺序性?
java·后端·kafka
开心点幸运点2 小时前
Excel——宏教程(1)
excel
周全全2 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
uzong2 小时前
一个 IDEA 老鸟的 DEBUG 私货之多线程调试
java·后端
AiFlutter2 小时前
Java实现简单的搜索引擎
java·搜索引擎·mybatis