一般在工作中,常常遇到各种各样的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
 }

监听器

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<java.lang.Integer, java.lang.String>
     * @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;
    }
}

调用

  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();
        //剩余的就是校验数据了
      
     }
GitHub 加速计划 / ea / easyexcel
31.64 K
7.47 K
下载
快速、简洁、解决大文件内存溢出的java处理Excel工具
最近提交(Master分支:3 个月前 )
c42183df Bugfix 2 个月前
efa7dff6 * 重新加回 `commons-io` 2 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