【EasyExcel】Excel工具类2.0

目录

[工具类 EasyExcelUtils](#工具类 EasyExcelUtils)

[表头、内容策略 ExcelStyleStrategy](#表头、内容策略 ExcelStyleStrategy)

[列宽自适应策略 ExcelWidthStyleStrategy](#列宽自适应策略 ExcelWidthStyleStrategy)


工具类 EasyExcelUtils

java 复制代码
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.leslie.common.utils.poi.excelStrategy.ExcelStyleStrategy;
import com.leslie.common.utils.poi.excelStrategy.ExcelWidthStyleStrategy;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * EasyExcel工具类
 *
 * @author Leslie Lee
 * @TIME 1956/09/12
 * @version 2003/04/01
 */
public class EasyExcelUtils {

    /**
     * 导出数据到Excel,自适应列宽
     * 浏览器直接下载文件
     *
     * @param response  response
     * @param fileName  导出文件名称
     * @param sheetName 文件sheet名称
     * @param clazz     导出数据对应实体
     * @param list      导出数据集合
     * @throws Exception 异常信息
     */
    public static void downloadExcel(HttpServletResponse response, String fileName, String sheetName, Class<?> clazz, List<?> list) throws Exception {
        EasyExcel.write(getServletOutputStream(response, fileName), clazz)
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .sheet(sheetName)
                .doWrite(list);
    }

    /**
     * 导出数据到Excel
     * 自适应列宽
     * 多sheet导出
     * sheetNames、lists 数量必须一致
     * 浏览器直接下载文件
     *
     * @param response   response
     * @param fileName   导出文件名称
     * @param sheetNames 文件sheet名称,例:new String[]{"测试sheet1","测试sheet2"}
     * @param clazz      导出数据对应实体
     * @param lists      导出数据集合
     * @throws Exception 异常信息
     */
    public static void downloadExcel(HttpServletResponse response, String fileName, String[] sheetNames, Class<?> clazz, List<?>... lists) throws Exception {
        if (sheetNames.length != lists.length)
            throw new IllegalArgumentException("sheetNames、lists 数量不一致");
        try (ExcelWriter excelWriter = EasyExcel.write(getServletOutputStream(response, fileName), clazz)
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .build()) {
            for (int i = 0; i < sheetNames.length; i++) {
                WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames[i])
                        .build();
                excelWriter.write(lists[i], writeSheet);
            }
        }
    }

    /**
     * 导出数据到Excel
     * 自适应列宽
     * 多sheet,多表头导出
     * sheetNames、lists 数量必须一致
     * 浏览器直接下载文件
     *
     * @param response   response
     * @param fileName   导出文件名称
     * @param sheetNames 文件sheet名称,例:new String[]{"测试sheet1","测试sheet2"}
     * @param clazz      导出数据对应实体,例:new Class[]{"测试class1","测试class2"}
     * @param lists      导出数据集合
     * @throws Exception 异常信息
     */
    public static void downloadExcel(HttpServletResponse response, String fileName, String[] sheetNames, Class<?>[] clazz, List<?>... lists) throws Exception {
        if (sheetNames.length != lists.length || sheetNames.length != clazz.length)
            throw new IllegalArgumentException("sheetNames、clazz、lists 数量不一致");
        try (ExcelWriter excelWriter = EasyExcel.write(getServletOutputStream(response, fileName))
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .build()) {
            for (int i = 0; i < sheetNames.length; i++) {
                WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames[i])
                        .head(clazz[i])
                        .build();
                excelWriter.write(lists[i], writeSheet);
            }
        }
    }

    /**
     * 导出数据到Excel
     * 自适应列宽
     * 默认表头、内容样式
     * 浏览器直接下载文件
     *
     * @param response  response
     * @param fileName  导出文件名称
     * @param sheetName 文件sheet名称
     * @param clazz     导出数据对应实体
     * @param list      导出数据集合
     * @throws Exception 异常信息
     */
    public static void downloadExcelDefaultStyle(HttpServletResponse response, String fileName, String sheetName, Class<?> clazz, List<?> list) throws Exception {
        EasyExcel.write(getServletOutputStream(response, fileName), clazz)
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .registerWriteHandler(ExcelStyleStrategy.getHorizontalCellStyleStrategyDefault())
                .sheet(sheetName)
                .doWrite(list);
    }

    /**
     * 导出数据到Excel
     * 自适应列宽
     * 默认表头、内容样式
     * 多sheet导出
     * sheetNames、lists 数量必须一致
     * 浏览器直接下载文件
     *
     * @param response   response
     * @param fileName   导出文件名称
     * @param sheetNames 文件sheet名称
     * @param clazz      导出数据对应实体
     * @param lists      导出数据集合
     * @throws Exception 异常信息
     */
    public static void downloadExcelDefaultStyle(HttpServletResponse response, String fileName, String[] sheetNames, Class<?> clazz, List<?>... lists) throws Exception {
        if (sheetNames.length != lists.length)
            throw new IllegalArgumentException("sheetNames、lists 数量不一致");
        try (ExcelWriter excelWriter = EasyExcel.write(getServletOutputStream(response, fileName), clazz)
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .registerWriteHandler(ExcelStyleStrategy.getHorizontalCellStyleStrategyDefault())
                .build()) {
            for (int i = 0; i < sheetNames.length; i++) {
                WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames[i])
                        .build();
                excelWriter.write(lists[i], writeSheet);
            }
        }
    }

    /**
     * 导出数据到Excel
     * 自适应列宽
     * 自定义表头、内容样式
     * 浏览器直接下载文件
     *
     * @param response                   response
     * @param fileName                   导出文件名称
     * @param sheetName                  文件sheet名称
     * @param clazz                      导出数据对应实体
     * @param list                       导出数据集合
     * @param headIndexedColors          表头背景颜色
     * @param contentIndexedColors       内容背景颜色
     * @param fontName                   统一字体名称
     * @param headFontSize               表头字体大小
     * @param contentFontSize            内容字体大小
     * @param headBold                   表头是否字体加粗
     * @param contentBold                内容是否字体加粗
     * @param borderStyle                边框样式,例:粗细,点状等
     * @param wrapped                    是否自动换行
     * @param headHorizontalAlignment    表头水平对齐方式
     * @param headVerticalAlignment      表头垂直对齐方式
     * @param contentHorizontalAlignment 内容水平对齐方式
     * @param contentVerticalAlignment   内容垂直对齐方式
     * @param shrinkToFit                是否自适应收缩
     * @throws Exception 异常信息
     */
    public static void downloadExcelCustomizeStyle(HttpServletResponse response, String fileName, String sheetName, Class<?> clazz, List<?> list, short headIndexedColors,
                                                   short contentIndexedColors, String fontName, short headFontSize, short contentFontSize, boolean headBold, boolean contentBold,
                                                   BorderStyle borderStyle, boolean wrapped, HorizontalAlignment headHorizontalAlignment, VerticalAlignment headVerticalAlignment,
                                                   HorizontalAlignment contentHorizontalAlignment, VerticalAlignment contentVerticalAlignment, boolean shrinkToFit) throws Exception {
        EasyExcel.write(getServletOutputStream(response, fileName), clazz)
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .registerWriteHandler(ExcelStyleStrategy.getHorizontalCellStyleStrategyCustomize(headIndexedColors, contentIndexedColors, fontName, headFontSize, contentFontSize,
                        headBold, contentBold, borderStyle, wrapped, headHorizontalAlignment, headVerticalAlignment, contentHorizontalAlignment, contentVerticalAlignment, shrinkToFit))
                .sheet(sheetName)
                .doWrite(list);
    }

    /**
     * 导出数据到Excel
     * 自适应列宽
     * 自定义表头、内容样式
     * 多sheet、多表头导出
     * sheetNames、clazz、lists 数量必须一致
     * 浏览器直接下载文件
     *
     * @param response                   response
     * @param fileName                   导出文件名称
     * @param sheetNames                 文件sheet名称
     * @param clazz                      导出数据对应实体
     * @param lists                      导出数据集合
     * @param headIndexedColors          表头背景颜色
     * @param contentIndexedColors       内容背景颜色
     * @param fontName                   统一字体名称
     * @param headFontSize               表头字体大小
     * @param contentFontSize            内容字体大小
     * @param headBold                   表头是否字体加粗
     * @param contentBold                内容是否字体加粗
     * @param borderStyle                边框样式,例:粗细,点状等
     * @param wrapped                    是否自动换行
     * @param headHorizontalAlignment    表头水平对齐方式
     * @param headVerticalAlignment      表头垂直对齐方式
     * @param contentHorizontalAlignment 内容水平对齐方式
     * @param contentVerticalAlignment   内容垂直对齐方式
     * @param shrinkToFit                是否自适应收缩
     * @throws Exception 异常信息
     */
    public static void downloadExcelCustomizeStyle(HttpServletResponse response, String fileName, String[] sheetNames, Class<?>[] clazz, short headIndexedColors,
                                                   short contentIndexedColors, String fontName, short headFontSize, short contentFontSize, boolean headBold, boolean contentBold,
                                                   BorderStyle borderStyle, boolean wrapped, HorizontalAlignment headHorizontalAlignment, VerticalAlignment headVerticalAlignment,
                                                   HorizontalAlignment contentHorizontalAlignment, VerticalAlignment contentVerticalAlignment, boolean shrinkToFit, List<?>... lists) throws Exception {
        if (sheetNames.length != lists.length || sheetNames.length != clazz.length)
            throw new IllegalArgumentException("sheetNames、clazz、lists 数量不一致");
        try (ExcelWriter excelWriter = EasyExcel.write(getServletOutputStream(response, fileName))
                .registerWriteHandler(new ExcelWidthStyleStrategy())
                .registerWriteHandler(ExcelStyleStrategy.getHorizontalCellStyleStrategyCustomize(headIndexedColors, contentIndexedColors, fontName, headFontSize, contentFontSize,
                        headBold, contentBold, borderStyle, wrapped, headHorizontalAlignment, headVerticalAlignment, contentHorizontalAlignment, contentVerticalAlignment, shrinkToFit))
                .build()) {
            for (int i = 0; i < sheetNames.length; i++) {
                WriteSheet writeSheet = EasyExcel.writerSheet(i, sheetNames[i])
                        .head(clazz[i])
                        .build();
                excelWriter.write(lists[i], writeSheet);
            }
        }
    }

    /**
     * 设置导出文件名及编码
     *
     * @param response response
     * @param fileName 文件名
     * @return ServletOutputStream
     * @throws IOException 异常信息
     */
    private static ServletOutputStream getServletOutputStream(HttpServletResponse response, String fileName) throws IOException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String newFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + newFileName + ".xlsx");
        return response.getOutputStream();
    }

}

