EasyExcel判断导入时是否符合给定模板

问题描述

在做系统的导入导出模块时需要在导入时判断用户导入的表格是否符合给定的模板,该系统导入导出使用的是EasyExcel,因此在实现该功能时是基于EasyExcel的

解决方案

创建Spring Boot项目,并添加如下依赖

java 复制代码
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>2.2.7</version>
</dependency>

创建导入时数据对应的实体类,并使用@ExcelProperty注解配置模板表头

java 复制代码
public class EasyExcelData {
    @ExcelProperty(value = "学号", index = 0)
    private String no;
    @ExcelProperty(value = "姓名", index = 1)
    private String name;
    @ExcelProperty(value = "性别", index = 2)
    private String gender;

    private String errorReason;

    public String getNo() {
        return no;
    }

    public void setNo(String no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getErrorReason() {
        return errorReason;
    }

    public void setErrorReason(String errorReason) {
        this.errorReason = errorReason;
    }

    @Override
    public String toString() {
        return "EasyExcelData{" +
                "no='" + no + '\'' +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                ", errorReason='" + errorReason + '\'' +
                '}';
    }
}

创建监听类并继承AnalysisEventListener类,重写invokeHeadMap方法,在该方法中判断是否符合模板

java 复制代码
public class EasyExcelDemoListener extends AnalysisEventListener<EasyExcelData> {

    private List<EasyExcelData> correctData = new ArrayList<>();
    private List<EasyExcelData> errorData = new ArrayList<>();

    /**
     * 在这里进行模板的判断
     * @param headMap 存放着导入表格的表头,键是索引,值是名称
     * @param context
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        /*
        count 记录模板表头有几个,用以判断用户导入的表格是否和模板完全一致
        如果用户导入表格较模板的表头多,但其余符合模板,这样不影响则不需要
         */
        int count = 0;
        // 获取数据实体的字段列表
        Field[] fields = EasyExcelData.class.getDeclaredFields();
        // 遍历字段进行判断
        for (Field field : fields) {
            // 获取当前字段上的ExcelProperty注解信息
            ExcelProperty fieldAnnotation = field.getAnnotation(ExcelProperty.class);
            // 判断当前字段上是否存在ExcelProperty注解
            if (fieldAnnotation != null) {
                ++count;
                // 存在ExcelProperty注解则根据注解的index索引到表头中获取对应的表头名
                String headName = headMap.get(fieldAnnotation.index());
                // 判断表头是否为空或是否和当前字段设置的表头名不相同
                if (StringUtils.isEmpty(headName) || !headName.equals(fieldAnnotation.value()[0])) {
                    // 如果为空或不相同,则抛出异常不再往下执行
                    throw new RuntimeException("模板错误,请检查导入模板");
                }
            }
        }

        // 判断用户导入表格的标题头是否完全符合模板
        if (count != headMap.size()) {
            throw new RuntimeException("模板错误,请检查导入模板");
        }
    }

    /**
     * 在这里可以进行数据的解析,每读取一条数据都会执行这个方法
     * @param easyExcelData 当前读取的数据
     * @param analysisContext
     */
    @Override
    public void invoke(EasyExcelData easyExcelData, AnalysisContext analysisContext) {
        if (StringUtils.isEmpty(easyExcelData.getNo())) {
            easyExcelData.setErrorReason("学号为空");
            errorData.add(easyExcelData);
        } else if (StringUtils.isEmpty(easyExcelData.getName())) {
            easyExcelData.setErrorReason("姓名为空");
            errorData.add(easyExcelData);
        } else if (StringUtils.isEmpty(easyExcelData.getGender())) {
            easyExcelData.setErrorReason("性别为空");
            errorData.add(easyExcelData);
        } else {
            correctData.add(easyExcelData);
        }

    }

    /**
     * 这里是读取完成后执行的方法
     * @param analysisContext
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 打印没有错误的数据
        System.out.println(correctData);
        // 打印有错误的数据
        System.out.println(errorData);
    }
}

进行测试,测试用到的表格可到EasyExcel判断导入时是否符合给定模板测试表格获取

java 复制代码
@Test
public void testEasyExcelReadError() {
    // 读取错误表格
    String fileName = "excel" + File.separator + "demo-error.xlsx";
    EasyExcel.read(fileName, EasyExcelData.class, new EasyExcelDemoListener()).sheet().doRead();
}

@Test
public void testEasyExcelReadCorrect() {
    // 读取正确表格
    String fileName = "excel" + File.separator + "demo-correct.xlsx";
    EasyExcel.read(fileName, EasyExcelData.class, new EasyExcelDemoListener()).sheet().doRead();
}
相关推荐
一只小小翠2 天前
EasyExcel 模板+公式填充
java·easyexcel
谈谈的心情9 天前
EasyExcel 动态设置表格的背景颜色和排列
java·easyexcel·导出表格
weixin_446707741 个月前
使用easyexcel导出复杂模板,同时使用bean,map,list填充
java·excel·easyexcel
pingzhuyan1 个月前
EasyExcel: 结合springboot实现表格导出入(单/多sheet), 全字段校验,批次等操作(全)
java·spring boot·servlet·threadlocal·easyexcel
Funky_oaNiu1 个月前
如何使用EasyExcel生成多列表组合填充的复杂Excel示例
java·excel·easyexcel
智汇探长1 个月前
EasyExcel自定义设置Excel表格宽高
java·excel·easyexcel
救救孩子把2 个月前
阿里公告:停止 EasyExcel 更新与维护
java·excel·easyexcel
STARBLOCKSHADOW2 个月前
【EasyExcel】EasyExcel导出表格包含合计行、自定义样式、自适应列宽
java·easyexcel·自定义导出
zzzgd8162 个月前
easyexcel实现自定义的策略类, 最后追加错误提示列, 自适应列宽,自动合并重复单元格, 美化表头
java·excel·表格·easyexcel·导入导出
友善的鸡蛋2 个月前
解决:使用EasyExcel导入Excel模板时出现数据导入不进去的问题
java·easyexcel·excel导入