EasyExcel数据导出功能封装

起因:

最近需要用到excel导出功能,使用EasyExcel可以快速实现导出,又需要优雅的对EasyExcel进行封装,在实现自己的导出功能时又可以制定一定的规则,让其他同事方便使用,最近研究了下网上的常规写法,站在巨人的肩上重新添加了自己的思路,供大家参考,有任何问题请多指教

痛点:

1、导出代码写在业务中,调用不统一且代码层次混乱
2、数据库查询的数据远多于对象中定义的数据,导出时默认导出了不想要的数据
3、相同的对象,在导出时需要根据不同条件进行设置不同的Excel表头字段,又不想定义多个导出对象
4、导出时如果设置过某个属性的表头宽度,优先按照设置的宽度导出,如果未设置,希望表头宽度有个默认值,而不是挤压在一起
5、excel需要导出大数据,都在一个sheet页中查看卡顿
6、导出的数据是数据库字符,查看excel人员看不懂,需要做数据转化

如果你有以上痛点问题,可以继续啦;如果没有也可以看看我的封装思路,还请各位高手不吝赐教,这里非常感谢 雪孤城的这篇文章 给了我很大的启发和参考

1. 工具类

1.1 EasyExcelUtil封装类

package cn.well.cloud.core.util.excel;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;/*** @Description: Easyexcel工具类封装及表格自动列宽设置* @Author: jiawei* @Date: 2023/7/26*/
@Slf4j
public class EasyExcelUtil {/*** 每个sheet的容量,即超过60000时就会把数据分sheet*/private static final int PAGE_SIZE = 60000;/*** 无过滤字段的导出excel* @param data 需要导出的数据集* @param fileName 需要导出的excel名* @param excelClass 需要导出的excel表头实体* @return* @author jiawei* @since 2023/7/27 下午1:39*/public static void exportByExcel(List<?> data, String fileName, Class<?> excelClass){exportByExcel(data, fileName, excelClass, AbstractEasyExcel.getExcludeColumnFieldNames());}/***  自定义过滤字段的导出excel* @param data 需要导出的数据集* @param fileName 需要导出的excel名* @param excelClass 需要导出的excel表头实体* @param excludeColumnFieldNames 需要过滤的字段集合* @return * @author jiawei* @since 2023/7/27 下午1:41*/public static void exportByExcel(List<?> data, String fileName, Class<?> excelClass, Collection<String> excludeColumnFieldNames){try {ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletResponse response = servletRequestAttributes.getResponse();long exportStartTime = System.currentTimeMillis();;log.info("报表导出Size: " + data.size() + "条。");// 把查询到的数据按设置的sheet的容量进行切割List<? extends List<?>> lists = SplitList.splitList(data, PAGE_SIZE);// 设置响应头AbstractEasyExcel.setHead(response, fileName + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));// 浏览器访问url直接下载文件的方式ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), excelClass).registerWriteHandler(AbstractEasyExcel.formatExcel()).registerWriteHandler(new AbstractEasyExcel.ExcelWidthStyleStrategy()).includeColumnFieldNames(AbstractEasyExcel.getIncludeColumnFiledNames(excelClass)).excludeColumnFieldNames(excludeColumnFieldNames).build();ExcelWriterSheetBuilder excelWriterSheetBuilder;WriteSheet writeSheet;if(ObjectUtil.hasNull(lists)){log.info("未查询到要导出的数据,导出终止");return;}for (int i = 1; i <= lists.size(); ++i) {excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);excelWriterSheetBuilder.sheetNo(i).sheetName("sheet" + i);writeSheet = excelWriterSheetBuilder.build();excelWriter.write(lists.get(i - 1), writeSheet);}// 必须要finish才会写入,不finish只会创建empty的文件excelWriter.finish();log.info("报表导出结束时间:" + new Date() + ";导出耗时: " + (System.currentTimeMillis() - exportStartTime) + "ms");} catch (IOException e) {e.printStackTrace();}}
}

1.2AbstractEasyExcel EasyExcel的基础封装,包含响应头设置,Excel的格式设置,根据实体设置需要导出的字段,设置需要过滤的实体中字段(字符串模式和lambda表达获取get方法引用的属性+连续方法调用模式),设置头部单元格宽度
AbstractEasyExcel

package cn.well.cloud.core.util.excel;import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import 

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

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

相关文章

【监控系统】可视化工具Grafana简介及容器化部署实战

1.什么是Grafana 官网地址&#xff1a;https://grafana.com/ Grafana用Go语言开发的开源数据可视化工具&#xff0c;可以做数据监控和数据统计&#xff0c;带有告警功能。支持快速灵活的客户端图表&#xff0c;面板插件有许多不同方式的可视化指标和日志&#xff0c;官方库中…

【NLP】无服务器问答系统

一、说明 在NLP的眼见的应用&#xff0c;就是在“ 当你在谷歌上提出一个问题并立即得到答案时会发生什么&#xff1f;例如&#xff0c;如果我们在谷歌搜索中询问谁是美国总统&#xff0c;我们会得到以下回答&#xff1a;Joe Biden&#xff1b;这是一个搜索问题&#xff0c;同时…

SpringCloudAlibaba微服务实战系列(一)Nacos服务注册发现

SpringCloudAlibaba微服务实战系列&#xff08;一&#xff09;Nacos服务注册发现 实战前先做一个背景了解。 单体架构、SOA和微服务 单体架构&#xff1a;近几年技术的飞速发展&#xff0c;各种各样的服务已经进入到网络化。单体架构发布时只需要打成一个war或jar包发布即可&a…

jar 命令实践

jar -h非法选项: h 用法: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ... 选项:-c 创建新档案-t 列出档案目录-x 从档案中提取指定的 (或所有) 文件-u 更新现有档案-v 在标准输出中生成详细输出-f 指定档案文件名-m 包含指定清单文…

嵌入式软件—RK3568开发环境搭建

一、RK3568 1.1 开发板特点 BSP比较大&#xff0c;对于电脑内存和存储空间要求高 1.2 BSP BSP&#xff08;Board Support Package&#xff0c;板级支持包&#xff09;&#xff0c;类似于PC系统中BIOS和驱动程序的集合&#xff0c;BSP包含的范围更广&#xff0c;除了外设驱动…

数值线性代数:知识框架

记录数值线性代数研究的知识框架。 软件包线性方程组直接法Guass消元法/LU分解、Cholesky分解 LAPACK oneAPI MKL ARPACK Octave 迭代法Jacobi迭代、SOR迭代、共轭梯度法最小二乘特征值/特征向量非对称幂法、QR、Arnoldi分解对称QR、Jacobi、二分法、分治法、SVD 参考资料 G…

noVNC安装部署

首先得确保你的vnc是管用的 然后再下面这一大堆地址随便下载一套noVNC的代码 git clone https://github.com/novnc/noVNC.git git clone git://github.com/kanaka/noVNC noVNC官网&#xff1a;noVNC noVNC Github&#xff1a;GitHub - novnc/noVNC: VNC client web applicatio…

pg三种插件验证

sr_plan 创建extension, 他会创建保留执行计划的表 创建表并插入数据 开启sr_plan.write_mode, 允许sr_plan收集SQL和执行计划 查看QUERY 1的执行计划 PostgreSQL支持merge join、GroupAggregate(通过INDEX SCAN),所以这个CASE,非常快,并不需要b对所有数据进行聚合。查看…

nginx mirror代码分析

实现方式 mirror逻辑的工作阶段&#xff1a; ngx在log phase之后&#xff08;在ngx_http_free_request处调用&#xff09;已完成向client端返回response&#xff0c;在log phase之后完成close connection&#xff08;短链接&#xff09;&#xff0c;在该阶段处理mirror逻辑不…

Python——Windows下载ffmpeg

目录 前言 一、下载 &#xff08;3种下载方式&#xff09; 1、第一种下载方式——我上传的文件 2、第二种下载方式——GitHub下载 3、第三种下载方式——官网下载 二、解压 三、配置环境变量 四、验证是否安装成功 五、其他 关于ffmpeg其他安装教程 ffmpeg的延迟问题 …

vscode保存html时,如何不换行?

我发现网上的答案都是千篇一律&#xff0c;都是复制过来的 "vetur.format.defaultFormatterOptions": {"js-beautify-html": {"wrap_line_length": 120,"wrap_attributes": "auto","end_with_newline": false}, …

typescript自动编译文件实时更新

npm install -g typescripttsc --init 生成tsconfig.json配置文件 tsc -w 在监听模式下运行&#xff0c;当文件发生改变的时候自动编译

C语言文件操作

目录 前言: 文件的分类 1. 程序文件 2.数据文件 文件的使用 文件指针 文件指针的使用 文件的打开与关闭 文件的使用方式 示例1&#xff1a; 示例2&#xff1a; 文件的顺序读写 函数简介 示例1&#xff1a; 示例2&#xff1a; 函数简介 示例1&#xff1a; 示例2&…

【我们一起60天准备考研算法面试(大全)-第二十六天 26/60】

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客&#xff0c;如有问题交流&#xff0c;欢迎评论区留言&#xff0c;一定尽快回复&#xff01;&#xff08;大家可以去看我的专栏&#xff0c;是所有文章的目录&#xff09;   文章字体风格&#xff1a; 红色文字表示&#…

linux获取随机字符串(或数字)的3种方法

1. 获取随机8位字符串&#xff1a; 方法1&#xff1a; # echo $RANDOM |md5sum |cut -c 1-8返回&#xff1a; 471b94f2方法2&#xff1a; # openssl rand -base64 4返回 vg3BEg方法3&#xff1a; # cat /proc/sys/kernel/random/uuid |cut -c 1-8返回 】ed9e032c2.获取随…

【什么是Read Write Through机制】

文章目录 一、Read-Write Through机制的定义二、Read-Write Through机制的特点三、Read-Write Through机制的实现方式四、Read-Write Through机制的应用场景 Read-Write Through机制是一种缓存一致性协议&#xff0c;用于保证存储子系统的缓存与主存储器之间的数据一致性。它是…

NAT详解(网络地址转换)

一句话说清楚它是干什么的&#xff1a; 网络地址转换&#xff1a;是指通过专用网络地址转换为公用地址&#xff0c;从而对外隐藏内部管理的IP地址&#xff0c;它使得整个专用网只需要一个全球IP就可以访问互联网&#xff0c;由于专用网IP地址是可以重用的&#xff0c;所以NAT大…

【Linux】Http协议的学习

文章目录 前言一、了解HTTP协议是如何规定的总结 前言 HTTP协议&#xff08;超文本传输协议&#xff09;和我们上一篇写的网络版计算器中自己定制的协议一样&#xff0c;只不过Http协议是是一个非常好用的协议&#xff0c;所以我们可以直接用现成的不用自己再搞一套了。 一、了…

EM算法实例

EM算法的E步骤&#xff0c; 是计算在当前的预估参数下&#xff0c;隐含变量&#xff08;是A硬币还是B硬币&#xff09;的每个值出现的概率。也就是给定和观测数据&#xff0c;计算这组数据出自A硬币的概率和这组数据出自B硬币的概率 我们根据E步中求出的A硬币、B硬币概率分布&…

在家构建您的迷你 ChatGPT

这篇文章分为三个部分&#xff1b;他们是&#xff1a; 什么是指令遵循模型&#xff1f;如何查找遵循模型的指令构建一个简单的聊天机器人废话不多说直接开始吧&#xff01;&#xff01;&#xff01; 什么是指令遵循模型&#xff1f; 语言模型是机器学习模型&#xff0c;可以根…