表头、内容策略 ExcelStyleStrategy

java 复制代码
import com.alibaba.excel.metadata.data.DataFormatData;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import org.apache.poi.ss.usermodel.*;

/**
 * 表头、内容样式
 *
 * @author Leslie Lee
 * @TIME 1956/09/12
 * @version 2003/04/01
 */
public class ExcelStyleStrategy {

    /**
     * 表头样式
     * 背景:天蓝色
     * 字体:宋体,(short) 12,加粗
     * 边框:粗细1
     * 内容:自动换行,整体居中,文本自适应收缩
     *
     * @return WriteCellStyle
     */
    public static WriteCellStyle getHeadStyle() {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("宋体");//设置字体名字
        headWriteFont.setFontHeightInPoints((short) 12);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;

        // 样式
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
        headWriteCellStyle.setWrapped(true);  //设置自动换行;
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适
        return headWriteCellStyle;
    }

    /**
     * 表头样式
     *
     * @param indexedColors       背景颜色
     * @param fontName            字体名称,例:宋体
     * @param fontSize            字体大小,例:(short) 12
     * @param bold                字体是否加粗
     * @param borderStyle         边框样式,例:粗细,点状等
     * @param wrapped             是否自动换行
     * @param horizontalAlignment 文本水平对齐方式
     * @param verticalAlignment   文本垂直对齐方式
     * @param shrinkToFit         文本是否自动收缩
     * @return WriteCellStyle
     */
    public static WriteCellStyle getHeadStyle(short indexedColors, String fontName, short fontSize, boolean bold, BorderStyle borderStyle,
                                              boolean wrapped, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, boolean shrinkToFit) {
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
        headWriteCellStyle.setFillForegroundColor(indexedColors);
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName(fontName);//设置字体名字
        headWriteFont.setFontHeightInPoints(fontSize);//设置字体大小
        headWriteFont.setBold(bold);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;

        // 样式
        headWriteCellStyle.setBorderBottom(borderStyle);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(borderStyle);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(borderStyle);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(borderStyle);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
        headWriteCellStyle.setWrapped(wrapped);  //设置自动换行;
        headWriteCellStyle.setHorizontalAlignment(horizontalAlignment);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(verticalAlignment);  //设置垂直对齐的样式为居中对齐;
        headWriteCellStyle.setShrinkToFit(shrinkToFit);//设置文本收缩至合适
        return headWriteCellStyle;
    }

