【EasyExcel】根据单元格内容自动调整列宽

1.自定义Excel列宽样式策略类

import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.commons.collections.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 自定义Excel列宽样式策略类,用于根据单元格内容自动调整列宽。
 * 继承自 AbstractColumnWidthStyleStrategy 以提供列宽调整功能。
 */
public class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {

    // 定义单元格最大列宽,避免列宽过大
    private static final int MAX_COLUMN_WIDTH = 30;
    // 缓存每个sheet中每列的最大列宽
    private final Map<Integer, Map<Integer, Integer>> columnWidthCache = new HashMap<>(8);

    /**
     * 设置列宽的方法,根据单元格内容的长度动态调整列宽。
     *
     * @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) {

        // 如果是表头或者单元格数据列表不为空,则需要设置列宽
        boolean needSetWidth = isHead || !CollectionUtils.isEmpty(cellDataList);

        if (needSetWidth) {
            // 获取当前sheet的列宽缓存
            Map<Integer, Integer> columnWidthMap =
                    columnWidthCache.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>(16));

            // 计算当前单元格的数据长度
            Integer columnWidth = computeCellDataLength(cellDataList, cell, isHead);

            if (columnWidth >= 0) {
                // 确保列宽不会超过最大值
                columnWidth = Math.min(columnWidth, MAX_COLUMN_WIDTH);

                // 获取当前列的最大列宽
                Integer maxColumnWidth = columnWidthMap.get(cell.getColumnIndex());

                // 如果当前列宽大于缓存中的最大列宽,则更新缓存并设置列宽
                if (maxColumnWidth == null || columnWidth > maxColumnWidth) {
                    columnWidthMap.put(cell.getColumnIndex(), columnWidth);
                    // 设置列宽,乘以512是因为Excel中列宽单位与字符长度有关
                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 512);
                }
            }
        }
    }

    /**
     * 计算单元格内容的字节长度
     *
     * @param cellDataList 当前列的单元格数据列表
     * @param cell 当前单元格
     * @param isHead 是否为表头
     * @return 单元格内容的字节长度
     */
    private Integer computeCellDataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
        if (isHead) {
            // 表头直接计算字符串的字节长度
            return cell.getStringCellValue().getBytes().length;
        } else {
            if (cellDataList == null || cellDataList.isEmpty()) {
                return -1; // 如果数据列表为空,则返回-1
            }
            WriteCellData<?> cellData = cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();

            if (type == null) {
                return -1; // 如果类型未知,则返回-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; // 对于其他类型,返回-1
                }
            }
        }
    }
}

2.使用策略

        excelWriter.write(ExcelData, EasyExcel.writerSheet(sheetName)
                    .head(Product.class)
                    .registerWriteHandler(new ExcelWidthStyleStrategy())
                    .build());

相关推荐

  1. EasyExcel根据单元内容自动调整

    2024-07-14 17:00:02       19 阅读
  2. eazyexcel生成校验单元内容的excel文件

    2024-07-14 17:00:02       27 阅读
  3. EsayExcel读取合并单元

    2024-07-14 17:00:02       49 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-14 17:00:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-14 17:00:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-14 17:00:02       58 阅读
  4. Python语言-面向对象

    2024-07-14 17:00:02       69 阅读

热门阅读

  1. Redis 底层数据结构

    2024-07-14 17:00:02       21 阅读
  2. C# Static的一些理解

    2024-07-14 17:00:02       17 阅读
  3. 多线程编程中的条件变量及其优化

    2024-07-14 17:00:02       15 阅读
  4. STM32F103控制0.96寸OLED显示

    2024-07-14 17:00:02       15 阅读
  5. GESP C++ 三级真题(2023年9月)T1 ⼩ 杨储蓄

    2024-07-14 17:00:02       14 阅读
  6. 2024年交安安全员考试题库及答案

    2024-07-14 17:00:02       19 阅读
  7. 2024年高校辅导员考试题库及答案

    2024-07-14 17:00:02       25 阅读
  8. VMM、VMI、VIM的简介

    2024-07-14 17:00:02       16 阅读
  9. Python 面试热门问题五

    2024-07-14 17:00:02       22 阅读
  10. TCP流量控制是怎么实现的?

    2024-07-14 17:00:02       24 阅读
  11. C#开发翻译较好的API

    2024-07-14 17:00:02       19 阅读