SpringBoot EasyPoi动态导入导出的两种方式实现方法详解

 更新时间:2022年09月24日 10:19:36   作者:Java升级之路  
项目里使用的是EasyPoi来处理导入导出功能的。近日因业务需求调整,一些导出功能的导出列需要根据不同的条件动态导出

前言

一开始为了图方便,使用的是土方法,即创建多个不同的实体类,每个实体类对应不同的列。这样虽说能实现,但实在不想多复制实体类,把代码堆的和shi山一样。于是查看官方文档,里面确实提供了更加优雅的实现方式。废话不多说,开整。

一、基于@Excel的 isColumnHidden 属性

我们项目使用的是注解方式导出,只需要在属性上增加@Excel注解,就可以导出该属性列。默认大家都会使用了,不会使用的出门右转去官网教程看看demo。

要动态导出列,我们需要用到 isColumnHidden 这个属性。

可以看到,isColumnHidden中提供的默认值是false,也就是默认全部导出,不隐藏。把值设为true,导出就没有该列了。所以这个问题就变成,导出要想动态显示哪些列,只需要动态设置 isColumnHidden 的值 就可以实现。

1.1 实现原理

JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

利用 JAVA反射机制。根据反射机制,我们可以拿到一个类的所有属性和方法,同理,注解也是一个类,也是可以拿到它的属性和方法,拿到之后就好办了,直接修改它的默认值,然后根据不同的条件调整,就可以达到一个类实现动态导出的目的。

1.2 实现步骤

先创建一个工具类,传入对象,获取注解值,并修改。

代码如下(示例):

/**
 * @description  动态显示Excel导出列
 * @date 2022/8/31
 */
public class EasyPoiUtil<T> {
    /**
     * 需要被反射的对象,使用泛型规范传入对象
     */
    public T t;
    public void hiddColumn(String columnName, Boolean target) throws Exception {
        if (t == null) {
            throw new ClassNotFoundException("TARGET OBJECT NOT FOUNT");
        }
        if (StringUtils.isEmpty(columnName)) {
            throw new NullPointerException("COLUMN NAME NOT NULL");
        }
        if (target == null) {
            target = true;
        }
        // 获取目标对象的属性值
        Field field = t.getClass().getDeclaredField(columnName);
        // 获取注解反射对象
        Excel excelAnnon = field.getAnnotation(Excel.class);
        // 获取代理
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(excelAnnon);
        Field excelField = invocationHandler.getClass().getDeclaredField("memberValues");
        // 因为这个字段是 private final 修饰,所以要打开权限
        excelField.setAccessible(true);
        Map memberValues = (Map) excelField.get(invocationHandler);
        memberValues.put("isColumnHidden", target);
    }
}

然后在需要导出的数据中更改对应条件能看到的列,这里以实际项目里的代码为例

