百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

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

toyiye 2024-06-23 18:41 22 浏览 0 评论

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 // 这个是从数据库查询出来的原始数据   
List<SysConfig> 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<SysConfig> list = configService.selectConfigList(config);
// 这里直接使用 ConfigVo3 做导出,不需要做任何其他改动
ExcelUtil2 util = new ExcelUtil2(ConfigVo3.class);
util.exportExcel(response, list, "参数数据");

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

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

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

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码