@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;
}
@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
@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();
}
// 字段校验
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