public List<ExportVo> batchLiveUserExport(LiveUser liveUser) {
        List<ExportVo> voList = baseMapper.batchLiveUserExport(liveUser);
        LiveInfo liveInfo = liveInfoService.getById(liveUser.getLiveId());
        if (liveInfo != null) {
            LiveSpecial liveSpecial = liveSpecialService.getById(liveInfo.getSpecialId());
            if ("2".equals(liveSpecial.getLivePlatform())) {
                setHiddColumn(voList,true);
            } else {
                setHiddColumn(voList,false);
            }
        }
        return voList;
    }
    private void setHiddColumn(List<ExportVo> list, Boolean value) {
        if (CollectionUtil.isNotEmpty(list)) {
            for (ExportVo vo : list) {
                EasyPoiUtil<ExportVo> easyPoiUtil = new EasyPoiUtil<>();
                easyPoiUtil.t = vo;
                // 是否导出 参与状态 一列  true 导出   false 不导出
                try {
                    easyPoiUtil.hiddColumn("isJoin", value);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

1.3 实现效果

可以看到导出的表格,“参与状态”一列,是根据条件动态显示了。(其实也全部导出了,只是隐藏了列,通过Execl里的设置还是可以显示隐藏列的,对这点有要求的此方式或者不适用)

二. 基于List< ExcelExportEntity > 的导出

上面说到,利用@Execl的 isColumnHidden 属性动态设置值,只是在导出时隐藏了该列而已,实际上也还是全部导出了。

要彻底的不导出,官方也给出了解决方案:基于List< ExcelExportEntity> 的导出

ExcelExportEntity是注解经过处理翻译成的实体类,两者几乎是一对的,所以如果我们要动态自定义导出列,只要动态拼装ExcelExportEntity就可以了

例如上面的栗子,我们只导出 “姓名”,“学号”,“手机号”,"通知状态"四列, 代码如下(示例):

   /**
     * 根据条件动态生成列信息
     **/
    private List<ExcelExportEntity> dynaCol(String type) {
        List<ExcelExportEntity> colList = new ArrayList<ExcelExportEntity>();
        colList.add(new ExcelExportEntity("姓名", "realName"));
        colList.add(new ExcelExportEntity("学号", "studNo"));
        if ("2".equals(type)) {
            colList.add(new ExcelExportEntity("手机号", "phoneNumber"));
            ExcelExportEntity excelentity = new ExcelExportEntity("通知状态", "isSms");
            // 值替换
            String[] isSmsReplace = {"未发送_N", "已发送_Y","_null"};
            excelentity.setReplace(isSmsReplace);
            colList.add(excelentity);
        }
        return colList;
    }
    /**
     * 导出 伪代码
     **/
    @GetMapping(value = "batchExport")
    public void batchExport(LiveUser liveUser, HttpServletResponse response){
        // 查询出导出的结果集
        List<LiveUserExportVo> liveUsers = liveUserService.batchLiveUserExport(liveUser);
        // 根据条件动态生成列信息
        List<ExcelExportEntity> beanList = dynaCol("2");
        // 导出
        ExcelUtil.exportExcelX(liveUsers, beanList,"名单.xls",  response,new ExportParams("名单", "名单"));
    }

实现效果

满足了只导出四列的要求。

总结

好了,以上就是本文的全部内容了。全文介绍了两种方式实现EasyPoi动态导出列,可以根据项目的实际情况看看能否用的上。

到此这篇关于SpringBoot EasyPoi动态导入导出的两种方式实现方法详解的文章就介绍到这了,更多相关SpringBoot EasyPoi导入导出内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java获取代码中方法参数名信息的方法

    Java获取代码中方法参数名信息的方法

    在java中,可以通过反射获取到类、字段、方法签名等相关的信息,像方法名、返回值类型、参数类型、泛型类型参数等,但是不能够获取方法的参数名。在实际开发场景中,有时需要根据方法的参数名做一些操作,那么该如何操作了呢?下面就通过这篇文章来学习学习吧。
    2016-09-09
  • Java获取启动参数方式

    Java获取启动参数方式

    本文介绍了Java应用程序如何获取JVM启动参数,包括标准参数、非标准参数和高级参数,介绍了通过`main`方法参数、`System.getProperty`和`RuntimeMXBean`获取启动参数的方式,并提供了一个实际项目案例,展示了如何结合多种方式灵活配置应用程序
    2025-01-01
  • Java中消息队列任务的平滑关闭详解

    Java中消息队列任务的平滑关闭详解

    对于消息队列的监听,我们一般使用Java写一个独立的程序,在Linux服务器上运行。程序启动后,通过消息队列客户端接收消息,放入一个线程池进行异步处理,并发的快速处理。这篇文章主要给大家介绍了关于Java中消息队列任务的平滑关闭的相关资料,需要的朋友可以参考下。
    2017-11-11
  • 关于各种排列组合java算法实现方法

    关于各种排列组合java算法实现方法

    这篇文章介绍了几种用JAVA实现的排列组合算法,有需要的朋友可以参考一下
    2013-06-06
  • springboot 配置DRUID数据源的方法实例分析

    springboot 配置DRUID数据源的方法实例分析

    这篇文章主要介绍了springboot 配置DRUID数据源的方法,结合实例形式分析了springboot 配置阿里DRUID数据源的具体步骤与相关操作技巧,需要的朋友可以参考下
    2019-12-12
  • 手把手带你分析SpringBoot自动装配完成了Ribbon哪些核心操作

    手把手带你分析SpringBoot自动装配完成了Ribbon哪些核心操作

    这篇文章主要介绍了详解Spring Boot自动装配Ribbon哪些核心操作的哪些操作,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • 详解JAVA 弱引用

    详解JAVA 弱引用

    这篇文章主要介绍了 JAVA 弱引用的相关资料,帮助大家更好的理解和学习java引用对象,感兴趣的朋友可以了解下
    2020-08-08
  • java中switch case语句需要加入break的原因解析

    java中switch case语句需要加入break的原因解析

    这篇文章主要介绍了java中switch case语句需要加入break的原因解析的相关资料,需要的朋友可以参考下
    2017-07-07
  • Java NIO通信基础示例详解

    Java NIO通信基础示例详解

    这篇文章主要为大家介绍了Java NIO通信基础使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • 使用Java编写一个简单的Web的监控系统

    使用Java编写一个简单的Web的监控系统

    这篇文章主要介绍了使用Java编写一个简单的Web的监控系统的例子,并且将重要信息转为XML通过网页前端显示,非常之实用,需要的朋友可以参考下
    2015-11-11

最新评论