当前位置: 首页 > news >正文

EasyExcel实现动态表头功能

EasyExcel实现动态表头功能

开发过程中,大部分都会使用到导出报表功能,目前阶段会用得有
poi导出(暂无),
easyexcel导出(官方文档,https://easyexcel.opensource.alibaba.com/docs/current/),
easypoi导出(官方文档,http://doc.wupaas.com/docs/easypoi/easypoi-1c10ldlb9epsk)。
三者感觉大差不差,只不过后两者有大部分功能得集成,可能会免去很多代码。详细得区别详见各自得官方文档,拿一个适合自己开发即可。接下来,着重介绍一下今天得嘉宾,easyExcel ,会通过他得某些功能,来实现动态表头得输出。

动态表头(官方List方式)

首先是我们经常使用得动态表头导出,也是一搜一大把得,更是官方文档里提供得一种动态表头方式,也就是增加对应得list。由自己在业务层算好需要多少个列,就增加多少个list,哪行需要合并 也要增加对应得数据。
这种方式么比较耗费代码,适用于增减几个字段得业务场景。
这种方式方法就不过多追叙了,基本上一搜就是一大把得方式,这次主要介绍得,是一种适用于统计年月得情况。

 private List<List<String>> head() {List<List<String>> list = new ArrayList<List<String>>();List<String> head0 = new ArrayList<String>();head0.add("字符串" + System.currentTimeMillis());List<String> head1 = new ArrayList<String>();head1.add("数字" + System.currentTimeMillis());List<String> head2 = new ArrayList<String>();head2.add("日期" + System.currentTimeMillis());list.add(head0);list.add(head1);list.add(head2);return list;}

动态表头(自研,性能未知)

这种业务场景,虽然不多,但是不免也有用到得地方,大概场景就是 根据选择得年月区间,表内容既要展示一些基本信息,也要展示对应得年月数据,例如选了1-2月 就是 基本数据+ 1月 + 2月。选了3-5月,就得显示 基本数据+ 3月 + 4月 + 5月,由于后边月得不确定性,官方文档得List方式就有点不是很又好了。一方面,反参字段得设计,由于每个月都有三四条业务数据,所以12个月得话 光反参字段就是 12X4+ ,太多了。如果每个月得数据后续在增加一个属性字段,代码层面就要跟着变动 n处*12处,显然使用list方式已经不是很适合了,代码编写量翻倍,修改时候也得翻倍,很容易出错。另一方面,easyexcel导出字段中不能使用list,否则注解识别不了,造成导出异常,大概就是只能输出字符串,不能输出整个list,

    @ApiModelProperty(value = "查询统计数据")private List<TT> ttList;

在这里插入图片描述

种种原因,之前得方式肯定是不适用了,只能是看看能不能将两种方式结合起来,
第一步,肯定是设计参数了,由于数据是按月查询得,月份得数据反参也肯定是用list来收了,只不过会将查询到得数据,会在xml中自动转为list。最终得反参就是 n个基础数据字段, 2个list月份数据,其中一个用于计算所选月得平均值。
第二步,反参里得月份怎么能输出到excel中,按照异常提示,搜索一下,也不难搜索,搜索到得基本一致,都是加一个类型转换得,就是把读取得数据转字符输出。

 @Overridepublic CellData convertToExcelData(Object o, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {//写excel文件时被EasyExcel调用//用json转换工具将List对象转换为json字符串String json = JSONUtil.toJsonStr(o);CellData cellData = new CellData();return new CellData(json);}
@ExcelProperty(converter = ListDataConverter.class)
private List<TT> ttList;

这是处理完之后得注解,需要加上这个,然后对应得导出

  //处理集合数据
EasyExcel.write(response.getOutputStream())
.registerConverter(new ListDataConverter())
......

这样 导出之后 前边得基础数据也能正常显示,
在这里插入图片描述
只不过数据都是字符形式,
接着第三步就是对这个数据的处理,
第三步,写入数据,https://blog.csdn.net/qq_43021813/article/details/121465753?spm=1001.2014.3001.5502
可以参考之前得写数据文档,只不过这次是 通过实现RowWriteHandler 然后重写里边得afterRowDispose实现,

  implements RowWriteHandler @Overridepublic void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {}

原理是将这个list对应得列,将数据取出,然后根据不同得参数去创建不同得列,list 有几个数据就创建几个列,一般是4X新列,并将数据放里,这样list循环完之后,就会得到一个动态得表头了

           //基础数据到11  从11 开始增加列 每增加一列 列+1int cellNum = 11 ;for (int i = 0; i < responseList.size(); i++) {//得分Cell cell1 = row.createCell(cellNum);cell1.setCellValue(ttList.get(i).getA().toString());// 每增加一列 列+1cellNum++;//得分Cell cell2 = row.createCell(cellNum);cell2.setCellValue(ttList.get(i).getB().toString());cellNum++;//设置得分小计Cell cell3 = row.createCell(cellNum);cell3.setCellValue(ttList.get(i).getC().toString());cellNum++;//设置是否达标Cell cell4 = row.createCell(cellNum);cell4.setCellValue(ttList.get(i).getD().toString());cellNum++;}

在这里插入图片描述123 是三个字段,这样就循环出了4个月得数据 每个月又有123 三条业务数据,这样赋值完毕后,发现原有得list得字符串还在,就得想办法删掉,使用 row.removeCell(cell100); 只能删除内容,这样一来,又在报表中有了一列空白列,搜了两天没搜到结果,然后想到注解可以指定列输出数据所有就给他指定到一个永远不会使用得列去

    @ExcelProperty(converter = ListDataConverter.class,index = 100)@ApiModelProperty(value = "得分汇总(分月)")private List<TT> ttList;

指定完就是这样 将数据输出到表得第100列,这样将数据读取后 在是哦那个remove就不会造成空白列了。
第四步,数据基本都渲染完了,然后就是创建表头,合并表头,等等, 这些就直接搜索就行了,一搜也是一大把,根据自己表头得需要,写不同得handler就行了。
第五步,增加表名,类型,sheet名等等,就不多介绍了。

总体下来,第一天搭架子,写sql倒是没啥坑,第二天开始踩了不少坑,都是数据转换,赋值excel列数据等,要么就是写数据得方式不对写不进去,要么就是读取得有问题,各种坑各种填,一天改来改去得,第三四天基本就步入正轨了,数据渲染,表头设置合并等。
查询一个月示例
在这里插入图片描述
查询半年,当然了,年月时间可以随意
在这里插入图片描述
最终得效果还算比较满意吧,其余得就是宽高得微调了,

总之,自研还是有难度啊,中间还一度研究到了easypoi。发现原理和这个也差不多,又切回了excel。
此文档就不贴源码了,如有需要请私信有偿提供。

相关文章:

EasyExcel实现动态表头功能

EasyExcel实现动态表头功能 开发过程中&#xff0c;大部分都会使用到导出报表功能&#xff0c;目前阶段会用得有 poi导出&#xff08;暂无&#xff09;&#xff0c; easyexcel导出&#xff08;官方文档&#xff0c;https://easyexcel.opensource.alibaba.com/docs/current/&am…...

Python | 安装、环境配置及包的安装

Python | 安装、环境配置及包的安装 一、前言二、python安装及编辑器配置2.1 python安装2.2 python调试2.3 python编辑器 | PyCharm2.3.1 PyCharm下载2.3.2 PyCharm安装2.3.3 PyCharm启动界面2.3.4 PyCharm初步设置2.3.5 PyCharm环境配置(含Python Interpreter配置)2.3.5.1 New…...

CentOS 7 安装 JDK17(注意版本号要与自己的版本一致)

查看是否有自带的 JDK java -versionrpm -qa | grep jdk卸载自带 JDK rpm -e --nodeps [name] # 如 rpm -e --nodeps java-1.8.0-openjdk-1.8.0.242.b08-1.el7.x86_64查看自带 JDK 是否卸载干净 java -versionrpm -qa | grep jdk在 oracle 官网下载自己所需 JDK 版本&#x…...

JavaScript 数组操作

JavaScript 中的数组提供了各种操作方法&#xff0c;包括增加、删除、修改、查找、排序、遍历、去重和转换等。以下是一些常用的数组操作方法&#xff1a; 增加元素 push(element1, element2, …, elementN): 将一个或多个元素添加到数组的末尾&#xff0c;并返回新数组的长度…...

idea使用lombok编译问题

idea编译报错问题如下&#xff1a; java: You arent using a compiler supported by lombok, so lombok will not work and has been disabled.Your processor is: com.sun.proxy.$Proxy26Lombok supports: OpenJDK javac, ECJ解决方案&#xff1a;在idea配置中File->Setti…...

GoLong的学习之路(番外)如何使用依赖注入工具:wire

我为什么要直接写番外呢&#xff1f;其原因很简单。项目中会使用&#xff0c;其实在这里大家就可以写一些项目来了。 依赖注入的工具本质思想其实都大差不差。无非控制反转和依赖注入。 文章目录 控制反转为什么需要依赖注入工具 wire的概念提供者&#xff08;provider&#x…...

【pyspider】爬取ajax请求数据(post),如何处理python2字典的unicode编码字段?

情景&#xff1a;传统的爬虫只需要设置fetch_typejs即可&#xff0c;因为可以获取到整个页面。但是现在ajax应用越来越广泛&#xff0c;所以有的网页不能用此种爬虫类型来获取页面的数据&#xff0c;只能用slef.crawl()来发起http请求来抓取数据。 直接上例子&#xff1a; 可以…...

torch.cumprod实现累乘计算

cumprod取自“cumulative product”的缩写&#xff0c;即“累计乘法”。 数学公式为&#xff1a; y i x 1 x 2 x 3 . . . x i y_ix_1\times{x_2}\times{x_3}\times{...}\times{x_i} yi​x1​x2​x3​...xi​ 官方链接&#xff1a;torch.cumprod 用法&#xff1a; impo…...

设计模式之迭代器模式

什么是迭代器模式 迭代器模式&#xff08;Iterator pattern&#xff09;是一种对象行为型设计模式&#xff0c;它提供了一种方法来顺序访问聚合对象中的元素&#xff0c;而又不暴露该对象的内部表示&#xff0c;同时也可以将迭代逻辑与聚合对象的实现分离&#xff0c;增强了代码…...

使用SSH ,让windows和linux互通

简介 SSH 是一种安全网络协议&#xff0c;旨在让客户端和服务器之间进行安全的数据传输。SSH 的核心思想是利用公钥加密技术和共享密钥加密技术相结合的方式&#xff0c;使客户端和服务器之间建立起安全的连接。 当客户端发起连接请求时&#xff0c;服务器会对客户端进行身份验…...

常用设计模式——策略模式

策略模式是什么 策略模式&#xff08;Strategy&#xff09;&#xff1a;针对一组算法&#xff0c;将每一个算法封装起来&#xff0c;从而使得它们可以相互替换。 比如我们一个软件的会员等级&#xff0c;每一个等级都会有对应的一些等级权益&#xff0c;那么每一个等级权益就…...

牛客网 CM11.链表分割

目录 1.解题思路2.代码实现 1.解题思路 此题目思路相对简单&#xff0c;利用双指针&#xff0c;一个指针指向小于val的&#xff0c;一个指针指向大于等于val的&#xff0c;但实现起来&#xff0c;如果仅仅使用单链表&#xff0c;那么还需特别判断第一个指针是否为空从而特意做…...

[iOS开发]iOS中TabBar中间按钮凸起的实现

在日常使用app的过程中&#xff0c;经常能看到人家实现了底部分栏控制器的中间按钮凸起的效果&#xff0c;那么这是怎么实现的呢&#xff1f; 效果演示&#xff1a; 实现原理&#xff1a; 创建按钮 创建一个UITabBar的子类&#xff0c;重写它的layoutSubviews方法&#xff1…...

数字时代,企业的数据共享意味着什么?

随着数字化整体在社会方方面面的推进&#xff0c;通过数据直接或间接创造的价值越来越大&#xff0c;逐渐成为了构建现代社会的重要要素。而对于企业来说&#xff0c;数据也是在数字经济中容易接触也切实能够利用产生大量价值&#xff0c;所以如何最大化利用数据&#xff0c;让…...

壹[1],QT自定义控件创建(QtDesigner)

1&#xff0c;环境 Qt 5.14.2 VS2022 原因&#xff1a;厌烦了控件提升的繁琐设置&#xff0c;且看不到界面预览显示。 2&#xff0c;QT制作自定义控件 2.1&#xff0c;New/其他项目/Qt4 设计师自定义控件 2.2&#xff0c;设置项目名称 2.3&#xff0c;设置 2.4&#xff0c;设…...

解决Java对接LDAP AD域登录出现Unprocessed Continuation Reference(s)错误

出现该错误的原因&#xff0c;主要是因为Java namingx的库&#xff0c;默认选项是未设置跟随&#xff0c;389返回的是AD域条目的引用&#xff0c;需要进行引用跟随。 解决方法分为两种&#xff0c;第一类不使用全局目录服务的端口389和636&#xff0c;而是使用真实端口 把代码…...

could not read ok from ADB Server

执行adb devices提示 List of devices attached * daemon not running; starting now at tcp:5037 could not read ok from ADB Server * failed to start daemon 方法1&#xff0c;关闭防火墙&#xff0c; could not read ok from ADB Server_夜星辰2023的博客-CSDN博客 我…...

超越基础:Flutter 中 onTap 的 5 条规则让你脱颖而出

小事情决定了你的熟练程度&#xff0c;这些小细节的有趣之处在于它们的丰富性。您将在代码库中的数百个位置遇到 onTap 事件。增强它们可以对代码的可维护性和最终用户体验产生重大的积极影响。 onTap 就是这样一个微小但丰富的东西——我们在每个屏幕上都使用它。这纯粹是关于…...

综合布线可视化管理系统价值分析

传统综合布线管理&#xff0c;全部依靠手工登记&#xff0c;利用标签标示线缆&#xff0c;利用文档资料记录链路的连接和变更&#xff0c;高度依赖网络管理员的管理能力&#xff0c;维护效率低下。同时&#xff0c;网络接入故障和非法接入难以及时发现。在以往的文章中小编一直…...

【JavaSE】基础笔记 - 类和对象(上)

目录 1、面向对象的初步认知 1.1、什么是面向对象 1.2、面向对象与面向过程 2. 类定义和使用 2.1、简单认识类 2.2、类的定义格式 2.3、自定义类举例说明 2.3.1、定义一个狗类 2.3.2、定义一个学生类 3、类的实例化 3.1、什么是实例化 3.2、类和对象的说明 1、面向…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中&#xff0c;云安全与网络安全作为信息安全的两大支柱&#xff0c;常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异&#xff0c;并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全&#xff1a;聚焦于保…...