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 {
    @Override
    protected 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;
    }
    @Override
    protected 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);
    @Override
    protected 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时则设置为255
        if (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 是否为表头
     */
    @Override
    protected 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();
    }
}
运行结果
- 使用表头设置的列宽

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


Easyexcel(5-自定义列宽)的更多相关文章
- NPOI自适应列宽
		当本地没有安装Excel,但是又想导出Excel,采用Office插件是行不通的,NPOI是导出Excel的一个开源的插件.在导出Excel后,为了方便阅读,可以才采用自适应列宽的方式使得单元格的宽度 ... 
- JQuery 表格拖动调整列宽效果
		类似于桌面程序中的表格拖动表头的效果,当鼠标停留在表头边框线上时,鼠标会变成表示左右拖动的形状,接着拖动鼠标,会在表格中出现一条随鼠标移动的竖线,最后放开鼠标,表格列宽会被调整.最近比较空闲,便自己动 ... 
- QTableView表格视图的列宽设置
		Qt中的表格控件可以通过从QTableView或QTableWidget派生子类实现.其中,QTableWidget只是对QTableView的一种简单封装.因为使用QTableView常常需要用户指 ... 
- MS WORD 表格自动调整列宽,自动变漂亮,根据内容自动调整 .
		在MS WORD中,当有大量的表格出现时,调整每个表格的的高和宽和大小将是一件非常累的事情,拖来拖去,非常耗时间,而且当WORD文档达到300页以上时,调整反应非常的慢,每次拖拉线后,需要等待一段时间 ... 
- (几乎)完美实现 el-table 列宽自适应
		背景 Element UI 是 PC 端比较流行的 Vue.js UI 框架,它的组件库基本能满足大部分常见的业务需求.但有时候会有一些定制性比较高的需求,组件本身可能没办法满足.最近在项目里就碰到了 ... 
- 修改yapf中的列宽限制值
		yapf是一款由Google开源的Python代码自动格式化工具,它根据PEP 8规范可以帮我们自动格式化我们的代码,让代码更规范.更漂亮.但是其中最大列宽被限制为80,如果超过80,在格式化时就会被 ... 
- Asp.net 设置GridView自适应列宽不变形
		动态绑定的GridView由于列数不固定,而列又太多,这样设置GridView固定宽度就不能满足需求了.为此整理了两种方法来达到GridView自适应列宽不变形的效果. //在GridView的行数据 ... 
- java表格操作之设置表格列宽
		设置所有列的宽度 /** * 设置所有列的列宽 * @param table * @param width */ public void setAllColumnWidth(JTable table, ... 
- column css3 列宽
		column-count 属性规定元素应该被分隔的列数: div { -moz-column-count:3; /* Firefox */ -webkit-column-count:3; /* Saf ... 
- [转]DevExpress.XtraGrid.GridControl gridView自动列宽代码
		gridView1.OptionsView.ColumnAutoWidth = false; for (int I = 0; I < gridView1.Columns.Count; I++ ... 
随机推荐
- 【NAS】绿联NAS+极狐Gitlab+1Panel
			1. 准备域名 例如我的 ???.mllt.cc 2. 内网穿透 我使用的Natfrp(https://www.natfrp.com/tunnel/) 创建HTTP隧道(对应端口10080)创建HTT ... 
- go编译可以指定os和arch
			是的,Go 编译器支持通过环境变量来指定目标操作系统(OS)和架构(Arch).这允许你为不同的平台交叉编译 Go 程序.你可以使用 GOOS 和 GOARCH 环境变量来指定目标系统. 例如,如果你 ... 
- 全网最详细的 tcpdump 使用指南
			https://www.cnblogs.com/wongbingming/p/13212306.html 今天要给大家介绍的一个 Unix 下的一个 网络数据采集分析工具,也就是我们常说的抓包工具. ... 
- 盘点5个常用的.Net依赖注入框架!
			盘点5个常用的依赖注入框架,特别是前面2个. 1.Microsoft.Extensions.DependencyInjection 这是.Net Core框架本身内置集成的,我们只需引入Microso ... 
- Qt音视频开发29-Onvif云台控制
			一.前言 云台控制也是onvif功能中最常用的,最常用的功能排第一的是拿到视频流地址,排第二的就是云台控制了,云台控制的含义就是对带云台的摄像机进行上下左右的移动,一般云台摄像机都是带有一个小电机,一 ... 
- Qt音视频开发9-ffmpeg录像存储
			一.前言 上一篇文章写道直接将视频流保存裸流到文件,尽管裸流文件有一定的好处,但是 毕竟大部分用户需要的不是裸流而是MP4视频文件,所以需要将视频流保存成MP4文件,毕竟电脑上的播放器包括默认的播放器 ... 
- Transmission安装及更换官方UI
			相关链接地址: Transmission镜像地址 Transmission 浏览器管理界面:Transmission Web Control UI. 创建容器 docker-compose.yaml ... 
- Spring+MyBatis企业应用实战(第二版)2018-电子书+源码+SQL脚本
			Spring+MyBatis企业应用实战(第二版)2018学习资料: 电子书: 链接:https://pan.baidu.com/s/1yAdlA5F_HuZMbO4who5jVw 提取码:58yz ... 
- IM消息ID技术专题(六):深度解密滴滴的高性能ID生成器(Tinyid)
			1.引言 在中大型IM系统中,聊天消息的唯一ID生成策略是个很重要的技术点.不夸张的说,聊天消息ID贯穿了整个聊天生命周期的几乎每一个算法.逻辑和过程,ID生成策略的好坏有可能直接决定系统在某些技术点 ... 
- Python 潮流周刊#84:2024 年 Python 的最佳实践(摘要)
			本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ... 