    /**
     * 内容样式
     * 背景:默认
     * 字体:宋体,(short)9,粗细1
     * 内容:整体居中,自动换行,文本自适应收缩
     *
     * @return WriteCellStyle
     */
    public static WriteCellStyle getContentStyle() {
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        // 设置字体
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontName("宋体"); //设置字体名字
        contentWriteFont.setFontHeightInPoints((short) 9);//设置字体大小
        contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;

        //设置样式;
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;

        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 水平居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        contentWriteCellStyle.setWrapped(true); //设置自动换行;
        DataFormatData dataFormatData = new DataFormatData();
        dataFormatData.setIndex((short) 49);
        contentWriteCellStyle.setDataFormatData(dataFormatData);//设置单元格格式是:文本格式,方式长数字文本科学计数法
        contentWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return contentWriteCellStyle;
    }

    /**
     * 内容样式
     *
     * @param indexedColors       背景颜色
     * @param fontName            字体名称,例:宋体
     * @param fontSize            字体大小,例:(short) 12
     * @param bold                字体是否加粗
     * @param borderStyle         边框样式,例:粗细,点状等
     * @param wrapped             是否自动换行
     * @param horizontalAlignment 文本水平对齐方式
     * @param verticalAlignment   文本垂直对齐方式
     * @param shrinkToFit         文本是否自动收缩
     * @return WriteCellStyle
     */
    public static WriteCellStyle getContentStyle(short indexedColors, String fontName, short fontSize, boolean bold, BorderStyle borderStyle,
                                                 boolean wrapped, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, boolean shrinkToFit) {
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        // 背景绿色
        contentWriteCellStyle.setFillForegroundColor(indexedColors);
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定

        // 设置字体
        WriteFont contentWriteFont = new WriteFont();
        contentWriteFont.setFontName(fontName); //设置字体名字
        contentWriteFont.setFontHeightInPoints(fontSize);//设置字体大小
        contentWriteFont.setBold(bold);//字体加粗
        contentWriteCellStyle.setWriteFont(contentWriteFont);//在样式用应用设置的字体;

        //设置样式;
        contentWriteCellStyle.setBorderBottom(borderStyle);//设置底边框;
        contentWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        contentWriteCellStyle.setBorderLeft(borderStyle);  //设置左边框;
        contentWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        contentWriteCellStyle.setBorderRight(borderStyle);//设置右边框;
        contentWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        contentWriteCellStyle.setBorderTop(borderStyle);//设置顶边框;
        contentWriteCellStyle.setTopBorderColor((short) 0); ///设置顶边框颜色;

        contentWriteCellStyle.setHorizontalAlignment(horizontalAlignment);// 水平居中
        contentWriteCellStyle.setVerticalAlignment(verticalAlignment);// 垂直居中
        contentWriteCellStyle.setWrapped(wrapped); //设置自动换行;
        DataFormatData dataFormatData = new DataFormatData();
        dataFormatData.setIndex((short) 49);
        contentWriteCellStyle.setDataFormatData(dataFormatData);//设置单元格格式是:文本格式,方式长数字文本科学计数法
        contentWriteCellStyle.setShrinkToFit(shrinkToFit);//设置文本收缩至合适

        return contentWriteCellStyle;
    }

