- 导入时,数据全部读取完,进行参数校验
- 如果参数校验失败后,将Excel导入的数据和校验错误信息,存到Redis中,最后将数据导出
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
控制层
一个导入,一个下载模板,一个导出批注后的模板
@Autowired RedisUtil redisUtil; @Autowired GsonBuilder gsonBuilder; private static final String PREFIX = "easyExcel_"; public static final String SEND_LIST = "sendList_"; public static final String SEND_LIST_ERROR = "_error"; public static final Long EXPIRE_TIME = 60 * 10L; @GetMapping(value = "importExcel") @ApiOperation("导入") public Result importExcel( @RequestParam(value = "file", required = true) MultipartFile file ) throws IOException { SendListListener sendListListener = new SendListListener(); EasyExcel.read(file.getInputStream(), SendListExcel.class, sendListListener).sheet().doRead(); List<SendListExcel> listExcels = sendListListener.getListExcels(); Gson gson = gsonBuilder.create(); if (sendListListener.getExcelErrorMap().size() > 0) { String uuid = IdUtils.id32(); String key = PREFIX + SEND_LIST + uuid; redisUtil.set(key, gson.toJson(listExcels), EXPIRE_TIME); redisUtil.set(key + SEND_LIST_ERROR, gson.toJson(sendListListener.getExcelErrorMap()), EXPIRE_TIME); return Result.error(uuid); } listExcels.forEach(System.out::println); return Result.success(); } @GetMapping("downloadExcelTemplate") @ApiOperation("下载Excel模板") public void export(HttpServletResponse response) throws Exception { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); String fileName = "发送名单管理模板.xlsx"; response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); EasyExcel.write(response.getOutputStream(), SendListExcel.class).sheet("sheet1").doWrite(new ArrayList<SendListExcel>()); } @GetMapping("downloadErrorExcel") @ApiImplicitParams(value = { @ApiImplicitParam(name = "uuid", dataType = "String", value = "校验参数失败后,返回的uuid") }) @ApiOperation("下载批注后到错误excel") public void downloadErrorExcel( HttpServletResponse response, @RequestParam(value = "uuid", required = true) String uuid ) throws IOException { SimpleDateFormat fDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); String fileName = fDate.format(new Date()) + ".xlsx"; response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); CommentWriteHandler commentWriteHandler = new CommentWriteHandler(); String key = PREFIX + SEND_LIST + uuid; String listExcelJson = (String) redisUtil.get(key); String listExcelErrorlJson = (String) redisUtil.get(key + SEND_LIST_ERROR); Gson gson = gsonBuilder.create(); if (listExcelJson != null && listExcelErrorlJson != null) { Type listExcelJsonType = new TypeToken<List<SendListExcel>>() { }.getType(); List<SendListExcel> sendListExcels = gson.fromJson(listExcelJson, listExcelJsonType); Type listExcelErrorlJsonType = new TypeToken<Map<Integer, List<ExcelError>>>() { }.getType(); Map<Integer, List<ExcelError>> errorMap = gson.fromJson(listExcelErrorlJson, listExcelErrorlJsonType); commentWriteHandler.setExcelErrorMap(errorMap); EasyExcel.write(response.getOutputStream(), SendListExcel.class) .inMemory(Boolean.TRUE) .sheet("sheet1") //注册批注拦截器 .registerWriteHandler(commentWriteHandler) .doWrite(sendListExcels); } }
导出实体类
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.write.style.ColumnWidth; import com.alibaba.excel.annotation.write.style.ContentRowHeight; import com.alibaba.excel.annotation.write.style.HeadRowHeight; import lombok.Data; import java.io.Serializable; /** * @Description: * @Author:chenyanbin * @Date:2021/2/3 10:20 上午 * @Versiion:1.0 */ @Data @ExcelIgnoreUnannotated() @ContentRowHeight(10) @HeadRowHeight(20) public class SendListExcel implements Serializable { @ExcelProperty(value = "账号",index = 0) @ColumnWidth(20) private String account; @ExcelProperty(value = "模板编号",index = 1) @ColumnWidth(30) private String templateCode; @ExcelProperty(value = "类型",index = 2) @ColumnWidth(15) private String accountType; }
EasyExcel监听器
import com.alibaba.excel.context.AnalysisContext; import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; import java.util.List; /** * @Description: * @Author:chenyanbin * @Date:2021/2/3 10:40 上午 * @Versiion:1.0 */ public class SendListListener extends AnalysisEventListenerAdapter<SendListExcel> { private List<SendListExcel> listExcels = new ArrayList<>(); public SendListListener() { super(); listExcels.clear(); excelErrorMap.clear(); } /** * 每一条数据解析都会调用 */ @Override public void invoke(SendListExcel sendListExcel, AnalysisContext analysisContext) { listExcels.add(sendListExcel); } /** * 所有数据解析完成都会调用 */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { SendListExcel sle = null; boolean isMatch = true; for (int i = 0; i < listExcels.size(); i++) { sle = listExcels.get(i); isMatch = true; Integer accountCellIndex = EasyExcelUtil.getCellIndex(sle, "account"); if (accountCellIndex != null) { if (StringUtils.isAllBlank(sle.getAccount())) { setExcelErrorMaps(i, accountCellIndex, "账号不能为空!"); } } Integer templateCodeCellIndex = EasyExcelUtil.getCellIndex(sle, "templateCode"); if (templateCodeCellIndex != null) { if (StringUtils.isAllBlank(sle.getTemplateCode())) { setExcelErrorMaps(i, templateCodeCellIndex, "模板编号不能为空!"); } } Integer accountTypeCellIndex = EasyExcelUtil.getCellIndex(sle, "accountType"); if (accountTypeCellIndex != null) { if (StringUtils.isAllBlank(sle.getAccountType())) { setExcelErrorMaps(i, accountTypeCellIndex, "类型不能为空!"); } else { if ("sms".equals(sle.getAccountType()) || "email".equals(sle.getAccountType()) || "wechat".equals(sle.getAccountType())) { isMatch = false; } if (isMatch) { setExcelErrorMaps(i, accountTypeCellIndex, "类型只允许:sms、email、wechat"); } } } } } public List<SendListExcel> getListExcels() { return listExcels; } }
其他
import com.alibaba.excel.write.handler.AbstractRowWriteHandler; import org.apache.poi.ss.usermodel.*; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Description:AbstractRowWriteHandler适配器 * @Author:chenyanbin * @Date:2021/2/3 10:04 上午 * @Versiion:1.0 */ public abstract class AbstractRowWriteHandlerAdapter extends AbstractRowWriteHandler { protected Map<Integer, List<ExcelError>> excelErrorMap = new HashMap<>(); public void setExcelErrorMap(Map<Integer, List<ExcelError>> excelErrorMap) { this.excelErrorMap = excelErrorMap; } /** * 设置单元格批注 * @param sheet sheet * @param rowIndex 行索引 * @param colIndex 列索引 * @param value 批注 */ protected void setCellCommon(Sheet sheet, int rowIndex, int colIndex, String value) { Workbook workbook = sheet.getWorkbook(); CellStyle cellStyle = workbook.createCellStyle(); cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); cellStyle.setFillForegroundColor(IndexedColors.RED.getIndex()); cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); Row row = sheet.getRow(rowIndex); if (row == null) { return; } Cell cell = row.getCell(colIndex); if (cell == null) { cell = row.createCell(colIndex); } if (value == null) { cell.removeCellComment(); return; } Drawing<?> drawing = sheet.createDrawingPatriarch(); CreationHelper factory = sheet.getWorkbook().getCreationHelper(); ClientAnchor anchor = factory.createClientAnchor(); Row row1 = sheet.getRow(anchor.getRow1()); if (row1 != null) { Cell cell1 = row1.getCell(anchor.getCol1()); if (cell1 != null) { cell1.removeCellComment(); } } Comment comment = drawing.createCellComment(anchor); RichTextString str = factory.createRichTextString(value); comment.setString(str); comment.setAuthor("admin"); cell.setCellComment(comment); cell.setCellStyle(cellStyle); } }