@Excel导出实现动态控制导出列

前言

如题,有需求,导出列需要由有用动态控制,但是又不想自己造轮子,索性在别人的 @Excel 基础上改了改 核心就是通过反射和动态代理,将自定义注解 showColumn 的值,在导出的时候做一下修改 直接上代码吧

正文

1. 为注解 Excel 添加属性 showColumn,默认值为true

2. 在原 ExcelUtil 中添加方法

/**
     *
     * 动态删除不显示的字段 - 动态地将 @Excel 的属性 showColumn 的值设置为 false
     * @param list 数据集合
     * @param columns 需要导出的字段
     * @return java.util.List<T>
     * @date 2021/5/14 15:58
     * @author wei.heng
     */
    public static <T> List<T> deleteNotDisplayColumns(List<? extends T> list, List<String> columns) {
        return list.parallelStream().peek(d -> {
            Class<?> aClass = d.getClass();
            Field[] declaredFields = aClass.getDeclaredFields();

            // 常量
            final String MEMBER_VALUES = "memberValues";
            // 定义需要修改的注解属性
            final String SHOW_COLUMN = "showColumn";
            for (Field field : declaredFields) {
                field.setAccessible(true);
                if(!columns.contains(field.getName())){
                    // 该字段导出时不需要
                    Excel annotation = field.getAnnotation(Excel.class);
                    if(annotation == null) {
                        continue;
                    }
                    // 修改showColumn属性值
                    InvocationHandler h = Proxy.getInvocationHandler(annotation);
                    try {
                        Field hField = h.getClass().getDeclaredField(MEMBER_VALUES);
                        hField.setAccessible(true);
                        Map memberValues = (Map) hField.get(h);
                        memberValues.put(SHOW_COLUMN, false);
                    } catch (NoSuchFieldException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                    //System.out.println(field.getName() + ", showColumn:"  + annotation.showColumn());
                }
            }
        }).collect(Collectors.toList());
    }

3.修改原方法

添加导出字段时候,新增 showColumn 的逻辑判断

private void putToField(Field field, Excel attr) {
        if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) {
            // 是否显示该字段 - 默认显示;若程序动态修改为不显示,则导出时不含该字段 - weiheng 20210514
            if(attr.showColumn()){
                this.fields.add(new Object[]{field, attr});
            }
        }
    }

4.使用

由此就实现了导出字段的客户端动态控制,个人感觉用起来还蛮方便的,做个笔记,以后不用重复写了

经验分享 程序员 微信小程序 职场和发展