EasyExcel导入失败返回失败的文件批注+底色标识出错误数据

监听器



/**
 * ExcelImportReadListener
 * 监听器
 *
 * @author [email protected]
 * @date 2022年09月01日 上午10:07
 */

@Slf4j
public class ExcelImportReadListener<T> extends AnalysisEventListener<T> {

    /**
     * 记录错误
     */
    public Map<Integer, Map<Integer, FailRecordEntity>> failListMap = new HashMap<>(16);

    /**
     * excel中读取的数据
     */
    public List<T> excelDates = new ArrayList<T>();


    Class clazz;


    /**
     * 批注、超链接、合并单元格信息等
     *
     * @param extra
     * @param context
     * @author [email protected]
     * @date 2022/9/6 下午2:26
     */
    @Override
    public void extra(CellExtra extra, AnalysisContext context) {
        super.extra(extra, context);
    }

    public ExcelImportReadListener(Class clazz) {
        super();
        this.clazz = clazz;
    }

    /**
     * 读取表头内容
     */
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        log.info("解析到一条头数据:" + headMap.toString());
        // count 记录模板表头有几个,用以判断用户导入的表格是否和模板完全一致
        // 如果用户导入表格较模板的表头多,但其余符合模板,这样不影响则不需要
        int count = 0;
        // 获取数据实体的字段列表
        Field[] fields = clazz.getDeclaredFields();
        // 遍历字段进行判断
        for (Field field : fields) {
            // 获取当前字段上的ExcelProperty注解信息
            ExcelProperty fieldAnnotation = field.getAnnotation(ExcelProperty.class);
            // 判断当前字段上是否存在ExcelProperty注解
            if (fieldAnnotation != null) {
                ++count;
                // 存在ExcelProperty注解则根据注解的index索引到表头中获取对应的表头名
                String headName = headMap.get(fieldAnnotation.index());
                // 判断表头是否为空或是否和当前字段设置的表头名不相同
                if (StringUtils.isEmpty(headName) || !headName.equals(fieldAnnotation.value()[0])) {
                    // 如果为空或不相同,则抛出异常不再往下执行
                    throw new ExcelAnalysisException("MRM.Excel.Import.Template.Exception");
                }
            }
        }

        // 判断用户导入表格的标题头是否完全符合模板(字段确定后打开)
      /*  if (count != headMap.size()) {
             throw new ExcelAnalysisException("MRM.Excel.Import.Template.Exception");
        }*/
    }

    /**
     * 通过class获取类字段信息
     */
    public Map<Integer, String> getIndexNameMap(Class clazz) throws NoSuchFieldException {
        Map<Integer, String> result = new HashMap<>(16);
        Field field;
        //获取类中所有的属性
        Field[] fields = clazz.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            field = clazz.getDeclaredField(fields[i].getName());
            field.setAccessible(true);
            //获取根据注解的方式获取ExcelProperty修饰的字
### EasyExcel 导入数据返回错误信息的解决方案 在使用EasyExcel进行数据导入的过程中,遇到不符合预期的数据格式或其他异常情况时,能够及时反馈具体的错误信息给用户是非常重要的。为了实现这一目标,在设计上通常会采用监听器模式来捕获读取过程中的各种事件,并通过自定义异常处理机制向外界传递详细的报错详情。 当发生像`Convert data com.alibaba.excel.metadata.data.ReadCellData@a8b42f88 to class java.util.Date error`这样的日期转换失败的情况时[^2],可以通过重写监听器中的相应方法来进行特定逻辑控制: #### 自定义监听器捕捉异常并记录位置 ```java public class CustomManageListener extends AnalysisEventListener<CustomerInfo> { private List<String> failMessages = new ArrayList<>(); @Override public void invoke(CustomerInfo customerInfo, AnalysisContext context) { try { // 对象校验逻辑... validateCustomerInfo(customerInfo); } catch (Exception e) { int rowIndex = context.readRowHolder().getRowIndex(); String errorMessage = "第" + rowIndex + "行存在非法数据:" + e.getMessage(); failMessages.add(errorMessage); } } @Override public void doAfterAllAnalysed(AnalysisContext context) { if (!failMessages.isEmpty()) { throw new ExcelImportException(String.join("\n", failMessages)); } } private void validateCustomerInfo(CustomerInfo info){ // 验证业务规则的具体实现... } } ``` 上述代码片段展示了如何创建一个继承自`AnalysisEventListener<T>`的监听者类`CustomManageListener`,用于监控每一行数据的解析过程。每当发现有不合法的数据项时,则将其所在的位置连同具体原因一起保存下来;待整个文件分析完毕之后再统一抛包含所有错误描述的信息。 对于更复杂的场景下(比如涉及多个表之间的关联关系),还可以进一步扩展此监听者的功能,使其不仅限于简单的字段验证,而是参与到更为深入的数据清洗工作中去[^5]。 此外,考虑到用户体验方面的需求,除了提供详尽的文字说明外,也可以考虑将这些提示以更加直观的形式展现来——例如生成带有标注的新版本Excel文档供下载查看等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

出世和尚欢乐多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值