赞
踩
一般在工作中,常常遇到各种各样的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();
//剩余的就是校验数据了
}
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。