EasyExcel日常使用总结
文章目录
- 概要
- 引入依赖
- 常用操作方法
- 折叠或隐藏列
- 折叠或隐藏行
- 单元格样式
- 单行表头设置
- 多行表头设置
- 多个sheet写入
- 自动列宽
概要
EasyExcel日常使用总结。
引入依赖
引入依赖
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>
常用操作方法
折叠或隐藏列
- 新建对象用于存储隐藏列数据,后续直接根据此数据进行折叠隐藏。
@Data
public class ExcelHiddenCellVo {// 分组坐标起始private int startHidden;// 分组坐标结束private int endHidden;// 是否折叠private Boolean ifCollapse;// 是否隐藏private Boolean ifHidden;
}
- 计算折叠隐藏列数据(逻辑可根据数据自定义,折叠隐藏的,可以是固定的也可以是动态的)
private List<ExcelHiddenCellVo> calculateHiddenColumn() {List<ExcelHiddenCellVo> excelHiddenCellVos = new ArrayList<>();ExcelHiddenCellVo excelHiddenCellVo = new ExcelHiddenCellVo();excelHiddenCellVo.setStartHidden(monthValue + 1);excelHiddenCellVo.setEndHidden(12);excelHiddenCellVo.setIfHidden(false);excelHiddenCellVo.setIfCollapse(true);excelHiddenCellVos.add(excelHiddenCellVo);return excelHiddenCellVos;}
- 定义RowWriteHandler类方法,在写入每一行数据之前或之后执行自定义操作
private RowWriteHandler rowWriteHandler(List<ExcelHiddenCellVo> excelHiddenCellVos) {return new RowWriteHandler() {@Overridepublic void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer relativeRowIndex, Boolean isHead) {// 列分组if (isHead && relativeRowIndex == 0) {excelHiddenCellVos.forEach(item -> {Sheet sheet = writeSheetHolder.getSheet();sheet.groupColumn(item.getStartHidden(), item.getEndHidden());sheet.setColumnGroupCollapsed(item.getStartHidden(), item.getIfCollapse());});}}};}
- 使用的话直接注册一个写入处理器,把RowWriteHandler操作写入。
EasyExcel.write(outputStream).head(this.emailExcelHead(year, deptName)) // 设置表头.inMemory(true).registerWriteHandler(this.rowWriteHandler(this.calculateHiddenColumn())).doWrite(deptKpiStatisticsExportVos);
折叠或隐藏行
和列是类似的,只是使用的Hanlder不一样
- 计算折叠隐藏行数据(逻辑可根据数据自定义,折叠隐藏的,可以是固定的也可以是动态的)
// 计算出需要折叠的行private List<ExcelHiddenCellVo> calculateHiddenRow(List<DeptKpiStatisticsExportVo> vos) {List<ExcelHiddenCellVo> excelHiddenCellVos = new ArrayList<>();......
- 定义CellWriteHandler类方法,在单元格创建后触发行折叠
private CellWriteHandler cellStyleHandler(List<ExcelHiddenCellVo> excelHiddenCellVos) {return new CellWriteHandler() {@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {excelHiddenCellVos.forEach(item -> {Sheet sheet = writeSheetHolder.getSheet();sheet.groupRow(item.getStartHidden(), item.getEndHidden());sheet.setRowGroupCollapsed(item.getStartHidden(), true);});}}
}
- 使用的话直接注册一个写入处理器,把CellWriteHandler操作写入。
EasyExcel.write(outputStream).head(this.emailExcelHead(year, deptName)) // 设置表头.inMemory(true).registerWriteHandler(this.rowWriteHandler(this.calculateHiddenColumn())).registerWriteHandler(this.cellStyleHandler(excelHiddenCellVos)).doWrite(deptKpiStatisticsExportVos);
单元格样式
- 我一般使用自定义HorizontalCellStyleStrategy类,作为整体的默认样式
// 整体默认的样式private HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {WriteCellStyle headWriteCellStyle = new WriteCellStyle();WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short) 9);headWriteFont.setBold(true);headWriteFont.setFontName("微软雅黑");headWriteCellStyle.setWriteFont(headWriteFont);// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 背景绿色contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());WriteFont contentWriteFont = new WriteFont();// 字体大小contentWriteFont.setFontHeightInPoints((short) 9);contentWriteFont.setFontName("微软雅黑");contentWriteCellStyle.setWriteFont(contentWriteFont);contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER); // 设置水平居中contentWriteCellStyle.setBorderTop(BorderStyle.THIN); // 设置边框contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);contentWriteCellStyle.setBorderRight(BorderStyle.THIN);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);}
- 需要自定义样式的,再写一个CellWriteHandler类。
// 创建自定义的单元格样式private CellWriteHandler cellStyleHandler(List<FinanceDeptKpiStatisticsExportVo> financeDeptKpiStatisticsExportVos, List<ExcelHiddenCellVo> excelHiddenCellVos) {return new CellWriteHandler() {@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {Cell cell = context.getCell();WriteCellData<?> cellData = context.getFirstCellData();WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();if (cell.getRowIndex() == 0 || cell.getRowIndex() == 1 || cell.getRowIndex() == 2) {WriteFont writeFont = new WriteFont();writeFont.setBold(true);writeFont.setFontName("微软雅黑");writeFont.setFontHeightInPoints((short) 14);writeCellStyle.setBorderTop(BorderStyle.NONE); // 设置边框writeCellStyle.setBorderBottom(BorderStyle.NONE);writeCellStyle.setBorderLeft(BorderStyle.NONE);writeCellStyle.setBorderRight(BorderStyle.NONE);writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);writeCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());writeCellStyle.setWriteFont(writeFont);}} }
}
- 使用同样的注册到registerWriteHandler里面。
单行表头设置
- 单行表头可以定义一个类,使用@ExcelProperty注解标识每个字段。
@Data
public class ExportVo {@ExcelProperty(index = 0, value = "工号")private String headAccount;@ExcelProperty(index = 1, value = "姓名")private String headName;
}
- 使用
EasyExcel.write(outputStream).head(ExportVo.class) // 设置表头
多行表头设置
使用List<List>嵌套,List里面元素有多少个,则表示有多少级表头。以下为四级表头。
// 表头设置private List<List<String>> emailExcelHead(String year, String deptName) {String title = deptName + "明细表";String titleYear = "(" + year + "年度)";List<List<String>> list = new ArrayList<>();List<String> head1 = new ArrayList<>();head1.add(title);head1.add(titleYear);head1.add("部门:");head1.add("序号");List<String> head2 = new ArrayList<>();head2.add(title);head2.add(titleYear);head2.add(deptName);head2.add("科目");List<String> head3 = new ArrayList<>();head3.add(title);head3.add(titleYear);head3.add("");head3.add("费用类型");list.add(head1);list.add(head2);list.add(head3);return list;
多个sheet写入
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();ExcelWriter excelWriter = EasyExcel.write(outputStream).build();WriteSheet writeSheet = EasyExcel.writerSheet("报表1").head(CompleteWarehousingManHourExportVo.class).registerWriteHandler(new ExcelWidthStyleStrategy(0)) // 自定义列宽策略.registerWriteHandler(WriteExcelUtils.getHorizontalCellStyleStrategy()) // 整体单元格的样式设置.registerWriteHandler(this.CompleteWarehousingStyleHandler()) // 自定义单元格样式.registerWriteHandler(this.rowWriteHandler(this.calculateHiddenColumn())) // 列分组.build();excelWriter.write(warehousingManHourExportVos, writeSheet);WriteSheet writeSheet2 = EasyExcel.writerSheet("报表2").head(CompleteMesManHourExportVo.class).registerWriteHandler(new ExcelWidthStyleStrategy(0)) // 自定义列宽策略.registerWriteHandler(WriteExcelUtils.getHorizontalCellStyleStrategy()) // 整体单元格的样式设置.build();excelWriter.write(completeMesManHourExportVos, writeSheet2);excelWriter.finish();outputStream.flush();outputStream.close();InputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
自动列宽
使用同样registerWriteHandler注册
public class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {// 单元格的最大宽度private static final int MAX_COLUMN_WIDTH = 8;// 缓存(第一个Map的键是sheet的index, 第二个Map的键是列的index, 值是数据长度)private Map<Integer, Map<Integer, Integer>> CACHE = new HashMap(8);// 表头 0为第a行,1为第2行 依次类推Integer headRow = 0;public ExcelWidthStyleStrategy(Integer headRow){this.headRow = headRow;}// 重写设置列宽的方法@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder,List<WriteCellData<?>> cellDataList,Cell cell,Head head,Integer relativeRowIndex,Boolean isHead) {boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);// 当时表头或者单元格数据列表有数据时才进行处理if (needSetWidth) {Map<Integer, Integer> maxColumnWidthMap =CACHE.get(writeSheetHolder.getSheetNo());if (maxColumnWidthMap == null) {maxColumnWidthMap = new HashMap(16);CACHE.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);}// 获取数据长度Integer columnWidth = this.getLength(cellDataList, cell, cell.getRowIndex());if (columnWidth >= 0) {if (columnWidth > MAX_COLUMN_WIDTH) {columnWidth = MAX_COLUMN_WIDTH;}// 确保一个列的列宽以表头为主,如果表头已经设置了列宽,单元格将会跟随表头的列宽Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());if (maxColumnWidth == null || columnWidth > maxColumnWidth) {// 控制以哪一行为表头,大于1则以第二行if (cell.getRowIndex() >= headRow)maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);// 如果使用EasyExcel默认表头,那么使用columnWidth * 512// 如果不使用EasyExcel默认表头,那么使用columnWidth * 256// 如果是自己定义的字体大小,可以再去测试这个参数常量writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 512);}}}}/*** 获取当前单元格的数据长度* @param cellDataList* @param cell* @param* @return*/private Integer getLength(List<WriteCellData<?>> cellDataList,Cell cell,Integer rowNum) {if (rowNum == headRow) {return cell.getStringCellValue().getBytes().length;} else {WriteCellData cellData = cellDataList.get(0);CellDataTypeEnum type = cellData.getType();if (type == null) {return -1;} else {switch(type) {case STRING:return cellData.getStringValue().getBytes().length;case BOOLEAN:return cellData.getBooleanValue().toString().getBytes().length;case NUMBER:return cellData.getNumberValue().toString().getBytes().length;default:return -1;}}}}}
相关文章:
EasyExcel日常使用总结
文章目录 概要引入依赖常用操作方法折叠或隐藏列折叠或隐藏行单元格样式单行表头设置多行表头设置多个sheet写入自动列宽 概要 EasyExcel日常使用总结。 引入依赖 引入依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</a…...
人只活一次,活出一道光吧
人只活一次, 你怎么舍得让自己的短暂的一生是丑陋的, 你怎么舍得让自己短暂的一生, 只是在往下坠落, 即便是坠落, 也应该具有落日般的华丽吧, 你会漫漫的活成一束光, 谁若接近你, 就是接近光, 【人人都想向上,人人都想老而不衰,但现实是当你想活成一道光…...
sqli-labs:1~16(sql注入点稳定判断语句、全回显半回显报错回显无回显利用思路、sql注入tips)
怎么验证sql注入的存在呢? 首先,双引号单引号注入,看看有没有报错,或者与正常参数的区别,有报错说明大概率可以注入成功,但是,很可能单引号和双引号测试可能没有报错回显,或者与正常…...
springboot农产品销售信息微信小程序—计算机毕业设计源码35557
摘 要 在信息飞速发展的今天,网络已成为人们重要的信息交流平台。每天都有大量的农产品需要通过网络发布,为此,本人开发了一个基于springboot农产品销售信息微信小程序。 对于本农产品销售信息系统的设计来说,它主要是采用后台采…...
HuggingChat macOS 版现已发布
Hugging Face 的开源聊天应用程序 Hugging Chat,现已推出适用于 macOS 的版本。 主要特点 Hugging Chat macOS 版本具有以下亮点: 强大的模型支持: 用户可以一键访问多个顶尖的开源大语言模型,包括 Qwen 2.5 72B、Command R、Phi 3.5、Mistral 12B 等等&…...
C#:动态为Object对象添加新属性的方法
在C#中,object 类型本身是一个基础类型,它不支持直接添加属性,因为 object 并不具备定义属性的能力(它不支持任何接口或基类中的属性,除非通过类型转换)。然而,有几种方法可以在运行时模拟给对象…...
我常用的几个Python金融数据接口库,非常好用~
在金融分析和量化投资领域,Python已成为最受欢迎的编程语言之一。这主要归功于其丰富的库和框架,它们提供了处理和分析金融数据所需的工具,而且还有大量免费实时的金融股票数据供你分析研究。 以下是六个最常用的Python金融数据接口库&#x…...
【机器学习】ID3、C4.5、CART 算法
目录 常见的决策树算法 1. ID3 2. C4.5 3. CART 决策树的优缺点 优点: 缺点: 决策树的优化 常见的决策树算法 1. ID3 ID3(Iterative Dichotomiser 3)算法使用信息增益作为特征选择的标准。它是一种贪心算法,信…...
UE5: Content browser工具编写02
DebugHeader.h 中的全局变量,已经在一个cpp file中被include了,如果在另一个cpp file中再include它,就会有一些conflicts。先全部给加一个static Add static keyword to debug functionsWrap all the functions inside of a namespaceprint …...
【ARM】MDK-当选择AC5时每次点击build都会全编译
【更多软件使用问题请点击亿道电子官方网站】 1、 文档目标 解决MDK中选择AC5时每次点击build都会全编译 2、 问题场景 在MDK中点击build时,正常会只进行增量编译,但目前每次点击的时候都会全编译。 3、软硬件环境 1 软件版本:Keil MDK 5.…...
使用ESPnet的 setup_anaconda.sh安装脚本一步到位,配置conda虚拟环境
使用ESPnet的 setup_anaconda.sh 安装脚本一步到位,配置conda虚拟环境 前言 ESPnet(End-to-End Speech Processing Toolkit)是一款用于语音识别、语音合成等任务的开源端到端语音处理工具包。为了在不同系统上快速配置ESPnet开发环境&#…...
9、论文阅读:无监督的感知驱动深水下图像增强
Perception-Driven Deep Underwater Image Enhancement Without Paired Supervision 前言引言相关工作UIE模型基于非物理模型基于物理模型基于深度学习质量度量在图像增强中的应用方法论问题表述PQR模型PDD网络生成器损失函数实验Enhancement Without Paired Supervision) 前言…...
谷歌收录查询工具,使用谷歌收录查询工具查询网站收录情况并优化内容的详细步骤
在数字营销和SEO领域,了解网站在谷歌搜索引擎中的收录情况至关重要。使用谷歌收录查询工具,可以有效地监测网站的索引状态,进而优化内容以提升网站排名和曝光度。以下是如何使用谷歌收录查询工具查询网站收录情况并优化内容的详细步骤&#x…...
代理中长效的长板在哪里
伙伴们,之前咱们讨论过了短效代理的用途,那么今天我们来聊一聊长效代理的多元化用途,大家也可以对比一下它们的区别,根据自身的需求针对性地去选择合适的哦。 在企业的网络安全保卫战中,长效代理像是一座坚不可摧的钢…...
VS code Jupyter notebook 导入文件目录问题
VS code Jupyter notebook 导入文件目录问题 引言正文引言 这几天被 VS code 中 Jupyter Notebook 中的文件导入折磨的死去活来。这里特来说明一下放置于不同文件夹下的模块该如何被导入。 正文 首先,我们需要按下 Ctrl + , 键打开设置,然后搜索 notebook file root。在如…...
【IDEA】将光标移动到您上一次编辑的地方
将光标移动到您上一次编辑的地方 使用 ctl <-- 似乎是回到上一个文件而 ctl shift Backspace 是回到上一次的光标,似乎更有用一些。Backspace 是删除按键,要非常小心。 快捷键快速回退到上一次编辑的位置 在 IntelliJ IDEA 中,您可以…...
设备管理平台-支持快速开发
技术路线(同时支持前后端分离 / 前后端一体,可用于网关或者服务器部署) 前端:layui-v2.9.17 后端:Net8.0 使用组件 Swagger、Jwt、Freesql、MiniExcel、MemoryCache(存储登录用户信息,代替HttpContext.S…...
Vue项目开发注意事项
事项一:项目代码放在本地怎么运行起来 1、首先确定项目对应的node和npm版本 node下载地址 Index of /dist/https://nodejs.org/dist/ node 与 npm版本对应关系 Node.js — Node.js Releases 2、node卸载的时候,会自动把对应的npm卸载掉 情况1&…...
Vivado时序报告之CDC详解大全
目录 一、前言 二、Report CDC 2.1 Report CDC 2.2 配置界面 2.3 CDC报告 2.3.1 General Information 2.3.2 Summary 2.3.3 CDC Details 2.4 Waiver 2.4.1 设置Waiver 2.4.2 报告查看 2.4.3 去除Waiver设置 三、工程设计 四、参考资料 一、前言 前面已经针对…...
【研赛A题成品论文】24华为杯数学建模研赛A题成品论文+可运行代码丨免费分享
2024华为杯研究生数学建模竞赛A题精品成品论文已出! A题 风电场有功功率优化分配 一、问题分析 A题是一道工程建模与优化类问题,其目的是根据题目所给的附件数据资料分析风机主轴及塔架疲劳损伤程度,以及建立优化模型求解最优有功功率分配…...
CCC数字钥匙Release 3实战:如何用BLE/UWB实现无钥匙进入(附避坑指南)
CCC数字钥匙Release 3实战:BLE/UWB无钥匙进入系统开发全解析 当你的手机靠近车辆时,车门自动解锁——这种科幻般的体验正通过CCC数字钥匙Release 3标准变为现实。作为汽车电子工程师,我曾用nRF5340开发板搭配UWB模块完整实现了这套系统&#…...
华为交换机等保2.0实战:手把手配置身份鉴别,从密码策略到登录超时
华为交换机等保2.0身份鉴别全流程配置指南 当企业网络面临等保2.0合规检查时,身份鉴别环节往往是整改重点。作为网络安全工程师,我曾协助多家企业通过等保测评,发现华为交换机的身份鉴别配置存在不少易忽略的细节。本文将分享一套经过实战验证…...
ESP32 LVGL8.1 —— 消息框进阶:自定义按钮与事件处理实战
1. ESP32与LVGL8.1消息框基础认知 第一次接触ESP32和LVGL8.1的消息框功能时,我完全被它的灵活性震惊了。想象一下,你正在开发一个智能家居控制面板,当用户操作不当或者系统需要确认时,弹出一个美观的对话框是多么自然的事情。这就…...
万象视界灵坛惊艳效果展示:同一张宠物图在‘金毛犬’‘幼犬’‘户外玩耍’‘毛发蓬松’多维排序
万象视界灵坛惊艳效果展示:同一张宠物图在"金毛犬""幼犬""户外玩耍""毛发蓬松"多维排序 1. 效果展示开场 今天我要向大家展示万象视界灵坛这个神奇工具的实际效果。它就像一个视觉魔法师,能够深入理解图片中的…...
Wan2.2-I2V-A14B惊艳案例:动态水墨山水+古风人物行走10秒视频生成
Wan2.2-I2V-A14B惊艳案例:动态水墨山水古风人物行走10秒视频生成 1. 开篇:当AI遇见传统水墨艺术 想象一下,你只需要输入一段文字描述,就能让AI生成一段10秒的动态水墨山水视频,画中还有古风人物悠然行走。这不是科幻…...
Ansible Playbook在JumpServer中的高级用法:自动化运维效率提升技巧
Ansible Playbook在JumpServer中的高阶实战:效率倍增的自动化运维策略 开篇:当堡垒机遇上自动化运维 想象一下这样的场景:凌晨三点,服务器突然告警,传统运维需要手动登录每台机器检查状态,而熟练使用Ansibl…...
【Matlab】MATLAB教程:图形属性修改(案例:set(h,‘Color‘,‘red‘),应用:自定义图形样式)
MATLAB教程:图形属性修改(案例:set(h,Color,red),应用:自定义图形样式) 在MATLAB数据可视化、实验报告绘图、工程结果展示等场景中,默认绘制的图形往往难以满足个性化需求和规范要求。无论是调整线条颜色、粗细,还是优化坐标轴、图例样式,核心目标都是通过图形属性修…...
SVM实战:从线性可分到核技巧的全面解析
1. SVM入门:从分类问题到最优超平面 第一次听说SVM时,我正被一个简单的二分类问题困扰着。手头有一组客户数据,需要根据消费习惯将他们分成两类。试过逻辑回归,效果勉强及格;用决策树又容易过拟合。直到同事推荐了SVM&…...
Java 25 FFI与C++ ABI不兼容?GCC 13/Clang 18符号修饰差异导致段错误的逆向工程溯源(含LLVM IR级对比图)
第一章:Java 25 FFI与C ABI不兼容问题的现场复现与现象确认Java 25 引入的 Foreign Function & Memory API(FFI)在调用 C 原生函数时,因 C ABI(Application Binary Interface)未被标准化支持࿰…...
千问3.5-2B镜像实战:免conda/pip安装,网页端直接调用内置视觉语言模型
千问3.5-2B镜像实战:免conda/pip安装,网页端直接调用内置视觉语言模型 1. 镜像介绍与核心能力 千问3.5-2B是Qwen系列中的轻量级视觉语言模型,专为图片理解和文本生成任务优化。这个预置镜像的最大特点是开箱即用——无需任何conda或pip安装…...
