若依二开:导出功能改造,让导出EXCEL 更灵活方便

createh52个月前 (02-01)技术教程17

最近因为交付项目忙起来没有时间更新头条,刚好项目中有导出功能。于是马上就答应客户绝对没有问题,因为心里想这功能若依框架里面不是已经做了吗,直接用不就完了,还能有啥工作量,心里暗暗自喜。

但是在真正使用的时候发现了一个大问题,客户的需求是不同页面导出的字段不一样(其实后台我是同一个表),而且这种需求还不少,反正就是不管你后台怎么设计,在不同的页面可能需要导出的数据字段多少是不一样的。比如一个历史表,在A模块里面需要导出4个字段,在B模块里面可能需要导出6个字段。咱先看一下若依里面的excel导出 是怎么用的。

这个是若依最简单的导出用法,看起来是不是很简单方便?但是你仔细看就可以看到 这个list是从数据库查出来的数据,然后

ExcelUtil u = new ExcelUtil<>(SysConfig.class) ,这里用的是泛型,而且构造器还需要一个Class参数,并且这个入参Class也是泛型要和上面list 的类型一样。换句话说就是数据源和导出模板必须是同一个类。excel导出的配置 就在那个 SysConfig入参里面。如果我数据来源都是 List list , 这个SysConfig 里面有十几个字段,但是用户只需要导出4个字段 那这里就不能满足需求了。 在不改造的情况下,必须得通过下面得方式去实现。

首先自己再定义一个实体类 SysConfigVo ,这个类只定义你需要导出的字段 ,然后 将 List list 这个数据源遍历 转换成 List list ,最后重新调用导出

ExcelUtil u = new ExcelUtil<>(SysConfigVo.class)

u.exportExcel(response, list, "参数数据");

这样做虽然解决了问题,但是感觉这种做法太过于繁琐,而且额外多了一次数据的遍历。如果是一个业务还好,要是好几个业务都需要不同的导出,这个就有点不方便了。所以这个导入工具目前来看有以下几点不足:

  1. 数据源和导出的模版是用一个偶合大
  2. 不能满足同一个数据源需要导出不同模版的需求
  3. 泛型导致强耦合
  4. 构造器参数使用泛型完全是多余的

其具体的代码如下图所示:

可以看到,构造方法的入参和数据来源的通过泛型强耦合在一起了。实际上数据源和导出模版没有类型上的绑定关系,应该通过字段名字关联就可,这样才能实现一个数据源多个模版。为了解决这个问题,我着手对这个工具类进行以下改造:

  1. 构造器参数不需要泛型
  2. 可以支持任意的模版配置
  3. 数据源和导出配置类没有强耦合

改造后应该支持如下面的用法:

   List list = configService.selectConfigList(config);
   ExcelUtil2 util = new ExcelUtil2(ConfigVo2.class);
   util.exportExcel(response, list, "参数数据");

数据来源是 List ,导出模版是 ConfigVo2 这两者不是同一个类型,

util.exportExcel(response, list, "参数数据")这个方法可以接受任意数据源。 即它和ConfigVo2不需要是同一个类型,这样就可以使用一个list 配置不同的ConfigVo2,或者ConfigVo3,ConfigVo4 ,如此就可以满足一个数据源匹配不同的导出模型了。

为了兼容之前的业务,我没有修改原来的代码,只是复制出来一个重新命名为 ExcelUtil2。下面分享一下如何改造这个工具类让它可以灵活的配置不同导出模版。

首先,为了不强类型耦合,这里要去掉泛型,然后数据源也不使用泛型,而是接受任意数据

