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

EasyExcel导出工具类

目录

工具类

头部实体类(要和工具类在同一个module或项目下)

日期转换器


工具类

/*** 导出Excel工具类*/
public class EasyExcelUtil<T> {/*** 单sheet(Map写入)* @param response 响应对象* @param headList 头部集合* @param dataList 数据集合*/public static void write(HttpServletResponse response, List<ExcelHead> headList, List<Map<String, Object>> dataList) throws IOException {ExcelWriterBuilder writerBuilder = EasyExcel.write();writerBuilder.file(response.getOutputStream());writerBuilder.excelType(ExcelTypeEnum.XLSX);//日期转换器TimestampStringConverter converter = new TimestampStringConverter();writerBuilder.registerConverter(converter).registerWriteHandler(new ColumnWidthStyleStrategy()).head(convertHead(headList)).sheet("sheet1").doWrite(convertData(headList, dataList));}/*** 多sheet(Map写入)* @param response 响应对象* @param headMap 头部Map数据* @param dataMap 数据Map数据* @param sheetMap sheet Map数据*/public static void multipleWrite(HttpServletResponse response, Map<String,List<ExcelHead>> headMap, Map<String,List<Map<String, Object>>> dataMap, Map<String,String> sheetMap) throws IOException {//日期转换器TimestampStringConverter converter = new TimestampStringConverter();ExcelWriter excelWriter = EasyExcel.write().registerConverter(converter).registerWriteHandler(new ColumnWidthStyleStrategy()).file(response.getOutputStream()).excelType(ExcelTypeEnum.XLSX).autoCloseStream(true).build();int i = 0;for (Map.Entry<String,List<ExcelHead>> entry : headMap.entrySet()) {WriteSheet writeSheet = EasyExcel.writerSheet(i++, sheetMap.get(entry.getKey())).head(convertHead(entry.getValue())).build();excelWriter.write(convertData(entry.getValue(), dataMap.get(entry.getKey())), writeSheet);}excelWriter.finish();}/*** 实体写入* @param response 响应对象* @param sheetName sheet名称* @param c 实体类* @param list 实体数据*/public static <T> void writeSheet(HttpServletResponse response, String sheetName, Class<T> c, List<T> list) throws IOException {EasyExcel.write(response.getOutputStream(), c).sheet(sheetName).doWrite(list);}/*** 读取并存储到实体* @param fileName 路径地址* @param sheetName sheet名称* @param c 实体类*/public static <T> List<T> read(String fileName, String sheetName, Class c) {List<T> list = new ArrayList();EasyExcel.read(fileName, c, new ReadListener<T>() {@Overridepublic void invoke(T o, AnalysisContext analysisContext) {list.add(o);}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}}).sheet(sheetName).doRead();return list;}/*** 读取并存储到实体* @param fileName 路径地址* @param sheetNo 指定sheet*/public static Map<String,Object> readToMap(String fileName, Integer sheetNo) {Map<String,Object> result = new HashMap<>();List<Map<String,Object>> dataList = new ArrayList();//头部mapMap<String,String> headMap = new HashMap<>();//头部拼音mapMap<String,String> pinyinMap = new HashMap<>();EasyExcel.read(fileName,new AnalysisEventListener<Map<Integer, Object>>() {@Overridepublic void invoke(Map<Integer, Object> data, AnalysisContext context) {Map<String,Object> map = new HashMap<>();for (Integer key : data.keySet()) {if(key!=null && data.get(key)!=null) {map.put("field_" + key.toString(), data.get(key));}}dataList.add(map);}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}@Overridepublic void invokeHead(Map<Integer, ReadCellData<?>> head, AnalysisContext context) {for (Integer key : head.keySet()) {if(key!=null && head.get(key)!=null && StringUtils.isNotBlank(head.get(key).getStringValue())) {headMap.put("field_" + key.toString(), head.get(key).getStringValue());pinyinMap.put("field_" + key.toString(), Pinyin4jUtils.getPinYinHeadChar(head.get(key).getStringValue()));}}}}).sheet(sheetNo).headRowNumber(1).doRead();result.put("headMap",headMap);result.put("pinyinMap",pinyinMap);result.put("dataList",dataList);result.put("count",dataList.size());return result;}/*** 读取表头并存储到实体* @param fileName 路径地址* @param sheetNo 指定sheet*/public static Map<String,Object> readToMapHead(String fileName, Integer sheetNo) {Map<String,Object> result = new HashMap<>();//头部mapMap<String,String> headMap = new HashMap<>();//头部拼音mapMap<String,String> pinyinMap = new HashMap<>();EasyExcel.read(fileName,new AnalysisEventListener<Map<Integer, Object>>() {@Overridepublic void invoke(Map<Integer, Object> data, AnalysisContext context) {}@Overridepublic void doAfterAllAnalysed(AnalysisContext analysisContext) {}@Overridepublic void invokeHead(Map<Integer, ReadCellData<?>> head, AnalysisContext context) {for (Integer key : head.keySet()) {if(key!=null && head.get(key)!=null && StringUtils.isNotBlank(head.get(key).getStringValue())) {headMap.put("field_" + key.toString(), head.get(key).getStringValue());pinyinMap.put("field_" + key.toString(), Pinyin4jUtils.getPinYinHeadChar(head.get(key).getStringValue()));}}}}).sheet(sheetNo).headRowNumber(1).doRead();result.put("headMap",headMap);result.put("pinyinMap",pinyinMap);return result;}/*** 头部转换* @param headList 头部集合*/private static List<List<String>> convertHead(List<ExcelHead> headList) {List<List<String>> list = new ArrayList<>();for (ExcelHead head : headList) {list.add(Lists.newArrayList(head.getTitle()));}//沒有搞清楚head的参数为List<List<String>>,用List<String>就OK了return list;}/*** 数据转换* @param headList 头部集合* @param dataList 数据集合*/private static List<List<Object>> convertData(List<ExcelHead> headList, List<Map<String, Object>> dataList) {List<List<Object>> result = new ArrayList();//对dataList转为easyExcel的数据格式for (Map<String, Object> data : dataList) {List<Object> row = new ArrayList();for (ExcelHead h : headList) {Object o = data.get(h.getFieldName());//需要对null的处理,比如age的null,要转为-1row.add(handler(o, h.getNullValue()));}result.add(row);}return result;}/*** 空值处理* @param o 数值* @param nullValue 空值置换*/private static Object handler(Object o, Object nullValue) {return o != null ? o : nullValue;}
}

头部实体类(要和工具类在同一个module或项目下)

/*** Excel头部实体*/
public class ExcelHead<T> {private String fieldName;private String title;private T nullValue;public ExcelHead(String fieldName, String title) {this.fieldName = fieldName;this.title = title;}public ExcelHead(String fieldName, String title, T nullValue) {this.fieldName = fieldName;this.title = title;this.nullValue = nullValue;}public String getFieldName() {return fieldName;}public void setFieldName(String fieldName) {this.fieldName = fieldName;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public T getNullValue() {return nullValue;}public void setNullValue(T nullValue) {this.nullValue = nullValue;}
}

注意:真正导出表格的是ExcelWriterSheetBuilder类中的方法,前面只是封装,这个是真正导出用到的;这个类是EasyExcel自带的。

日期转换器

/*** 日期转换器*/
public class TimestampStringConverter implements Converter<Timestamp> {@Overridepublic Class<?> supportJavaTypeKey() {return Timestamp.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}@Overridepublic WriteCellData<?> convertToExcelData(Timestamp value, ExcelContentProperty contentProperty,GlobalConfiguration globalConfiguration) {WriteCellData cellData = new WriteCellData();String cellValue;if (contentProperty == null || contentProperty.getDateTimeFormatProperty() == null) {cellValue = DateUtils.format(value.toLocalDateTime(), null, globalConfiguration.getLocale());} else {cellValue = DateUtils.format(value.toLocalDateTime(), contentProperty.getDateTimeFormatProperty().getFormat(),globalConfiguration.getLocale());}cellData.setType(CellDataTypeEnum.STRING);cellData.setStringValue(cellValue);cellData.setData(cellValue);return cellData;}
}

相关文章:

EasyExcel导出工具类

目录 工具类 头部实体类&#xff08;要和工具类在同一个module或项目下&#xff09; 日期转换器 工具类 /*** 导出Excel工具类*/ public class EasyExcelUtil<T> {/*** 单sheet&#xff08;Map写入&#xff09;* param response 响应对象* param headList 头部集合* p…...

【Godot4.2】EasyTreeData通用解析

概述 之前在《【Godot4.2】Tree控件自定义树形数据ETD及其解析》一文中&#xff0c;实现了对带缩进的层级结构文本的解析&#xff0c;并将其用于Tree控件的列表项构造。 不过当时并没有实现专门的类&#xff0c;今天花了一点时间实现了一下。现在可以更方便的构造和解析ETD数…...

力扣每日一题109:有序链表转换二叉搜索树

题目 中等 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为 平衡 二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0&#xff0c;-3,9&#xff0c;-10,null,5]&#xff0c;它…...

企业计算机服务器中了locked勒索病毒怎么处理,locked勒索病毒解密建议

随着互联网技术在企业当中的应用&#xff0c;越来越多的企业利用网络开展各项工作业务&#xff0c;网络为企业提供了极大便利&#xff0c;也大大加快了企业发展步伐&#xff0c;提高了企业生产办公效率。但网络技术的发展也为企业的数据安全带来严重威胁。近期&#xff0c;云天…...

开源推荐榜【MalusAdmin基于 Vue3/TypeScript/NaiveUI 和 NET7 Sqlsugar 开发的后台管理框架】

简介 Malus是海棠的意思&#xff0c;顾名思义&#xff0c;海棠后台管理系统&#xff0c;读音与【马卢斯】相近&#xff0c;也可称作为马卢斯后台管理系统。 基于NET Core | NET7/8 & Sqlsugar | Vue3 | vite4 | TypeScript | NaiveUI 开发的前后端分离式权限管理系统,采用…...

批量抓取某电影网站的下载链接

思路&#xff1a; 进入电影天堂首页&#xff0c;提取到主页面中的每一个电影的背后的那个urL地址 a. 拿到“2024必看热片”那一块的HTML代码 b. 从刚才拿到的HTML代码中提取到href的值访问子页面&#xff0c;提取到电影的名称以及下载地址 a. 拿到子页面的页面源代码 b. 数据提…...

2024-05-06 问AI: 介绍一下深度学习中的LSTM网络

文心一言 当谈到深度学习中的LSTM&#xff08;Long Short-Term Memory&#xff09;网络时&#xff0c;它是一种特殊的循环神经网络&#xff08;RNN&#xff09;架构&#xff0c;旨在解决传统RNN在处理长序列时遇到的梯度消失和梯度爆炸问题。LSTM网络因其能够捕捉序列数据中的…...

二、Redis五种常用数据类型-String

1、用途 简单的K-V缓存计数器分布式锁session共享分布式ID生成(自增) 2、底层实现结构 Redis底层是c语言实现的&#xff0c;但是并没有使用c的string来表示字符串&#xff0c;而是使用自己的简单动态字符串的抽象类型(simple dynamic string,SDS)。 SDS结构&#xff1a; st…...

echarts柱状图实现左右横向对比

实现效果如上图 其实是两组数据&#xff0c;其中一组数据改为负数&#xff0c;然后 在展示的时候&#xff0c;在将负数取反 第一处修改坐标轴 xAxis: [{type: value,axisLabel: {formatter: function (value) {if (value < 0) {return -value;}else{return value;}}}}], 第…...

脸爱云一脸通智慧管理平台 SystemMng 管理用户信息泄露漏洞(XVE-2024-9382)

0x01 产品简介 脸爱云一脸通智慧管理平台是一套功能强大,运行稳定,操作简单方便,用户界面美观,轻松统计数据的一脸通系统。无需安装,只需在后台配置即可在浏览器登录。 功能包括:系统管理中心、人员信息管理中心、设备管理中心、消费管理子系统、订餐管理子系统、水控管…...

spring笔记2

一、基于xml的AOP实现 基于注解管理Bean&#xff0c;注解扫描 <context:component-scan base-package"com.zhou.spring.aop.xml"></context:component-scan><aop:config> <!-- 设置一个公共的切入点表达式--><aop:pointcut id&q…...

【挑战30天首通《谷粒商城》】-【第一天】02、简介-项目整体效果展示

文章目录 课程介绍 ( 本章了解即可&#xff0c;可以略过)一、 分布式基础 (全栈开发篇) (初中级)二、 分布式高级 (微服务架构篇) ( 高级)三、高可用集群 (架构师提升篇)( 架构 ) one more thing 课程介绍 ( 本章了解即可&#xff0c;可以略过) 1.分布式基础(全栈开发篇)2.分布…...

Kafka 生产者应用解析

目录 1、生产者消息发送流程 1.1、发送原理 2、异步发送 API 2.1、普通异步发送 2.2、带回调函数的异步发送 3、同步发送 API 4、生产者分区 4.1、分区的优势 4.2、生产者发送消息的分区策略 示例1&#xff1a;将数据发往指定 partition 示例2&#xff1a;有 key 的…...

GEE错误——image.reduceRegion is not a function

简介 image.reduceRegion is not a function 这里的主要问题是我们进行地统计分析的时候&#xff0c;我们的作用对象必须是单景影像&#xff0c;而不是影像集合 错误"image.reduceRegion is not a function" 表示你正在尝试使用reduceRegion()函数来处理图像数据&…...

rk356x 关于yocto编译linux及bitbake实用方法

Yocto 完整编译 source oe-init-build-envbitbake core-image-minimalYocto 查询包名 bitbake -s | grep XXX // 获取rockchip相关包 :~/rk3568/yocto$ bitbake -s | grep rockchip android-tools-conf-rockchip :1.0-r0 gstreamer1.0-rockchip …...

Chrome您的连接不是私密连接 |输入“thisisunsafe”命令绕过警告or添加启动参数

一、输入 thisisunsafe 在当前页面用键盘输入 thisisunsafe &#xff0c;不是在地址栏输入(切记)&#xff0c;就直接敲键盘就行了 因为Chrome不信任这些自签名ssl证书&#xff0c;为了安全起见&#xff0c;直接禁止访问了&#xff0c;thisisunsafe 这个命令&#xff0c;说明你…...

牛客面试前端1

HTML语义化 是什么 前端语义化是指在构建网页时多使用html语义化标签布局&#xff0c;多使用带有语义的标签如header&#xff0c;aside&#xff0c;footer等标签为什么 结构清晰利于开发者开发与维护 有利于seo搜索引擎优化 有利于在网络卡顿时&#xff0c;正常显示页面结构&a…...

Linux的软件包管理器-yum

文章目录 软件包的概念yum源的配置的原因yum的使用查看软件包安装软件卸载软件 软件包的概念 软件包(SoftWare Package)是指具有特定的功能&#xff0c;用来完成特定任务的一个程序或一组程序。可分为应用软件包和系统软件包两大类 在Linux系统中&#xff0c;下载安装软件的方式…...

选择排序(Selection Sort)

选择排序(Selection Sort)是一种简单直观的排序算法。它的工作原理如下: 遍历数组:从待排序的数列中,找到当前未排序部分(即整个数组或已排序部分之后的部分)中的最小(或最大,取决于排序方式)元素。 交换位置:将找到的最小元素与未排序部分的第一个元素交换位置,这…...

网络面试题目

1、BGP报文有哪些? 有5种报文,Open、 Update、 Notification、 Keepalive和 Route-refresh等5种报文类型。 2、Vxlan了解多少? VLAN作为传统的网络隔离技术,VXLAN完美地弥补了VLAN的上述不足。 VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),(VXL…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:

在 HarmonyOS 应用开发中&#xff0c;手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力&#xff0c;既支持点击、长按、拖拽等基础单一手势的精细控制&#xff0c;也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档&#xff0c…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

JavaScript基础-API 和 Web API

在学习JavaScript的过程中&#xff0c;理解API&#xff08;应用程序接口&#xff09;和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能&#xff0c;使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

渗透实战PortSwigger靶场:lab13存储型DOM XSS详解

进来是需要留言的&#xff0c;先用做简单的 html 标签测试 发现面的</h1>不见了 数据包中找到了一个loadCommentsWithVulnerableEscapeHtml.js 他是把用户输入的<>进行 html 编码&#xff0c;输入的<>当成字符串处理回显到页面中&#xff0c;看来只是把用户输…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...