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

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. 使用单元格内容设置的列宽

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

相关文章:

Easyexcel(5-自定义列宽)

相关文章链接 Easyexcel&#xff08;1-注解使用&#xff09;Easyexcel&#xff08;2-文件读取&#xff09;Easyexcel&#xff08;3-文件导出&#xff09;Easyexcel&#xff08;4-模板文件&#xff09;Easyexcel&#xff08;5-自定义列宽&#xff09; 注解 ColumnWidth Data…...

操作系统实验 C++实现死锁检测算法

实验目的 模拟实现死锁检测算法 实验内容 1、 输入&#xff1a; “资源分配表”文件&#xff0c;每一行包含资源编号、进程编号两项&#xff08;均用整数表示&#xff0c;并用空格分隔开&#xff09;&#xff0c;记录资源分配给了哪个进程。 “进程等待表”文件&…...

小鹏汽车智慧材料数据库系统项目总成数据同步

1、定时任务处理 2、提供了接口 小鹏方面提供的推送的数据表结构&#xff1a; 这几个表总数为100多万&#xff0c;经过条件筛选过滤后大概2万多条数据 小鹏的人给的示例图&#xff1a; 界面&#xff1a; SQL: -- 查询车型 select bmm.md_material_id, bmm.material_num, bm…...

1、HCIP之RSTP协议与STP相关安全配置

目录 RSTP—快速生成树协议 STP STP的缺点&#xff1a; STP的选举&#xff08;Listening状态中&#xff09;&#xff1a; RSTP P/A&#xff08;提议/同意&#xff09;机制 同步机制&#xff1a; 边缘端口的配置&#xff1a; RSTP的端口角色划分&#xff1a; ensp模拟…...

Linux云服务器docker使用教程

诸神缄默不语-个人CSDN博文目录 我用的是腾讯云服务器&#xff0c;操作系统是OpenCloudOS 9&#xff0c;基本上可以当特色版CentOS用。 docker安装跟各个系统关系太大了&#xff0c;我就不写了。OpenCloudOS 9安装docker见这篇博文&#xff1a;腾讯云服务器使用教程 文章目录 …...

如何从android的webview 取得页面上的数据

要从Android的WebView中获取页面上的数据&#xff0c;通常有几种常见的方法&#xff1a; JavaScript Interface&#xff1a;通过JavaScript和Android Interface进行通信。这种方法允许你在JavaScript中调用Android的方法&#xff0c;反之亦然。 Evaluate JavaScript&#xff…...

VTK知识学习(12)- 读取PNG图像