然后就是获取数据这个方法,原来是根据属性反射获取数据(所以它会要求数据类型和excel模版类型是同一个类。也就是你必须得像下面这样创建对象:

ExcelUtil u = new ExcelUtil<>(SysConfig.class) ,这个入参和数据源是同一个类型。这就是下图的Field 和T vo 必须是同属一个Class的原因,实际上这个T 泛型在这里没有任何作用,因为压根不需要知道它是什么类型。

下面是我改造后的代码截图,可以看到 这个数据是Object 任意类型,并不是T 泛型了,然后Field 和Object可以是同一个类也可以不同(但是需要有相同属性名) ,所以不能使用字段反射而是得使用方法反射。也就是通过数据源的Class 执行它的get方法获取真正的数据,而这个方法名则由Field对象提供(就是属性名称),这个Field 就是来自构造方法里面的那个配置类,这里就是解耦的关键所在。从这里也可以看出,实际上数据源是不需要关心它是什么具体类型的,只需要知道它是一个Object 就可以啦。

通过上面改造后,就可以通过一个数据源灵活的配置不同的导出模版了,如下面这样愉快的使用:

 // 这个是从数据库查询出来的原始数据   
List list = configService.selectConfigList(config);
// 创建对象,不需要泛型,但是需要一个导出模版的入参,这个参数来确定导出的模版格式和字段
ExcelUtil2 util = new ExcelUtil2(ConfigVo2.class);
// 这个方法可以接收SysConfig类型的 也可以接收其他任意类型的List,它和ConfigVo2可以不相同
util.exportExcel(response, list, "参数数据");

@Data
public class ConfigVo2 {
    @Excel(name = "参数名称", sort = 2)
    private String configName;
    @Excel(name = "参数主键", cellType = Excel.ColumnType.NUMERIC, sort = 1)
    private Long configId;
}

同样的数据源,咱可以导出到不同的模版中

@Data
public class ConfigVo3 {
    @Excel(name = "参数键名")
    private String configKey;
    @Excel(name = "参数键值")
    private String configValue;
}

List list = configService.selectConfigList(config);
// 这里直接使用 ConfigVo3 做导出,不需要做任何其他改动
ExcelUtil2 util = new ExcelUtil2(ConfigVo3.class);
util.exportExcel(response, list, "参数数据");

如果还有其它的导出模版,在不改变你service的前提下你只需要再创建提供模版类定义导出字段就可以了。

通过以上改造,这个导出工具就更加灵活了,适应更多的业务场景。但是从我个人角度看,又遇到另外一个问题,就是你需要建很多这种模版类,这些模版类又只使用一次,那你的代码就臃肿起来。下一期分享如何通过动态配置来如何解决这个问题。

十几年JAVA老码农,喜欢研究技术,目前是自由开发者,擅长物联网、TMS、MES、电商、在线教育项目开发,欢迎大家一起分享交流。

相关文章

Hutool Java工具类库导出Excel,超级简单

作者:程序猿的内心独白原文链接:http://suo.im/5Zxx2L前言在开发应用系统的时候,导出文件是必不可放的功能。以前用过POI、easyexcel等工具的导入导出功能,但总感觉太麻烦了,代...

java大牛告诉你这样导出excel更加简单高效

1.简述在java开发项目,我们经常会遇到将数据导出到Excel表格的需求 ,比较流行的使用POI、EasyExcel等。Apache POI是一个Java API,用于处理Microsoft Off...

【干货】如何使用Java实现百万数据的Excel导出功能?

Java作为一种常用的编程语言,在实现大量数据导出功能时具有很高的效率和可扩展性。本文将介绍如何使用Java实现百万数据的Excel导出功能。一、需求分析在很多实际应用场景中,我们需要将大量数据导出到...

程序员:超级简单导出Excel 工具,Hutool Java工具类库

前言在开发应用系统的时候,导出文件是必不可放的功能。以前用过POI、easyexcel等工具的导入导出功能,但总感觉太麻烦了,代码特别多,感觉并不是很好用。今天给大家介绍一款新工具,java工具类库H...

【Java技巧】高效数据传输:Java通过绑定快速将数据导出至Excel

前言把数据导出至 Excel 是很常见的需求,而数据的持久化,往往又放在数据库中。因此把数据库中的数据导出到 Excel中,成了非常普遍的一个需求。以关系型数据库为例,数据表是一个二维矩阵,但是为了易...

如何在SpringBoot中实现Excel数据导出功能?

在一些企业级的应用中,对于数据导出成Excel表格的需求是一个非常常见的需求,在SpringBoot中,我们可以借助于Apache POI库来实现这个需求,下面我们就来详细介绍一下如何在Spring...