Easyexcel(5-自定义列宽)

相关文章链接

  1. Easyexcel(1-注解使用)
  2. Easyexcel(2-文件读取)
  3. Easyexcel(3-文件导出)
  4. Easyexcel(4-模板文件)
  5. Easyexcel(5-自定义列宽)

注解

@ColumnWidth

@Data
public class WidthAndHeightData {@ExcelProperty("字符串标题")private String string;@ExcelProperty("日期标题")private Date date;@ColumnWidth(50)@ExcelProperty("数字标题")private Double doubleData;
}

注解使用时表头长度无法做到动态调整,只能固定设置,每次调整表头长度时只能重新修改代码

注意:@ColumnWidth最大值只能为255,超过255*256长度时会报错

查看XSSFSheet源码

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

类方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

AbstractHeadColumnWidthStyleStrategy

public abstract class AbstractHeadColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head,Integer relativeRowIndex, Boolean isHead) {// 判断是否满足 当前行索引不为空 && (当前是表头 || 当前行索引是首行)// 如果不满足,则说明不是表头,不需要设置boolean needSetWidth = relativeRowIndex != null && (isHead || relativeRowIndex == 0);if (!needSetWidth) {return;}Integer width = columnWidth(head, cell.getColumnIndex());if (width != null) {width = width * 256;writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), width);}}protected abstract Integer columnWidth(Head head, Integer columnIndex);
}

通过继承AbstractHeadColumnWidthStyleStrategy类,实现columnWidth方法获取其对应列的宽度

SimpleColumnWidthStyleStrategy

源码查看

public class SimpleColumnWidthStyleStrategy extends AbstractHeadColumnWidthStyleStrategy {private final Integer columnWidth;public SimpleColumnWidthStyleStrategy(Integer columnWidth) {this.columnWidth = columnWidth;}@Overrideprotected Integer columnWidth(Head head, Integer columnIndex) {return columnWidth;}
}

基本使用

通过registerWriteHandler设置策略方法调整每列的固定宽度