1、代码 private void ShowPngImage(){vtkPNGReader pngReader vtkPNGReader.New();pngReader.SetFileName("D:\\图像\\boxes\\cardboard_boxes_01.png");pngReader.Update();vtkImageActor imageActor vtkImageActor.New();imageActor.SetInputData(pngReader.Get…...

Springboot项目搭建(3)-更改用户信息与文件上传

1.概要 前一章节完成了用户信息的注册、登录、详细信息查询&#xff0c;以及线程池与拦截器技术。 这一章完善了用户信息更新/更改功能&#xff0c;包括昵称、邮箱、头像、密码等... 而后接触到了本地上传和云上传&#xff0c;其二者区别&#xff1a; 选择本地上传还是云上…...

Docker1:认识docker、在Linux中安装docker

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…...

python成绩分级 2024年6月python二级真题 青少年编程电子学会编程等级考试python二级真题解析

目录 python成绩分级 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序代码 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python成绩分级 2024年6月 python编程等级考试二级编程题 一、题目要求 …...

android 如何获取当前 Activity 的类名和包名

其一&#xff1a;getClass().getSimpleName() public static String getTopActivity(Context context){ ActivityManager am (ActivityManager) context.getSystemService(context.ACTIVITY_SERVICE); ComponentName cn am.getRunningTasks(1).get(0).topAct…...

Spring Boot 项目 myblog 整理

myblog 项目是一个典型的 Spring Boot 项目&#xff0c;主要包括用户注册、登录、文章管理&#xff08;创建、查询、更新、删除&#xff09;等功能。 1. 项目结构与依赖设置 项目初始化与依赖 使用 Spring Initializr 创建项目。引入必要的依赖包&#xff1a; Spring Boot W…...

uniapp 城市选择插件

uniapp城市选择插件 如上图 地址 完整demo <template><view><city-selectcityClick"cityClick":formatName"formatName":activeCity"activeCity":hotCity"hotCity":obtainCitys"obtainCitys":isSearch&quo…...

测试工程师如何在面试中脱颖而出

目录 1.平时工作中是怎么去测的&#xff1f; 2.B/S架构和C/S架构区别 3.B/S架构的系统从哪些点去测&#xff1f; 4.你为什么能够做测试这一行&#xff1f;&#xff08;根据个人情况分析理解&#xff09; 5.你认为测试的目的是什么&#xff1f; 6.软件测试的流程&#xff…...

Mesh路由组网

Mesh无线网格网络&#xff0c;多跳&#xff08;multi-hop&#xff09;网络&#xff0c;为解决全屋覆盖信号&#xff0c;一般用于家庭网络和小型企业 原理 网关路由器&#xff08;主路由&#xff0c;连接光猫&#xff09;&#xff0c;Mesh路由器&#xff08;子路由&#xff0c;…...

LeetCode131:分割回文串

题目链接&#xff1a;131. 分割回文串 - 力扣&#xff08;LeetCode&#xff09; 代码如下&#xff1a; class Solution { private:vector<vector<string>> result;vector<string> path; // 放已经回文的子串void backtracking (const string& s, int s…...

详细解析 devmem 命令:在 Linux 系统中直接访问内存的利器

目录 什么是 devmem&#xff1f;为什么需要 devmem&#xff1f;devmem 命令的基本语法devmem 在硬件调试中的应用安全性与风险devmem 的常见应用示例结论 在嵌入式系统开发和硬件调试中&#xff0c;开发者经常需要直接与硬件打交道&#xff0c;访问和修改内存中某些特定区域的内…...

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时&#xff0c;突然发现它的一个接口&#xff0c;被另一个服务ip频繁的请求。 按理说&#xff0c;之前设置的是&#xff0c;每隔1分钟请求一次接口。但从日志来看&#xff0c;则是1秒钟请求一次&#xff…...

【前端知识】nodejs项目配置package.json深入解读

package.json详细解读 文件解读一、文件结构二、字段详解三、使用场景四、注意事项 组件版本匹配规则 文件解读 package.json 文件是 Node.js 项目中的一个核心配置文件&#xff0c;它位于项目的根目录下&#xff0c;并包含项目的基本信息、依赖关系、脚本、版本等内容。以下是…...

XGBOOST算法Python实现(保姆级)

摘要 XGBoost算法&#xff08;eXtreme Gradient Boosting&#xff09;在目前的Kaggle、数学建模和大数据应用等竞赛中非常流行。本文将会从XGBOOST算法原理、Python实现、敏感性分析和实际应用进行详细说明。 目录 0 绪论 一、材料准备 二、算法原理 三、算法Python实现 3…...

JDK、MAVEN与IDEA的安装与配置

1.认识JDK、MAVEN与IDEA JDK 提供了编译和运行Java程序的基本环境。Maven 帮助管理项目的构建和依赖。IDEA 提供了一个强大的开发环境&#xff0c;使得编写、调试和运行Java程序更加高效。 2. 安装与环境配置 2.1 官网地址 选择你需要的版本下载&#xff1a; MAVEN下载传送…...

输出比较简介

输出比较简介 主要是用来输出PWM波形&#xff0c;这个波形是驱动电机的&#xff08;智能车和机器人等&#xff09;必要条件 OC&#xff08;Output Compare&#xff09;输出比较&#xff0c;还有IC&#xff0c;全称是Input Capture&#xff0c;意为输入捕获&#xff0c;还有CC…...

什么是反向 DNS 查找以及它的作用是什么?

反向DNS查询&#xff08;rDNS&#xff09;是一种技术&#xff0c;用于确定与某个IP地址对应的域名。当我们对一个IP地址进行反向DNS查询时&#xff0c;实际上是向域名系统&#xff08;DNS&#xff09;的特殊部分请求信息&#xff0c;这部分被称为PTR记录。PTR记录会返回与这个I…...

集群聊天服务器(13)redis环境安装和发布订阅命令

目录 环境安装订阅redis发布-订阅的客户端编程环境配置客户端编程 功能测试 环境安装 sudo apt-get install redis-server 先启动redis服务 /etc/init.d/redis-server start默认在6379端口上 redis是存键值对的&#xff0c;还可以存链表、数组等等复杂数据结构 而且数据是在…...

[ubuntu]编译共享内存读取出现read.c:(.text+0x1a): undefined reference to `shm_open‘问题解决方案

问题log /tmp/ccByifPx.o: In function main: read.c:(.text0x1a): undefined reference to shm_open read.c:(.text0xd9): undefined reference to shm_unlink collect2: error: ld returned 1 exit status 程序代码 #include <stdio.h> #include <stdlib.h> #…...

Python Matplotlib 安装指南:使用 Miniconda 实现跨 Linux、macOS 和 Windows 平台安装

Python Matplotlib 安装指南&#xff1a;使用 Miniconda 实现跨 Linux、macOS 和 Windows 平台安装 Matplotlib是Python最常用的数据可视化工具之一&#xff0c;结合Miniconda可以轻松管理安装和依赖项。在这篇文章中&#xff0c;我们将详细介绍如何使用Miniconda在Linux、mac…...

DimensionX 部署笔记

目录 生成视频用CogVideoX-5b-I2V 推理代码&#xff1a; DimensionX 生成视频用CogVideoX-5b-I2V 推理代码&#xff1a; 可以生成&#xff0c;从左向右旋转的&#xff0c;也可以生成从上往下旋转的&#xff1a; import torch from diffusers import CogVideoXImageToVideo…...

django从入门到精通(五)——表单与模型

好的&#xff0c;下面将详细介绍 Django 的表单与模型&#xff0c;包括它们的定义、使用、如何在 Django Admin 中结合使用&#xff0c;以及相关的字段类型和验证机制。 Django 模型与表单 1. Django 模型 Django 模型是一个 Python 类&#xff0c;用于定义数据库中的数据结…...

C语言Day 03 学习总结

Day 03 学习总结 流程控制语句 顺序结构 程序从上到下依次执行。每一条语句顺序执行&#xff0c;直到结束。 选择结构 程序根据条件选择执行某一条分支。包括 if-else 和 switch-case。 循环结构 程序反复执行某段代码。包括 for、while、do-while。 跳转结构 控制程序直接跳…...

kafka中是如何快速定位到一个offset的

定位到具体的segment日志文件&#xff0c;采用二分法先定位到index索引文件计算查找的offset在日志文件的相对偏移量 1、分区和日志段&#xff1a; 每个主题的分区&#xff08;Partition&#xff09;被划分为多个日志段&#xff08;Log Segment&#xff09;。每个日志段是一个…...