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

相关推荐
科技新资讯1 天前
AI如何批量处理Excel文件? 从数据合并、清洗到自动生成报表,看看 AI Agent 怎么完成任务
大数据·人工智能·excel
用户0332126663671 天前
使用 Python 在 Excel 中添加与删除筛选器
python·excel
xurime1 天前
Excelize 开源基础库发布 2.11.1 版本更新
数据分析·excel·开源软件·excelize·gitcode
梦想出海-Phoebe1 天前
Gemini新增文件编辑功能:PDF、Word、Excel处理体验分享
pdf·word·excel
Data-Miner2 天前
AI和Excel怎么结合才能真提效
人工智能·excel
taller_20003 天前
【012】数据类型入门: Excel 数据到 Python 值的转换
python·excel·pie·py
彦5 天前
Excel实用技巧笔记
excel
Logic1015 天前
Excel流程控制if函数,IF+数组轻松解决复杂判断问题
excel·流程控制·条件判断·if·excel函数·if函数·数组公式
跨境猫小妹6 天前
跨境电商订单导出CSV用Excel打开后订单号变成科学计数法如何定位并修复
excel·跨境电商·营销策略
weixin_440401696 天前
大数据技术-数据分析(EXcel+Python数据处理+SQL)
大数据·python·数据分析·excel