@Data
public class User {@ExcelProperty(value = "用户Id")private Integer userId;@ExcelProperty(value = "姓名")private String name;@ExcelProperty(value = "手机")private String phone;@ExcelProperty(value = "邮箱")private String email;@ExcelProperty(value = "创建时间")private Date createTime;
}
@GetMapping("/download2")
public void download2(HttpServletResponse response) {try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");User user = new User();user.setUserId(123);user.setName("asplplplplpplplplplpl");user.setPhone("15245413");user.setEmail("54565454@qq.com");user.setCreateTime(new Date());EasyExcel.write(response.getOutputStream(), User.class).sheet("模板").registerWriteHandler(new SimpleColumnWidthStyleStrategy(20)).doWrite(Arrays.asList(user));} catch (Exception e) {e.printStackTrace();}
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

LongestMatchColumnWidthStyleStrategy

源码查看

public class LongestMatchColumnWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {private static final int MAX_COLUMN_WIDTH = 255;private final Map<Integer, Map<Integer, Integer>> cache = MapUtils.newHashMapWithExpectedSize(8);@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell,Head head,Integer relativeRowIndex, Boolean isHead) {// 判断 是否为表头 || 导出内容是否为空boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);if (!needSetWidth) {return;}Map<Integer, Integer> maxColumnWidthMap = cache.computeIfAbsent(writeSheetHolder.getSheetNo(), key -> new HashMap<>(16));Integer columnWidth = dataLength(cellDataList, cell, isHead);if (columnWidth < 0) {return;}// 超过最大值255时则设置为255if (columnWidth > MAX_COLUMN_WIDTH) {columnWidth = MAX_COLUMN_WIDTH;}// 比较该列的宽度,如果比原来的宽度大,则重新设置Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());if (maxColumnWidth == null || columnWidth > maxColumnWidth) {maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);}}private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {// 如果是表头,则返回表头的宽度if (isHead) {return cell.getStringCellValue().getBytes().length;}// 如果是单元格内容,则根据类型返回其内容的宽度WriteCellData<?> cellData = cellDataList.get(0);CellDataTypeEnum type = cellData.getType();if (type == null) {return -1;}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;}}
}

LongestMatchColumnWidthStyleStrategy是一个列宽自适应策略。当我们在写入Excel数据时,如果希望根据数据的实际长度来自适应调整列宽,就可以使用这个策略。它会遍历指定列的所有数据(包括表头),找出最长的数据,然后根据这个最长数据的长度来设定该列的宽度,确保数据在单元格内不会被截断。

根据官网介绍:这个目前不是很好用,比如有数字就会导致换行。而且长度也不是刚好和实际长度一致。 所以需要精确到刚好列宽的慎用。

基本使用

@GetMapping("/download1")
public void download1(HttpServletResponse response) {try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");User user = new User();user.setUserId(123);user.setName("asplplplplpplplplplpl");user.setPhone("15245413");user.setEmail("54565454@qq.com");user.setCreateTime(new Date());EasyExcel.write(response.getOutputStream(), User.class).sheet("模板").registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).doWrite(Arrays.asList(user));} catch (Exception e) {e.printStackTrace();}
}

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表头宽度工具类

仿照LongestMatchColumnWidthStyleStrategy源码自定义工具类

使用构造器传参的方式,用户可以自定义通过表头或者单元格内容长度来设置列宽,通过修改常数值和比例可以自己设置想调整的列宽

/*** 表头宽度根据表头或数据内容自适应*/
public class CustomWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {/*** 1-根据表头宽度,2-根据单元格内容*/private Integer type;private Map<Integer, Map<Integer, Integer>> cache = new HashMap<>();public CustomWidthStyleStrategy(Integer type) {this.type = type;}/*** 设置列宽** @param writeSheetHolder 写入Sheet的持有者* @param cellDataList 当前列的单元格数据列表* @param cell 当前单元格* @param head 表头* @param relativeRowIndex 当前行的相对索引* @param isHead 是否为表头*/@Overrideprotected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {if (type == 1) {if (isHead) {int columnWidth = cell.getStringCellValue().length();columnWidth = Math.max(columnWidth * 2, 20);if (columnWidth > 255) {columnWidth = 255;}writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);}return;}//不把标头计算在内boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);if (needSetWidth) {Map<Integer, Integer> maxColumnWidthMap = cache.get(writeSheetHolder.getSheetNo());if (maxColumnWidthMap == null) {maxColumnWidthMap = new HashMap<>();cache.put(writeSheetHolder.getSheetNo(), maxColumnWidthMap);}Integer columnWidth = this.dataLength(cellDataList, cell, isHead);if (columnWidth >= 0) {if (columnWidth > 255) {columnWidth = 255;}Integer maxColumnWidth = maxColumnWidthMap.get(cell.getColumnIndex());if (maxColumnWidth == null || columnWidth > maxColumnWidth) {maxColumnWidthMap.put(cell.getColumnIndex(), columnWidth);writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);}}}}/*** 数据长度** @param cellDataList* @param cell* @param isHead* @return*/private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {//头直接返回原始长度if (isHead) {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 + 1;case BOOLEAN:return cellData.getBooleanValue().toString().getBytes().length;case NUMBER:return cellData.getNumberValue().toString().getBytes().length * 2;case DATE:return cellData.getDateValue().toString().length() + 1;default:return -1;}}}}
}
@GetMapping("/download3")
public void download3(HttpServletResponse response) {try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");User user = new User();user.setUserId(123);user.setName("asplplplplpplplplplpl");user.setPhone("15245413");user.setEmail("54565454@qq.com");user.setCreateTime(new Date());EasyExcel.write(response.getOutputStream(), User.class).sheet("模板").registerWriteHandler(new CustomWidthStyleStrategy(1)).doWrite(Arrays.asList(user));} catch (Exception e) {e.printStackTrace();}
}@GetMapping("/download4")
public void download4(HttpServletResponse response) {try {response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xls");User user = new User();user.setUserId(123);user.setName("asplplplplpplplplplpl");user.setPhone("15245413");user.setEmail("54565454@qq.com");user.setCreateTime(new Date());EasyExcel.write(response.getOutputStream(), User.class).sheet("模板").registerWriteHandler(new CustomWidthStyleStrategy(2)).doWrite(Arrays.asList(user));} catch (Exception e) {e.printStackTrace();}
}

运行结果

  1. 使用表头设置的列宽

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 使用单元格内容设置的列宽

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

相关文章

C++ 中的模板特化和偏特化

C中的模板特化和偏特化是C模板编程中的两种重要技术&#xff0c;用于在特定情况下提供更优化的代码实现。‌ 模板特化 模板特化是指在模板参数为特定类型时&#xff0c;提供一种特定的实现方式。模板特化分为‌函数模板特化‌和‌类模板特化‌。 函数模板特化‌&#xff1a; …

短信发送业务

Override public void sendCode(String phone) {// 通过正则判断手机号的合法性if (!phone.matches("^1[3-9]\\d{9}$")) {throw new RuntimeException("请输入合法的手机号");}// 判断3次// String.format("code:%s", phone)String numKey Stri…

1+X应急响应(网络)文件包含漏洞:

常见网络攻击-文件包含漏洞&命令执行漏洞&#xff1a; 文件包含漏洞简介&#xff1a; 分析漏洞产生的原因&#xff1a; 四个函数&#xff1a; 产生漏洞的原因&#xff1a; 漏洞利用条件&#xff1a; 文件包含&#xff1a; 漏洞分类&#xff1a; 本地文件包含&#xff1a; …

深入实践 Shell 脚本编程:高效自动化操作指南

一、什么是 Shell 脚本&#xff1f; Shell 脚本是一种用 Shell 编写的脚本程序&#xff0c;用于执行一系列的命令。它是 Linux/Unix 系统中自动化管理任务的利器&#xff0c;能够显著提升工作效率&#xff0c;特别适合批量处理文件、监控系统状态、自动部署等任务。 二、Shell…

HTML5 SVG

HTML5 SVG SVG(Scalable Vector Graphics)是一种基于XML的图像格式,用于在网页上创建矢量图形。与传统的位图图像(如PNG和JPEG)不同,SVG图像可以无限放大而不失真,因为它们是由直线和曲线定义的数学路径,而不是像素点。HTML5支持直接在网页中嵌入SVG,使得网页设计更加…

Flutter:SlideTransition位移动画,Interval动画延迟

配置vsync&#xff0c;需要实现一下with SingleTickerProviderStateMixinclass _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin{// 定义 AnimationControllerlate AnimationController _controller;overridevoid initState() {super.…

gitlab:使用脚本批量下载项目,实现全项目检索

目的 当需要知道gitlab中所有项目是否存在某段代码时&#xff0c;gitlab免费版只提供了当个项目内的检索&#xff0c;当项目过多时一个个查太过繁琐。下面通过 GitLab API 将指定 Group 下的所有项目克隆到本地。此脚本会自动获取项目列表并逐一克隆它们&#xff0c;再在本地进…

【Android】android compat理解

1&#xff0c;前提 即便是在同一手机上安装的不同apk&#xff0c;其编译的apk不同&#xff0c;也会导致行为上的差异。如SDK34有限制后台启动&#xff0c;但如果安装的apk所依赖的sdk是33&#xff0c;则不会表现出此差异。这是如何实现的呢&#xff1f;其实&#xff0c;本质是…

使用php和Xunsearch提升音乐网站的歌曲搜索效果

文章精选推荐 1 JetBrains Ai assistant 编程工具让你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的图标增强神器 3 IDEA插件推荐-SequenceDiagram&#xff0c;自动生成时序图 4 BashSupport Pro 这个ides插件主要是用来干嘛的 &#xff1f; 5 IDEA必装的插件&…

电脑自动关机时间如何定?Wise Auto Shutdown 设置关机教程

在日常使用电脑的过程中&#xff0c;有时我们需要让电脑在特定的时间自动关机&#xff0c;比如在下载大文件完成后、执行长时间的任务结束时&#xff0c;或者只是单纯想在某个预定时间让电脑自动关闭以节省能源。这时候&#xff0c;Wise Auto Shutdown 这款软件就能派上大用场了…

微信小程序被攻击怎么选择高防产品

家人们&#xff0c;微信小程序被攻击了&#xff01;这事儿可不小。你想想&#xff0c;咱们平时用小程序点外卖、购物、玩游戏&#xff0c;现在却可能面临信息泄露风险。卡顿、闪退都算轻的&#xff0c;关键是咱的账号安全、个人数据&#xff0c;就像在“裸奔”。小程序本是方便…

k8s上面的Redis集群链接不上master的解决办法

问题描述 之前在k8s上面部署了一台node&#xff0c;然后创建了6个redis的pod&#xff0c;构建了一个redis的集群&#xff0c;正常运行。 最近添加了一台slave node&#xff0c;然后把其中的几个redis的pod调度到了slave node上面&#xff0c;结果集群就起不来了&#xff0c;…

什么是 C++ 中的智能指针?有哪些类型的智能指针?

智能指针的定义 在 C 中&#xff0c;智能指针是一种类模板&#xff0c;用于管理动态分配的内存。它的主要目的是自动管理内存的生命周期&#xff0c;避免手动释放内存时可能出现的错误&#xff0c;如内存泄漏&#xff08;忘记释放内存&#xff09;和悬空指针&#xff08;访问已…

Oracle热备过程中对数据库崩溃的处理方法

引言 在热备过程中如果发生数据库崩溃、断电等情况该如何处理? 如果正在备份 users 表空间的数据文件过程中,此时的数据文件表头 SCN 会被锁定,此时正在复制数据文件时数据库崩溃,系统断电。 从而导致数据文件表头与控制文件中的不一致,导致数据库无法打开,会要求介质恢…

Python操作neo4j库py2neo使用之创建和查询(二)

Python操作neo4j库py2neo使用之创建和查询&#xff08;二&#xff09; py2neo 创建操作 1、连接数据库 from py2neo import Graph graph Graph("bolt://100.100.20.55:7687", auth(user, pwd), nameneo4j)2、创建Node from py2neo import Node, Subgraph # 创建…

Elasticsearch面试内容整理-高级特性

Elasticsearch 提供了一系列高级特性,这些特性可以极大地增强其搜索、分析和管理能力,使得它在大数据场景中表现出色。以下是 Elasticsearch 的一些重要高级特性: 近实时搜索(Near Real-Time Search) Elasticsearch 的一个关键特性是 近实时搜索(NRT),这意味着数据写入…

算法专题十一: 基础递归

目录 1. 汉诺塔2. 合并两个有序链表3. 反转链表4. 两两交换链表中的节点5. Pow(x, n) 1. 汉诺塔 题目链接&#xff1a; Leetcode汉诺塔 算法原理&#xff1a; 递归&#xff1a;宏观视角理解递归 本道题为什么能用递归&#xff1f; 让我们逐一分析 首先思考我们如何来解决汉诺…

Cmakelist.txt之win-c-udp-client

1.cmakelist.txt cmake_minimum_required(VERSION 3.16) ​ project(c_udp_client LANGUAGES C) ​ add_executable(c_udp_client main.c) ​ target_link_libraries(c_udp_client wsock32) ​ ​ include(GNUInstallDirs) install(TARGETS c_udp_clientLIBRARY DESTINATION $…

Git错误:gnutls_handshake() failed: The TLS connection was non-properly terminated

最终我通过这个博客解决了问题&#xff1a;解决Git错误&#xff1a;gnutls_handshake() failed: The TLS connection was non-properly terminated 解决方案 1. 检查网络连接 首先&#xff0c;确保你的网络连接是稳定的。尝试访问其他HTTPS网站或服务&#xff0c;以排除网络问…

用Python做一个websocket服务端

我对websocket服务端的功能定义是&#xff1a; 1.能将client端的软硬件信息关联&#xff08;如client_name和对应ip:port&#xff09;&#xff0c;且不支持重复关联; 2.可以判断接收自client端的消息属于哪种任务&#xff0c;并对应执行&#xff08;如关联、发消息&#xff0…