EasyPOI批量导入后返回所有数据&尾列反馈报错信息
前言
因业务要求需要把导入的Excel数据加上反馈信息一起返回给导入者,反馈信息放在Excel最后一列完成显示绿色"成功" 失败则显示红色"失败原因".
导入用EasyPOI网络上有很多成熟且简单的导入加失败信息反馈给用户的写法与我的业务相似度50%,那我只需要稍加改动就可以完成此任务.
业务逻辑:
- 加Maven依赖
- entity类加导入注解
- 导入编码
- 包装导出数据导出
一.依赖
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.4.0</version>
<exclusions>
<exclusion>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-wps</artifactId>
</exclusion>
</exclusions>
</dependency>
二.代码
-
entity类
继承IExcelModel,IExcelDataModel 重写errorMsg,rowNum的get|set方法.errorMsg是校验完必填和最大最小Size等…不符合的数据给用户的提示信息.rowNum是导入时每行数据的顺序.都有用记下来后面要考.
@Data public class StudentExcelVo extends PomId implements IExcelModel, IExcelDataModel { private static final long serialVersionUID = 1L; @Excel(name = "名字", orderNum = "1", width = 40) @NotNull(message = "不能为空") @Size(message = "不能超过10个字符",max = 10) private String name; @Excel(name = "性别", orderNum = "2", width = 40) @NotNull(message = "不能为空") private String sex; @Excel(name = "年龄", orderNum = "3", width = 40) @NotNull(message = "不能为空") private Integer age; private String createdByUser; private LocalDateTime createdTime; private String lastModifiedByUser; private LocalDateTime lastModifiedTime; @Excel(name="结果", orderNum = "4", width = 40) private String errorMsg; private Integer rowNum; @Override public String getErrorMsg() { return errorMsg; } @Override public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } @Override public Integer getRowNum() { return rowNum; } @Override public void setRowNum(Integer rowNum) { this.rowNum = rowNum; } }
-
service方法
此处"//"在开头的注解都是我加的有些话痨 其他的是复制来的
@Override public Workbook importExcelStudents(Principal user, MultipartFile file) throws Exception { ImportParams params = new ImportParams(); //表格标题行数,默认0 表示没有标题 params.setTitleRows(0); //表头行数,默认1 表示有一行表头 params.setHeadRows(1); //开始读取的sheet位置,默认为0 params.setStartSheetIndex(0); //... 更多参数查看源码api //需要校验 params.setNeedVerify(true); // 调easyPOI获取所有数据 ExcelImportResult<StudentExcelVo> importResult = ExcelImportUtil.importExcelMore( file.getInputStream(), StudentExcelVo.class, params); // list是通过entity必填校验的数据可以直接入库 List<StudentExcelVo> list = importResult.getList(); // failList是未通过校验的数据不可入库 List<StudentExcelVo> failList = importResult.getFailList(); Student pomMediaAccount = new Student(); list.stream().forEach(poVo -> { poVo.setCreatedByUser(user.getName()); poVo.setLastModifiedByUser(user.getName()); }); // 因为做导入时考虑有单独的导出接口和导入所用字段不一样 导入时用的原始类是封装的Vo入库需要转成po // 用的是mybatis plus 不转会报错 不知道有没有更好的方法 List<? extends Student> pomMediaAccounts = JSON.parseArray(JSON.toJSONString(list), pomMediaAccount.getClass()); // 完整数据存表 pomMediaAccounts.stream().forEach(student -> { this.saveOrUpdate(student); }); // 把校验失败的数据加进来 list.addAll(failList); list.stream().forEach(poVo -> { // 校验失败的数据已经有错误信息了 把成功的信息加进去 if (null == poVo.getErrorMsg()) { poVo.setErrorMsg("成功"); } }); // 重新根据导入时的顺序排列 list.sort(Comparator.comparing(StudentExcelVo::getRowNum)); Workbook excelfile = ExcelExportUtil.exportExcel(new ExportParams("student录入信息反馈", "信息"), StudentExcelVo.class, list); //-------------------------------设置单元格样式开始------------------------------------- //获取sheetAt对象,这里一个sheetAt所以角标是0 Sheet sheetAt = excelfile.getSheetAt(0); // 表格行数 int lastRowNum = sheetAt.getLastRowNum(); //开始遍历单元格并进行判断是否渲染 for (int i = 2; i <= lastRowNum; i++) { //获取每行对象 Row row = sheetAt.getRow(i); //获取结果列单元格对象 Cell cell = row.getCell(3); //获取当前单元格 中的value String cellValue = String.valueOf(cell.getRichStringCellValue()); //获取单元格样式对象 CellStyle cellStyle = excelfile.createCellStyle(); //获取单元格内容对象 Font font = excelfile.createFont(); //一定要装入 样式中才会生效 cellStyle.setFont(font); //设置单元格字体颜色 失败为红色 if ("成功".equals(cellValue)) { font.setColor(IndexedColors.GREEN.getIndex()); } else { font.setColor(IndexedColors.RED.getIndex()); } cell.setCellStyle(cellStyle); } //-------------------------------设置单元格样式完成------------------------------------- return excelfile; }
-
controller方法
@ApiOperation(value = "批量导入") @PostMapping("/importExcelStudents") public void importExcelStudents( @ApiIgnore @Autowired Principal user, @RequestParam(value = "file") @RequestPart MultipartFile file, HttpServletResponse resp) { try { Workbook excelfile = service.importExcelStudents(user, file); DownloadHelper.setupHeaderForDownloadXlsx(resp, "student录入信息反馈"); excelfile.write(resp.getOutputStream()); } catch (Exception e) { log.debug("importExcel:student信息批量导入失败"); log.warn("", e); throw new PomRespServerSideException("student信息批量导入失败"); } }
三.测试
-
导入数据
-
反馈数据
四.总结
- 导出文件并不是原导入文件后加一列 列宽与原文件可能出入很大.
- 记录一下,希望能坚持记录.
- 完了.