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

相关推荐
喝汽水的猫^9 小时前
Java实现Excel 导出(多 Sheet、复杂格式)
java·excel
小费的部落12 小时前
Excel 在Sheet3中 匹配Sheet1的A列和Sheet2的A列并处理空内容
java·前端·excel
缺点内向13 小时前
如何在 C# 中重命名 Excel 工作表并设置标签颜色
开发语言·c#·excel
wtsolutions18 小时前
Sheet-to-Doc: Automate Document Generation with Excel Data and Word Templates
word·excel·wtsolutions
wtsolutions19 小时前
Sheet-to-Doc:用Excel数据和Word模板自动生成文档
excel·wps·wtsolutions
程序猿ZhangSir19 小时前
将数据库数据导出为Excel文件,并针对性的对部分数据做脱敏加密,常用方法解析
excel
哆啦A梦15882 天前
商城后台管理系统 03 Vue项目-实现表格导出EXCEL表格
前端·vue.js·excel
xingzhemengyou12 天前
python pandas操作excel
python·excel·pandas
小小心LOVE2 天前
Vue3 安装和使用 vue-office来实现 Word、Excel 和 PDF 文件的预览
vue.js·word·excel
cyhysr2 天前
oracle的model子句让sql像excel一样灵活2
sql·oracle·excel