package com.ruoyi.common.utils.poi; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.excel.context.AnalysisContext; import com.alibaba.excel.event.AnalysisEventListener; import com.alibaba.excel.exception.ExcelAnalysisException; import com.alibaba.excel.exception.ExcelDataConvertException; import com.alibaba.fastjson.JSON; import com.ruoyi.common.utils.ValidatorUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.validation.*; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** * 公共excel监听类 * @param */ public class ExcelListener extends AnalysisEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(ExcelListener.class); /** 数据对象list */ private final List list = new ArrayList<>(); /** 错误信息列表 */ private final List errorList = new ArrayList<>(); /** 遇到异常是否跳出导入,默认为是 */ private Boolean skipException = Boolean.TRUE; /** 是否Validator检验,默认为是 */ private Boolean isValidate = Boolean.TRUE; /** * 导入回执 */ private final ExcelResult excelResult = new ExcelResult<>(); public ExcelListener() { } public ExcelListener(boolean isValidate, boolean skipException) { this.isValidate = isValidate; this.skipException = skipException; } /** * 处理异常 * * @param exception ExcelDataConvertException * @param context excel上下文 */ @Override public void onException(Exception exception, AnalysisContext context) throws Exception { // 如果是某一个单元格的转换异常 能获取到具体行号 // 如果要获取头的信息 配合doAfterAllAnalysedHeadMap使用 String errMsg = null; if (exception instanceof ExcelDataConvertException) { ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException)exception; errMsg = StrUtil.format("第{}行-第{}列解析异常
", excelDataConvertException.getRowIndex() + 1, excelDataConvertException.getColumnIndex() + 1); LOGGER.error(errMsg); } if (exception instanceof ConstraintViolationException) { ConstraintViolationException constraintViolationException = (ConstraintViolationException)exception; Set> constraintViolations = constraintViolationException.getConstraintViolations(); String constraintViolationsMsg= CollUtil.join(constraintViolations .stream() .map(ConstraintViolation::getMessage) .collect(Collectors.toList()), ","); errMsg = StrUtil.format("第{}行数据校验异常:{}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg); LOGGER.error(errMsg); } errorList.add(errMsg); if (!skipException){ throw new ExcelAnalysisException(errMsg); } } @Override public void invokeHeadMap(Map headMap, AnalysisContext context) { LOGGER.debug("解析到一条头数据:{}", JSON.toJSONString(headMap)); } @Override public void invoke(T data, AnalysisContext context) { if (isValidate) { ValidatorUtils.validate(data); } list.add(data); } @Override public void doAfterAllAnalysed(AnalysisContext context) { excelResult.setList(list); excelResult.setErrorList(errorList); LOGGER.debug("所有数据解析完成!"); } /** * 获取导入数据 * @return 导入数据 */ public List getList() { return list; } public ExcelResult getExcelResult() { return excelResult; } }