    /**
     * 获取默认表头、内容样式
     *
     * @return HorizontalCellStyleStrategy
     */
    public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategyDefault() {
        return new HorizontalCellStyleStrategy(getHeadStyle(), getContentStyle());
    }

    /**
     * 自定义表头、内容样式
     *
     * @param headIndexedColors          表头背景颜色
     * @param contentIndexedColors       内容背景颜色
     * @param fontName                   统一字体名称
     * @param headFontSize               表头字体大小
     * @param contentFontSize            内容字体大小
     * @param headBold                   表头是否字体加粗
     * @param contentBold                内容是否字体加粗
     * @param borderStyle                边框样式,例:粗细,点状等
     * @param wrapped                    是否自动换行
     * @param headHorizontalAlignment    表头水平对齐方式
     * @param headVerticalAlignment      表头垂直对齐方式
     * @param contentHorizontalAlignment 内容水平对齐方式
     * @param contentVerticalAlignment   内容垂直对齐方式
     * @param shrinkToFit                是否自适应收缩
     * @return HorizontalCellStyleStrategy
     */
    public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategyCustomize(short headIndexedColors, short contentIndexedColors, String fontName, short headFontSize, short contentFontSize, boolean headBold,
                                                                                      boolean contentBold, BorderStyle borderStyle, boolean wrapped, HorizontalAlignment headHorizontalAlignment,
                                                                                      VerticalAlignment headVerticalAlignment, HorizontalAlignment contentHorizontalAlignment, VerticalAlignment contentVerticalAlignment, boolean shrinkToFit) {
        return new HorizontalCellStyleStrategy(getHeadStyle(headIndexedColors, fontName, headFontSize, headBold, borderStyle, wrapped, headHorizontalAlignment, headVerticalAlignment, shrinkToFit),
                getContentStyle(contentIndexedColors, fontName, contentFontSize, contentBold, borderStyle, wrapped, contentHorizontalAlignment, contentVerticalAlignment, shrinkToFit));
    }
}

