• easyExcel解析复杂表头数据


    一般在工作中,常常遇到各种各样的excel需要解析,只按照正确的模板来解析,测试就会说,一般有经验的测试会使用不同的模板来导入数据,说白了就是想说他很专业嘛,这个能理解,那么这块就需要重新校验表头,甚至是样例数据都要校验,本文只校验表头数据,至于样例那些数据先不校验,毕竟bug改完了自己光明正大的摸鱼影响很不好,剩下的就看看测试专业不专业了,有需要了再加校验呗
    在这里插入图片描述

    实体类

    public class ExcelVO {
    
        @ExcelProperty(value = "编号")
        @ApiModelProperty("编码,不可重复")
        private String code;
    
        @ExcelProperty(value = "*中文名称")
        @ApiModelProperty("标准的中文名称")
        private String cnName;
    
        @ExcelProperty(value = "*英文名称")
        @ApiModelProperty("英文名称")
        private String enName;
    
        @ExcelProperty(value = "业务含义说明")
        @ApiModelProperty("业务含义说明")
        private String businessMeaning;
    
        @ExcelProperty(value = "*类型")
        @ApiModelProperty("类型")
        private String dataType;
    
        @ExcelProperty(value = "*长度")
        @ApiModelProperty("长度")
        private Long length;
    
        @ExcelProperty(value = "数据精度")
        @ApiModelProperty("精度")
        private Integer numericalPrecision;
    
        @ExcelProperty(value = "*其他说明1")
        @ApiModelProperty("是否唯一 1:是 0:否")
        private String one;
    
        @ExcelProperty(value = "*其他说明2")
        @ApiModelProperty("是否允许为空 1:是 0:否")
        private String two;
    
        @ExcelProperty(value = "其他说明3")
        @ApiModelProperty("数据源系统")
        private String three;
       //省略get和set
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    监听器

    public class MdExcelListener<T> extends AnalysisEventListener<T> {
    
        private static final Logger log = LoggerFactory.getLogger(MdExcelListener.class);
        //表头所在行数
        private int headRowNumber;
        //开始读取行数,实际再+1
        private int startRowNumber;
    
        // Excel对象
        private Class<T> clazzT;
    
        public MdExcelListener() {
        }
    
        public MdExcelListener(int headRowNumber, int startRowNumber, Class<T> clazzT) {
            this.headRowNumber = headRowNumber;
            this.startRowNumber = startRowNumber;
            this.clazzT = clazzT;
        }
    
        /**
         * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
         */
        private static final int BATCH_COUNT = 100;
    
        /**
         * 缓存的数据
         */
        private List<T> cachedDataList = ListUtils.newArrayList();
    
        @Override
        public void invoke(T data, AnalysisContext context) {
    
    
            if (context.readRowHolder().getRowIndex().intValue() > startRowNumber) {
                //log.info("解析到一条数据:{}", JSON.toJSONString(data));
                cachedDataList.add(data);
            }
        }
    
        /**
         * @param headMap 传入Excel的头部(第headRowNumber行数据)数据的index,name
         * @param context
         * @description: 校验Excel头部格式,必须完全匹配
         * @date 2019/12/24 19:27
         */
        private static int i=0;
        @Override
        public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
    
            i++;
            if (i == headRowNumber) {
                super.invokeHeadMap(headMap, context);
                validExcelHeader(headMap, clazzT);
            }
    
        }
    
        @Override
        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
    
        }
    
        /**
         * @param clazzT
         * @return java.util.Map
         * @description: 获取注解里ExcelProperty的value,用作校验excel
         * @date 2021/12/09 19:21
         */
        public static <T> void validExcelHeader(Map<Integer, String> headMap, Class<T> clazzT) {
            System.out.println("表头检验");
            // 判断传入对象
            if (Objects.isNull(clazzT)) {
                return;
            }
            // 获取表头值
            Collection<String> heads = headMap.values();
            // 获取类注解的表头值
            Set<String> nameMap = getNameSet(clazzT);
    
            // 循环验证表头是否正确
            for (String head : heads) {
                if (!nameMap.contains(head)) {
                    throw new BizException("解析excel表头与模板不符,解析失败");
                }
            }
        }
    
        static <T> Set<String> getNameSet(Class<T> clazzT) {
            Set<String> result = new HashSet<>();
            Field[] fields = clazzT.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                if (excelProperty != null) {
                    String[] values = excelProperty.value();
                    StringBuilder value = new StringBuilder();
                    for (String v : values) {
                        value.append(v);
                    }
                    result.add(value.toString());
                }
            }
            return result;
        }
    
        public List<T> getCachedDataList() {
            return cachedDataList;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110

    调用

      public void importStandard(MultipartFile file, HttpServletResponse response) throws IOException {
            ExcelReader excelReader = null;
            excelReader = EasyExcel.read(file.getInputStream()).build();
            //3代表第三行是表头数据,9代表开始读取数据行数,其实是从第10行开始读取的
            MdExcelListener listener = new MdExcelListener<>(3,9,ExcelVO.class);
            ReadSheet readSheet = EasyExcel.readSheet(0).head(MdExcelVO.class).headRowNumber(3).registerReadListener(listener).build();
    
            excelReader.read(readSheet);
    
            //基本信息
            List<ExcelVO> excelResult = listener.getCachedDataList();
            //剩余的就是校验数据了
          
         }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    C语言双向链表
    String类常用方法
    环境数据监测在环保物联网有什么价值?
    一文掌握Python多线程与多进程
    知识点滴 - 关于汉语学习的网络资源
    Python连接MS SQLServer测试
    全网最牛自动化测试框架系列之pytest(7)-yield与终结函数
    Virtualbox中对SD卡进行格式化和分区
    Linux 启动管理
    stable-diffusion-webui安装与使用过程中的遇到的error合集
  • 原文地址:https://blog.csdn.net/qq_45502554/article/details/126769388