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。
此文档就不贴源码了,如有需要请私信有偿提供。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/134409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】特殊类设计+类型转换+IO流

&#x1f307;个人主页&#xff1a;平凡的小苏 &#x1f4da;学习格言&#xff1a;命运给你一个低的起点&#xff0c;是想看你精彩的翻盘&#xff0c;而不是让你自甘堕落&#xff0c;脚下的路虽然难走&#xff0c;但我还能走&#xff0c;比起向阳而生&#xff0c;我更想尝试逆风…

c语言实现http下载功能,显示进度条和下载速率

#include <stdio.h>//printf #include <string.h>//字符串处理 #include <sys/socket.h>//套接字 #include <arpa/inet.h>//ip地址处理 #include <fcntl.h>//open系统调用 #include <unistd.h>//write系统调用 #include <netdb.h>//…

机器学习实战:基于sklearn的工业蒸汽量预测

文章目录 写在前面工业蒸汽量预测1.基础代码2.模型训练3.模型正则化4.模型交叉验证5.模型超参空间及调参6.学习曲线和验证曲线 写在后面 写在前面 本期内容&#xff1a;基于机器学习的工业蒸汽量预测 实验环境&#xff1a; anaconda python sklearn 注&#xff1a;本专栏内所有…

K8s学习笔记——认识理解篇

1. K8s诞生背景 回顾应用的部署&#xff0c;经历了以下几个阶段&#xff1a; 传统部署&#xff1a;物理服务器上运行应用程序。虚拟机部署&#xff1a;物理服务器上安装虚拟机&#xff0c;在虚拟机上运行应用程序。容器部署&#xff1a;物理服务器上安装容器运行时&#xff0…

YB4554是一款经济高效、完全集成的高端输入电压单电池锂离子电池充电器。

YB4554 带OVP保护的高输入电压充电器 概述&#xff1a; YB4554是一款经济高效、完全集成的高端输入电压单电池锂离子电池充电器。这个充电器使用锂离子要求的CC/CV充电模式电池充电器可接受高达24V&#xff0c;但当输入电压超过OVP阈值&#xff0c;通常为6.8V&#xff0c;以防…

antdv使用a-cascader联级选择器实现自定义浮层样式

一般的使用组件库想要自定义样式都会使用深度选择器deep去实现 但是有的组件不管是deep还是!important还是写行内样式都改不掉 这里主要讲使用a-cascader联级选择器的浮层改变样式 一&#xff0c;使用组件 <a-cascader:options"regionOptions"change-on-selectv…

30道高频Vue面试题快问快答

面试中的快问快答 快问快答的情景在面试中非常常见。 在面试过程中&#xff0c;面试官通常会使用快问快答的方式来快速评估面试者的基础知识、思维能力和反应速度。 这种情景下&#xff0c;面试官会提出一系列简短的问题&#xff0c;并期望面试者能够迅速做出回答或提供简洁明…

云计算实战项目之---学之思在线考试系统

简介&#xff1a; 学之思开源考试系统是一款 java vue 的前后端分离的考试系统。主要优点是开发、部署简单快捷、界面设计友好、代码结构清晰。支持web端和微信小程序&#xff0c;能覆盖到pc机和手机等设备。 支持多种部署方式&#xff1a;集成部署、前后端分离部署、docker部…

初识rust

调试下rust 的执行流程 参考&#xff1a; 认识 Cargo - Rust语言圣经(Rust Course) 新建一个hello world 程序&#xff1a; fn main() {println!("Hello, world!"); }用IDA 打开exe&#xff0c;并加载符号&#xff1a; 根据字符串找到主程序入口&#xff1a; 双击…

SpringCloud 微服务全栈体系(十二)

第十一章 分布式搜索引擎 elasticsearch 一、初识 elasticsearch 1. 了解 ES 1.1 elasticsearch 的作用 elasticsearch 是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 例如&#xff1a; 在 GitHub 搜…

【安全】Java幂等性校验解决重复点击(6种实现方式)

