EasyExcel拿表头(二级表头)爬坑,invokeHeadMap方法

OK,不废话,直接开干!说实话是有些坑,或者是我不会用吧

模板如下:

复制代码
invokeHeadMap 这个方法其实针对第一行就是表头的完全没问题。

针对第二行的,我DEBUG拿到的是这样

很明显,他拿到了第一行;既然他只能拿到第一行的数据,那么我们就换一个思路,只校验能拿到的表头,就不做那么好。思路就是拿到value不为null的key,作为一个新的map,然后再去比对代码如下:
复制代码
    /**
     * 验证具有表头为第二行的 Excel 模板是否正确。
     *
     * @param clazz 要验证的 Excel 类型。
     * @param headMap 包含 Excel 表头信息的映射。
     *
     */
    private void validateTwoRowHeaderMap(Class<?> clazz, Map<Integer, String> headMap) {
        validateExcelTemplate(clazz, headMap);
    }

    /**
     * 验证 Excel 表头信息是否与预定义的属性映射匹配。
     *
     * @param clazz 要验证的 Excel 类型。
     * @param headMap 包含 Excel 表头信息的映射。
     * @return 如果所有表头都匹配,返回 true;否则返回 false。
     */
    private void validateExcelTemplate(Class<?> clazz, Map<Integer, String> headMap) {
        Map<Integer, String> collect = headMap.entrySet().stream()
                .filter(entry -> entry.getValue() != null)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        Map<Integer, String> excelPropertyMap = getExcelPropertyMap(clazz, 0);

        for (Integer i : collect.keySet()) {
            if (!collect.get(i).equals(excelPropertyMap.get(i))) {
                throw new ExcelAnalysisException("模板错误,请检查导入模板");
            }
        }
    }

    /**
     * 根据类类型和位置参数获取 Excel 属性映射。
     *
     * @param clazz 要获取属性映射的 Excel 类型。
     * @param position 位置参数,用于确定具体的属性值。
     * @return 包含 Excel 属性映射的 Map。
     */
    private Map<Integer, String> getExcelPropertyMap(Class<?> clazz,Integer position) {
        Map<Integer, String> excelPropertyMap = new HashMap<>();
        Field[] fields = clazz.getDeclaredFields(); // 获取所有字段,包括私有字段

        for (Field field : fields) {
            if (!Modifier.isStatic(field.getModifiers())) { // 忽略静态字段
                ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
                if (excelProperty != null) {
                    int index = excelProperty.index();
                    String value = excelProperty.value()[position];
                    excelPropertyMap.put(index, value);
                }
            }
        }
        return excelPropertyMap;
    }

其实我这里是把校验表头为第一行和第二行的分开了,如下图:

然后无语的来了,针对表头为第二行的,走我自己处理以后的方法,框架还会去调用invokeHeadMap方法,并且这次拿到了全部信息,如下图:

然后又走我那个针对表头为第二行的处理方法,成功报错! 就很无语。

搞半天我那个还白写了。

然后我又发现,不是每次都会去调用两次,如果第一次调用的时候,抛了异常,那么就不会调用第二次。

然后我现在也还在看怎么处理一下,反正这个方法,针对复杂表头,需要自己加逻辑处理,直接用是用不了的,我也是记录一下和分享一下思路吧。不过知道了这个流程,处理也不是很麻烦。对了 ,我这个项目时老项目,easyExcel版本是2.几的,我不知道是不是版本的问题,设置了表头行然后神奇的来了,针对表头为第二行的,走我自己处理以后的方法,框架还会去调用数在走这个invokeHeadMap方法的时候没用。貌似3版本可以直接拿到。
欢迎评论区交流!
========================后续来了

简单处理一下吧,能有个作用就行,为每个线程单独设置一个计数器,主要是不想在改了,还在催,能跑就行,代码不要写的太完美了,你弄久了,还嫌你效率低呢,哈哈

参考思路就行了,贴了代码也用不了

相关推荐
为美好的生活献上中指3 分钟前
*Java 沉淀重走长征路*之——《Java Web 应用开发完全指南:从零到企业实战(两万字深度解析)》
java·开发语言·前端·html·javaweb·js
Predestination王瀞潞3 分钟前
Maven项目的架构(Spring Boot 实战版)
spring boot·架构·maven
li星野4 分钟前
QT面试题
java·数据库·qt
不光头强5 分钟前
抽象类和接口的区别
java·开发语言·python
xiaoye37085 分钟前
Spring 的自动装配 vs 手动注入
java·spring
好学且牛逼的马5 分钟前
Spring Boot 核心注解完全手册
java·spring boot·后端
彭于晏Yan8 分钟前
Spring Boot监听Redis Key过期事件
java·spring boot·redis
weixin_418270538 分钟前
window上codex 安装
java
低调小一9 分钟前
OpenClaw 模型配置与火山 Coding Plan 支持清单(实践笔记)
java·前端·笔记·openclaw
xuxie9910 分钟前
Next 13 sqlite3 查找、网页
java·数据库·oracle