easyexcel 结合javax.validation实现excel导入校验

在使用easyexcel时发现是没有对单元格值校验的方式,我个人只发现了一个转换异常类ExcelDataConvertException,当单元格中的值转换不成实体类中改值所对应的属性类型时,会抛出改异常,onException中可以处理。但如果需要把一行中的所有错误的值都找到的话,就不能触发onException,官方文档原话如下:

在转换异常 获取其他异常下会调用本接口。抛出异常则停止读取。如果这里不抛出异常则 继续读取下一行

即如果触发了onException且不抛出异常,直接开始读取下一行数据

@Override
public void onException(Exception exception, AnalysisContext context){
    if(exception instanceof ExcelDataConvertException){
        ExcelDataConvertException e = (ExcelDataConvertException)exception;
        
    }
}

因为我们是要校验整个excel中所有错误数据,显然不能触发onException,所以我的做法是通过使用String类型接收所有单元格值,然后通过javax.validation注解的方式对值进行校验。在invoke中获取到data数据,然后对data进行校验,propertyNameMap是中的key是field的name,通过javax.validation中获取到的name从propertyNameMap中得到该属性在excel中的行号,列号等信息,用于最后的错误提示信息的封装

@ExcelProperty("地区")
@NotBlank(message = "区不能为空")
private String area;
public void invoke(E data, AnalysisContext analysisContext) {
    Map propertyNameMap = getPropertyNameMap(true,analysisContext);
    if (validate(data,propertyNameMap)) {
        dataList.add(data);
    }
}
 boolean validate(E e, Map propertyNameMap) {
    boolean validateResult = true;
    Set> validateSet = Validation.buildDefaultValidatorFactory().getValidator().validate(e, Default.class);
    if (validateSet != null && !validateSet.isEmpty()) {
        validateResult = false;
        ExcelErrorDTO errorDTO;
        for (ConstraintViolation constraint : validateSet) {
            Path propertyPath = constraint.getPropertyPath();
            String propertyName = propertyPath.toString();
            ExcelCellBo bo = propertyNameMap.get(propertyName);
            errorDTO = new ExcelErrorDTO();
            errorDTO.setHeadName(bo.getHeadName());
            Object invalidValue = constraint.getInvalidValue();
            if (invalidValue != null) {
                errorDTO.setValue(invalidValue.toString());
            }else {
                errorDTO.setValue(null);
            }
            errorDTO.setColumnIndex(bo.getColumnIndex()+1);
            errorDTO.setRowIndex(bo.getRowIndex()+1);                  errorDTO.setErrMsg("第"+errorDTO.getRowIndex()+"第"+errorDTO.getColumnIndex()+"列,"+constraint.getMessage());
            errorList.add(errorDTO);
        }
    }
    return validateResult;
}

 

 Map getPropertyNameMap(boolean isSingleHeader, AnalysisContext analysisContext){
    Map propertyNameMap = new HashMap<>(16);
    ReadRowHolder readRowHolder = analysisContext.readRowHolder();
    Integer rowIndex = readRowHolder.getRowIndex();
    ReadHolder readHolder = analysisContext.currentReadHolder();
    ExcelReadHeadProperty excelReadHeadProperty = readHolder.excelReadHeadProperty();
    Collection values;
    if (isSingleHeader){
        Map contentPropertyMap = excelReadHeadProperty.getContentPropertyMap();
        values = contentPropertyMap.values();
    }else {
        //也适用于单行表头
        Map fieldNameContentPropertyMap = excelReadHeadProperty.getFieldNameContentPropertyMap();
        values = fieldNameContentPropertyMap.values();
    }
    ExcelCellBo bo;
    for (ExcelContentProperty contentProperty : values) {
        bo = new ExcelCellBo();
        bo.setRowIndex(rowIndex);
        bo.setColumnIndex(contentProperty.getHead().getColumnIndex());
        bo.setFieldName(contentProperty.getHead().getFieldName());
        //多行表头
        bo.setHeadName(String.join(",",contentProperty.getHead().getHeadNameList()));
        bo.setField(contentProperty.getField());
        propertyNameMap.put(contentProperty.getHead().getFieldName(),bo);
    }
    return propertyNameMap;
}
@Data
public class ExcelCellBo {
    private Field field;
    private String fieldName;
    private String headName;
    private Integer columnIndex;
    private Integer rowIndex;
}

你可能感兴趣的:(java,easyexcel)