EasyExcel导入数据校验

一、ExcelVO

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class BookExcelVO implements Serializable {

    @Size(max = 20, message = "书名超出20长度")
    @ExcelProperty(value = "书名")
    private String name;

    @Size(max = 10, message = "作者超出20长度")
    @ExcelProperty(value = "作者")
    private String author;

    @Pattern(regexp = "^[1-9]\\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", message = "出版日期格式(yyyy-MM-dd)有误")
    @ExcelProperty(value = "出版日期")
    private String publishDate;
}

二、编写Controller模拟导出

@GetMapping(value = "/exportBooks", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public void test(HttpServletResponse response) {
    List<BookExcelVO> excelVOS = new ArrayList<>();
    excelVOS.add(BookExcelVO.builder().name("西游记").author("吴承恩").publishDate("1592-01-02").build());
    excelVOS.add(BookExcelVO.builder().name("红楼梦").author("曹雪芹").publishDate("1953-03-09").build());
    try {
        ExcelUtil.exportExcel(response, "书籍", "Sheet1", BookExcelVO.class, excelVOS);
    } catch (IOException e) {
        throw new EasyExcelException(EasyExcelExtExceptionTypes.EXPORT_FAILED);
    }
}

导出测试: http://127.0.0.1:8888/book/exportBooks

三、导入

3.1 正常导入

@PostMapping(value = "importBooks")
public R importBooks(@RequestParam("file") MultipartFile file) {
    if (Objects.isNull(file) || file.isEmpty()) {
        throw new EasyExcelException(EasyExcelExtExceptionTypes.IMPORT_FILE_IS_EMPTY);
    }
    List<BookExcelVO> bookExcelVOS;
    try {
        bookExcelVOS = ExcelUtil.readExcel(file, BookExcelVO.class);
    } catch (IOException e) {
        throw new EasyExcelException(EasyExcelExtExceptionTypes.IMPORT_PARSE_DATA_FAILED);
    }

    for (BookExcelVO bookExcelVO : bookExcelVOS) {
        log.info(JSON.toJSONString(bookExcelVO));
        // 数据拷贝
    }
    // 批量保存
    return R.ok();
}

3.2 增加校验

// 字段校验
ValidationUtil.doValidate(bookExcelVOS);

校验的实现

public class ValidationUtil {

    public static Validator getValidator() {
        return validator;
    }

    static Validator validator;

    static {
        ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
        validator = validatorFactory.getValidator();
    }

    public static <T> void doValidate(List<T> var1, Class<?>... var2) {
        List<ImportExpVO> expVOList = new ArrayList<>();
        int rowNum = 1;
        for (T var0 : var1) {
            rowNum++; // 跳过标题行, 此为excel的行号
            List<String> errMsg = new ArrayList<>();
            Set<ConstraintViolation<T>> validateRstSet = ValidationUtil.getValidator().validate(var0, var2);
            for (ConstraintViolation<T> constraintViolation : validateRstSet) {
                errMsg.add(constraintViolation.getMessage());
            }
            if (errMsg.size() > 0) {
                expVOList.add(ImportExpVO.builder().rowNum(rowNum).errMsg(errMsg).build());
            }
        }
        if (expVOList.size() > 0) {
            // 组装异常数据
            throw new EasyExcelException(EasyExcelExtExceptionTypes.DATA_VALID_FAILED, expVOList);
        }
    }
}

进行正常测试

### 正常数据上传
POST http://127.0.0.1:8888/book/importBooks
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="书籍.xlsx"

< ./书籍.xlsx
--WebAppBoundary--
{
  "code": 200,
  "msg": "success"
}

进行异常测试

### 异常数据上传-验证校验
POST http://127.0.0.1:8888/book/importBooks
Content-Type: multipart/form-data; boundary=WebAppBoundary

--WebAppBoundary
Content-Disposition: form-data; name="file"; filename="书籍exp.xlsx"

< ./书籍exp.xlsx
--WebAppBoundary--
{
  "code": "DATA_VALID_FAILED",
  "msg": "数据校验失败",
  "data": [
    {
      "rowNum": 2,
      "errMsg": [
        "作者超出20长度"
      ]
    },
    {
      "rowNum": 3,
      "errMsg": [
        "出版日期格式(yyyy-MM-dd)有误",
        "作者超出20长度"
      ]
    }
  ]
}

code address: easyexcel-validate-example

你可能感兴趣的:(excel,spring,boot)