列宽自适应策略 ExcelWidthStyleStrategy

java 复制代码
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.CellData;
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.poi.ss.usermodel.Cell;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 自动列宽
 *
 * @Package_Name com.leslie.common.utils.poi
 * @Author Leslie Lee
 * @TIME 1956-09-12
 * @Version 2.0
 */
public class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
    // excel列宽不能超过 255 * 255,因为要留出一点间距,所以设置最大为254
    private static final int MAX_COLUMN_WIDTH = 254;
    private final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>(8);

    /**
     * 设置列宽
     *
     * @param writeSheetHolder 书写页架
     * @param cellDataList     单元格数据列表
     * @param cell             细胞
     * @param head             头
     * @param relativeRowIndex 相对行索引
     * @param isHead           是头
     */
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        boolean needSetWidth = isHead || !cellDataList.isEmpty();
        if (needSetWidth) {
            Map<Integer, Integer> maxColumnWidthMap = CACHE.computeIfAbsent(writeSheetHolder.getSheetNo(), k -> new HashMap<>(16));

            Integer columnWidth = this.dataLength(cellDataList, cell, isHead);
            if (columnWidth >= 0) {
                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);
                    // + 1 是为了让列的左右两边留出一点间距
                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), (columnWidth + 1) * 256);
                }
            }
        }
    }

    /**
     * 数据长度
     *
     * @param cellDataList 单元格数据列表
     * @param cell         细胞
     * @param isHead       是头
     * @return {@link Integer }
     */
    private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
        if (isHead) {
            return cell.getStringCellValue().getBytes().length;
        } else {
            CellData<?> cellData = cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();
            if (type == null) {
                return -1;
            } else {
                return switch (type) {
                    case STRING -> cellData.getStringValue().getBytes().length;
                    case BOOLEAN -> cellData.getBooleanValue().toString().getBytes().length;
                    case NUMBER -> cellData.getNumberValue().toString().getBytes().length;
                    default -> -1;
                };
            }
        }
    }

    public ExcelWidthStyleStrategy() {
    }

}

Leslie Lee 随笔

相关推荐
Oll Correct18 小时前
Excel基础操作(五)
笔记·excel
一晌小贪欢19 小时前
Python 操作 Excel 高阶技巧:用 openpyxl 玩转循环与 Decimal 精度控制
开发语言·python·excel·openpyxl·python办公·python读取excel
day day day ...20 小时前
easyExcel和poi分别处理不同标准的excel
java·服务器·excel
骆驼爱记录20 小时前
Word侧边页码设置全攻略
前端·自动化·word·excel·wps·新人首发
开开心心_Every2 天前
发票批量打印工具支持双面预览页面方向设置
游戏·微信·pdf·华为云·excel·语音识别·googlecloud
xinlianluohan2 天前
excel筛选背景颜色的值&拼接单元格&判断单元格是否含有中文
excel
骆驼爱记录2 天前
Word通配符技巧:高效文档处理指南
开发语言·c#·自动化·word·excel·wps·新人首发
AI刀刀2 天前
豆包怎么生成excel
ai·excel·豆包·deepseek·ds随心转
骆驼爱记录2 天前
Word表格题注自动设置全攻略
开发语言·c#·自动化·word·excel·wps·新人首发
天荒地老笑话么2 天前
Vim核心快捷键与运维实战指南
运维·vim·excel