目录 一、简介1.1 什么是幂等&#xff1f;1.2 为什么需要幂等性&#xff1f;1.3 接口超时&#xff0c;应该如何处理&#xff1f;1.4 幂等性对系统的影响 二、Restful API 接口的幂等性三、实现方式3.1 数据库层面&#xff0c;主键/唯一索引冲突3.2 数据库层面&#xff0c;乐观锁…

亚马逊云科技产品测评』活动征文|通过使用Amazon Neptune来预测电影类型初体验

文章目录 福利来袭Amazon Neptune什么是图数据库为什么要使用图数据库什么是Amazon NeptuneNeptune 的特点 快速入门环境搭建notebook 图神经网络快速构建加载数据配置端点Gremlin 查询清理 删除环境S3 存储桶删除 授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转…

chatgpt升级啦,训练数据时间更新到2023年4月,支持tools(升级functionCall),128k上下文

&#xff08;2023年11月7日&#xff09; gpt-4-1106-preview https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo 训练数据日期升级到2023年四月 上线文增加到128k 调用一次chatgpt接口&#xff0c;可以得到多次函数调用 import OpenAI from "openai"…

水利部加快推进小型水库除险加固,大坝安全监测是重点

国务院常务会议明确到2025年前&#xff0c;完成新出现病险水库的除险加固&#xff0c;配套完善重点小型水库雨水情和安全监测设施&#xff0c;实现水库安全鉴定和除险加固常态化。 为加快推进小型水库除险加固前期工作&#xff0c;水利部协调财政部提前下达了2023年度中央补助…

网络流量分类概述

1. 什么是网络流量&#xff1f; 一条网络流量是指在一段特定的时间间隔之内&#xff0c;通过网络中某一个观测点的所有具有相同五元组(源IP地址、目的IP地址、传输层协议、源端口和目的端口)的分组的集合。 比如(10.134.113.77&#xff0c;47.98.43.47&#xff0c;TLSv1.2&…

YOLOv8-Pose推理详解及部署实现

目录 前言一、YOLOv8-Pose推理(Python)1. YOLOv8-Pose预测2. YOLOv8-Pose预处理3. YOLOv8-Pose后处理4. YOLOv8-Pose推理 二、YOLOv8-Pose推理(C)1. ONNX导出2. YOLOv8-Pose预处理3. YOLOv8-Pose后处理4. YOLOv8-Pose推理 三、YOLOv8-Pose部署1. 源码下载2. 环境配置2.1 配置CM…

web前端js基础------制作滚动图片

1&#xff0c;要求 通过定时器使其出现滚动的效果 可以通过按键控制图片滚动的方向&#xff08;设置两个按钮绑定点击事件&#xff09; 当鼠标悬停时图片停止&#xff0c;鼠标离开时图片继续向前滚动&#xff08;可以设置鼠标的悬停和离开事件&#xff09; 参考如下 conten…

揭开堆叠式自动编码器的强大功能

一、介绍 在不断发展的人工智能和机器学习领域&#xff0c;深度学习技术因其处理复杂和高维数据的能力而广受欢迎。在各种深度学习模型中&#xff0c;堆叠式自动编码器是一种多功能且功能强大的工具&#xff0c;可用于特征学习、降维和数据表示。本文探讨了堆叠式自动编码器在深…

【论文阅读】Generating Radiology Reports via Memory-driven Transformer (EMNLP 2020)

资料链接 论文原文&#xff1a;https://arxiv.org/pdf/2010.16056v2.pdf 代码链接&#xff08;含数据集&#xff09;&#xff1a;https://github.com/cuhksz-nlp/R2Gen/ 背景与动机 这篇文章的标题是“Generating Radiology Reports via Memory-driven Transformer”&#xf…

【JAVA】:万字长篇带你了解JAVA并发编程-死锁优化【六】

目录 【JAVA】&#xff1a;万字长篇带你了解JAVA并发编程-并发编程的优化【六】并发编程的优化避免死锁死锁产生的条件避免死锁的方式死锁例程代码使用JpsJstack查看进程死锁问题 避免资源竞争 个人主页: 【⭐️个人主页】 需要您的【&#x1f496; 点赞关注】支持 &#x1f4a…