【EasyExcel】Excel工具类2.0

发布于:2025-09-05 ⋅ 阅读:(15) ⋅ 点赞:(0)

目录

工具类 EasyExcelUtils

表头、内容策略 ExcelStyleStrategy

列宽自适应策略 ExcelWidthStyleStrategy


工具类 EasyExcelUtils

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

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

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 随笔


网站公告

今日签到

点亮在社区的每一天
去签到