欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java EasyExcel實(shí)現(xiàn)導(dǎo)出多sheet并設(shè)置單元格樣式

 更新時間:2023年11月10日 15:46:53   作者:penga  
EasyExcel是一個基于Java的、快速、簡潔、解決大文件內(nèi)存溢出的Excel處理工具,下面我們就來學(xué)習(xí)一下EasyExcel如何實(shí)現(xiàn)導(dǎo)出多sheet并設(shè)置單元格樣式吧

前言

最近在做項目時遇到了特殊的Excel導(dǎo)出需求,需要對不同sheet設(shè)置不同樣式,但網(wǎng)上找了很多方法都有問題。在經(jīng)歷一段時間的爬坑之后,終于解決,于是寫這篇文章把他分享出來。

EasyExcel簡介

EasyExcel是一個基于Java的、快速、簡潔、解決大文件內(nèi)存溢出的Excel處理工具。他能讓你在不用考慮性能、內(nèi)存的等因素的情況下,快速完成Excel的讀、寫等功能。也是目前比較常用的Excel處理工具。

關(guān)于如何讀取和寫入Excel文件,官網(wǎng)教程已經(jīng)很全面,這里不做過多贅述。

需求

假設(shè)我們遇到了這樣一個需求:

現(xiàn)在要導(dǎo)出一個數(shù)碼產(chǎn)品的報表,有手機(jī)和電腦兩大類,需要在表頭統(tǒng)計總價、均價、最高價、最低價,并需要按指標(biāo)對數(shù)據(jù)進(jìn)行特殊處理。

手機(jī):

  • 價格 > 5000,字體為紅色;
  • CPU 為 曉龍8 Gen3時,單元格高亮為黃色。

電腦:

  • 價格 > 10000,字體為紅色;
  • 顯卡為4090時,單元格高亮為藍(lán)色。

開始

導(dǎo)入依賴

SpringBoot 依賴自行導(dǎo)入

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>

<!-- hutool 工具集,為了構(gòu)造模擬數(shù)據(jù),具體項目請根據(jù)實(shí)際情況引入 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.22</version>
</dependency>

接口

注:為了閱讀簡潔,這里簡化了部分代碼

/**
 * 導(dǎo)出Excel 接口
 *
 * @param response
 */
@PostMapping("export")
public void exportExcel(HttpServletResponse response) {
    digitalProductService.exportExcel(response);
}

服務(wù)實(shí)現(xiàn)類

首先模擬一部分?jǐn)?shù)據(jù)

package com.penga.demo.service.impl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.penga.demo.service.IDigitalProductService;
import com.penga.demo.util.DigitalProductCellWriteHandler;
import com.penga.demo.util.EasyExcelUtils;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class DigitalProductServiceImpl implements IDigitalProductService {

    @Override
    public void exportExcel(HttpServletResponse response) {
        // 初始化多個sheet
        List<String> sheetNames = ListUtil.toList("手機(jī)", "電腦");
        // 初始化數(shù)據(jù)集
        List<List<List<Object>>> dataLists = getDatas();
        // 統(tǒng)計數(shù)據(jù)
        List<BigDecimal> phonePriceList = dataLists.get(0).stream().map(dl -> Convert.toBigDecimal(dl.get(3))).collect(Collectors.toList());
        List<BigDecimal> pcPriceList = dataLists.get(1).stream().map(dl -> Convert.toBigDecimal(dl.get(2))).collect(Collectors.toList());
        String phoneTotalHeader = getTotalHeader(phonePriceList);
        String pcTotalHeader = getTotalHeader(pcPriceList);
        // 初始化每個sheet里面的header
        List<List<List<String>>> headerLists = getHeaders(phoneTotalHeader, pcTotalHeader);
        EasyExcelUtils.writeExcelSheets(response, "數(shù)碼產(chǎn)品報表", sheetNames, headerLists, dataLists, new DigitalProductCellWriteHandler());
    }

    private List<List<List<String>>> getHeaders(String phoneTotalHeader, String pcTotalHeader) {
        String phoneTitle = "手機(jī)-統(tǒng)計報表";
        String pcTitle = "電腦-統(tǒng)計報表";
        List<List<List<String>>> headerLists = new ArrayList<>();
        List<List<String>> headerList1 = new ArrayList<>();
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "序號"));
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "型號"));
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "上市日期"));
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "價格"));
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "CPU"));
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "RAM容量"));
        headerList1.add(ListUtil.toList(phoneTitle, phoneTotalHeader, "ROM容量"));
        List<List<String>> headerList2 = new ArrayList<>();
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "序號"));
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "配置"));
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "價格"));
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "CPU"));
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "顯卡"));
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "內(nèi)存"));
        headerList2.add(ListUtil.toList(pcTitle, pcTotalHeader, "硬盤容量"));
        headerLists.add(headerList1);
        headerLists.add(headerList2);
        return headerLists;
    }

    private String getTotalHeader(List<BigDecimal> priceList) {
        BigDecimal sum = priceList.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal avg = sum.divide(new BigDecimal(priceList.size()), 2, RoundingMode.HALF_UP);
        BigDecimal max = priceList.stream().max(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
        BigDecimal min = priceList.stream().min(BigDecimal::compareTo).orElse(BigDecimal.ZERO);
        return StrUtil.format("總價:{}  均價:{}\n最高價:{}  最低價:{}", sum, avg, max, min);
    }

    private List<List<List<Object>>> getDatas() {
        List<List<List<Object>>> dataLists = new ArrayList<>();
        // dataList 的順序一定要與 headerList 的順序一一對應(yīng)
        List<List<Object>> dataList1 = new ArrayList<>();
        dataList1.add(ListUtil.toList(1, "iQOO 12 Pro", "2023年11月7日", new BigDecimal("4999.00"), "高通 驍龍8 Gen3", "16GB", "256GB"));
        dataList1.add(ListUtil.toList(2, "小米14 Pro", "2023年10月31日", new BigDecimal("5499.00"), "高通 驍龍8 Gen3", "16GB", "512GB"));
        dataList1.add(ListUtil.toList(3, "HUAWEI Mate 60 Pro", "2023年8月29日", new BigDecimal("6999.00"), "海思 麒麟 9000s", "12GB", "512GB"));
        dataList1.add(ListUtil.toList(4, "蘋果iPhone 15 Pro", "2023年09月22日", new BigDecimal("10999.00"), "蘋果 A17 Pro", "8GB", "256GB"));
        dataList1.add(ListUtil.toList(5, "vivo X90s", "2023年06月30日", new BigDecimal("4099.00"), "聯(lián)發(fā)科 天璣9200+", "12GB", "512GB"));
        dataLists.add(dataList1);
        List<List<Object>> dataList2 = new ArrayList<>();
        dataList2.add(ListUtil.toList(1, "配置1", new BigDecimal("5199.00"), "Intel 酷睿 i5 13400F", "RTX 4060", "16GB", "固態(tài)硬盤 1TB"));
        dataList2.add(ListUtil.toList(2, "配置2", new BigDecimal("17599.00"), "Intel 酷睿 i9 14900KF", "RTX 4080", "32GB", "機(jī)械硬盤 1TB"));
        dataList2.add(ListUtil.toList(3, "配置3", new BigDecimal("30999.00"), "Intel 酷睿 i9 14900KF", "RTX 4090", "32GB", "固態(tài)硬盤 2TB"));
        dataLists.add(dataList2);
        return dataLists;
    }
}

這里針對幾個list進(jìn)行說明

  • List<String> sheetNames 顯而易見,就是創(chuàng)建多個 sheet
  • List<List<List<String>>> headerLists最外層 list 代表每個 sheet 創(chuàng)建一個 header,第二層 list 代表橫向的 header,第三層 list 代表縱向的。EasyExcel會將第二層 list 中的每個三層 list 元素同序(index)相等的字符進(jìn)行合并,利用這個特性可以很方便的創(chuàng)建多級表頭。
  • List<List<List<Object>>> dataLists同樣的,最外層 list 代表每個 sheet 里的數(shù)據(jù),第二層 list 代表縱向每行的數(shù)據(jù),第三層 list 代表單元格的數(shù)據(jù)

Excel導(dǎo)出工具

package com.penga.demo.util;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.handler.WriteHandler;
import com.alibaba.excel.write.metadata.WriteSheet;
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.*;
import org.springframework.http.MediaType;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

public class EasyExcelUtils {

    /**
     * @param response     返回
     * @param fileName     文件名
     * @param sheetNames   sheet集合
     * @param headerLists  表頭集合
     * @param dataLists    數(shù)據(jù)集合
     * @param writeHandler 自定義樣式
     */
    public static void writeExcelSheets(HttpServletResponse response, String fileName, List<String> sheetNames,
                                        List<List<List<String>>> headerLists, List<List<List<Object>>> dataLists, WriteHandler writeHandler) {
        ServletOutputStream out = null;
        try {
            out = getOut(response, fileName);
            sheetNames = sheetNames.stream().distinct().collect(Collectors.toList());
            int num = sheetNames.size();

            // 設(shè)置基礎(chǔ)樣式
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(getHeadStyle(), getContentStyle());
            ExcelWriter excelWriter = EasyExcel.write(out).build();
            for (int i = 0; i < num; i++) {
                ExcelWriterSheetBuilder sheetBuilder = EasyExcel.writerSheet(i, sheetNames.get(i)).head(headerLists.get(i))
                        // 自動列寬(按實(shí)際情況加入)
                        .registerWriteHandler(new CustomHandler())
                        .registerWriteHandler(horizontalCellStyleStrategy);
                if (Objects.nonNull(writeHandler)) {
                    // 自定義樣式設(shè)置
                    sheetBuilder.registerWriteHandler(writeHandler);
                }
                WriteSheet writeSheet = sheetBuilder.build();
                if (CollectionUtil.isEmpty(dataLists)) {
                    excelWriter.write(new ArrayList<>(), writeSheet);
                } else {
                    excelWriter.write(dataLists.get(i), writeSheet);
                }
            }
            excelWriter.finish();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (Objects.nonNull(out)) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static ServletOutputStream getOut(HttpServletResponse response, String fileName) throws Exception {
        fileName = fileName + new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) + ExcelTypeEnum.XLSX.getValue();
        setAttachmentResponseHeader(response, fileName);
        response.setCharacterEncoding("utf-8");
        response.setContentType(MediaType.MULTIPART_FORM_DATA_VALUE);
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        return response.getOutputStream();
    }

    /**
     * 下載文件名重新編碼
     *
     * @param response     響應(yīng)對象
     * @param realFileName 真實(shí)文件名
     * @return
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
        String percentEncodedFileName = percentEncode(realFileName);
        String contentDispositionValue = "attachment; filename=" + percentEncodedFileName + ";filename*=utf-8''" + percentEncodedFileName;
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", contentDispositionValue);
    }

    /**
     * 百分號編碼工具方法
     *
     * @param s  需要百分號編碼的字符串
     * @return   百分號編碼后的字符串
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\+", "%20");
    }

    /**
     * 頭部樣式
     */
    private static WriteCellStyle getHeadStyle() {
        // 頭的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景顏色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 字體
        WriteFont headWriteFont = new WriteFont();
        //設(shè)置字體名字
        headWriteFont.setFontName("微軟雅黑");
        //設(shè)置字體大小
        headWriteFont.setFontHeightInPoints((short) 10);
        //字體加粗
        headWriteFont.setBold(false);
        //在樣式用應(yīng)用設(shè)置的字體
        headWriteCellStyle.setWriteFont(headWriteFont);

        // 邊框樣式
        setBorderStyle(headWriteCellStyle);

        //設(shè)置自動換行
        headWriteCellStyle.setWrapped(true);

        //設(shè)置水平對齊的樣式為居中對齊
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        //設(shè)置垂直對齊的樣式為居中對齊
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

        //設(shè)置文本收縮至合適
        //        headWriteCellStyle.setShrinkToFit(true);

        return headWriteCellStyle;
    }

    /**
     * 內(nèi)容樣式
     */
    private static WriteCellStyle getContentStyle() {
        // 內(nèi)容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();

        // 背景白色
        // 這里需要指定 FillPatternType 為FillPatternType.SOLID_FOREGROUND 不然無法顯示背景顏色.頭默認(rèn)了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);

        // 設(shè)置字體
        WriteFont contentWriteFont = new WriteFont();
        //設(shè)置字體大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        //設(shè)置字體名字
        contentWriteFont.setFontName("宋體");
        //在樣式用應(yīng)用設(shè)置的字體
        contentWriteCellStyle.setWriteFont(contentWriteFont);

        //設(shè)置樣式
        setBorderStyle(contentWriteCellStyle);

        // 水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //設(shè)置自動換行
        contentWriteCellStyle.setWrapped(true);

        //設(shè)置單元格格式是:文本格式,方式長數(shù)字文本科學(xué)計數(shù)法
//        contentWriteCellStyle.setDataFormatData();

        //設(shè)置文本收縮至合適
        // contentWriteCellStyle.setShrinkToFit(true);

        return contentWriteCellStyle;
    }

    /**
     * 邊框樣式
     */
    private static void setBorderStyle(WriteCellStyle cellStyle) {
        //設(shè)置底邊框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        //設(shè)置底邊框顏色
        cellStyle.setBottomBorderColor(IndexedColors.BLACK1.getIndex());
        //設(shè)置左邊框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        //設(shè)置左邊框顏色
        cellStyle.setLeftBorderColor(IndexedColors.BLACK1.getIndex());
        //設(shè)置右邊框
        cellStyle.setBorderRight(BorderStyle.THIN);
        //設(shè)置右邊框顏色
        cellStyle.setRightBorderColor(IndexedColors.BLACK1.getIndex());
        //設(shè)置頂邊框
        cellStyle.setBorderTop(BorderStyle.THIN);
        //設(shè)置頂邊框顏色
        cellStyle.setTopBorderColor(IndexedColors.BLACK1.getIndex());
    }
}

自定義樣式

如果要設(shè)置其他樣式,可以在評論區(qū)提出來,或閱讀源碼。

package com.penga.demo.util;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.*;

import java.util.List;

public class DigitalProductCellWriteHandler implements CellWriteHandler {

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> cellDataList, 
                                Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        int rowIndex = cell.getRowIndex();
        int columnIndex = cell.getColumnIndex();
        String sheetName = cell.getSheet().getSheetName();
        if (rowIndex == 1 && columnIndex == 0) {
            // 設(shè)置表頭統(tǒng)計的樣式,由于單元格是合并的,只設(shè)置第一列就行了
            setTotalStyle(writeSheetHolder, cellDataList, cell);
            return;
        }
        if (!isHead) {
            // 內(nèi)容樣式處理
            Workbook workbook = cell.getSheet().getWorkbook();
            if (sheetName.equals("手機(jī)")) {
                // 判斷是否為”手機(jī)“sheet
                if (columnIndex == 3) {
                    // 判斷價格
                    // 注意,這里的 cell.get**Value 有多個方法,一定要準(zhǔn)確,否則會報錯,報錯后不會再進(jìn)入這個攔截器,直接導(dǎo)出了
                    // 如果無法準(zhǔn)確判斷應(yīng)該用哪個 getValue,可以 debug 測試
                    double value = cell.getNumericCellValue();
                    if (value > 5000.00) {
                        // 字體樣式改為紅色
                        CellStyle cellStyle = getContentCellStyle(workbook, IndexedColors.WHITE.getIndex(), IndexedColors.RED.getIndex());
                        //設(shè)置當(dāng)前單元格樣式
                        cell.setCellStyle(cellStyle);
                        // 這里要把 WriteCellData的樣式清空
                        // 不然后面還有一個攔截器 FillStyleCellWriteHandler 默認(rèn)會將 WriteCellStyle 設(shè)置到cell里面去 會導(dǎo)致自己設(shè)置的不一樣
                        cellDataList.get(0).setWriteCellStyle(null);
                    }
                } else if (columnIndex == 4) {
                    // 判斷CPU
                    String value = cell.getStringCellValue();
                    if (value.contains("驍龍8 Gen3")) {
                        // 背景改為黃色
                        CellStyle cellStyle = getContentCellStyle(workbook, IndexedColors.YELLOW.getIndex(), IndexedColors.BLACK.getIndex());
                        cell.setCellStyle(cellStyle);
                        cellDataList.get(0).setWriteCellStyle(null);
                    }
                }
            } else {
                // ”電腦“sheet
                if (columnIndex == 2) {
                    // 判斷價格
                    double value = cell.getNumericCellValue();
                    if (value > 10000.00) {
                        // 字體樣式改為紅色
                        CellStyle cellStyle = getContentCellStyle(workbook, IndexedColors.WHITE.getIndex(), IndexedColors.RED.getIndex());
                        cell.setCellStyle(cellStyle);
                        cellDataList.get(0).setWriteCellStyle(null);
                    }
                } else if (columnIndex == 4) {
                    String value = cell.getStringCellValue();
                    if (value.contains("RTX 4090")) {
                        // 背景改為藍(lán)色
                        CellStyle cellStyle = getContentCellStyle(workbook, IndexedColors.LIGHT_BLUE.getIndex(), IndexedColors.BLACK.getIndex());
                        cell.setCellStyle(cellStyle);
                        cellDataList.get(0).setWriteCellStyle(null);
                    }
                }
            }
        }
    }

    private CellStyle getContentCellStyle(Workbook workbook, short ffColorIndex, short fontColorIndex) {
        // 單元格策略
        CellStyle cellStyle = workbook.createCellStyle();
        // 設(shè)置背景顏色
        cellStyle.setFillForegroundColor(ffColorIndex);
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 設(shè)置垂直居中為居中對齊
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 設(shè)置左右對齊為居中對齊
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        // 自動換行
        cellStyle.setWrapText(true);
        // 設(shè)置邊框
        setBorderStyle(cellStyle);
        // 字體
        Font font = workbook.createFont();
        //設(shè)置字體名字
        font.setFontName("宋體");
        //設(shè)置字體大小
        font.setFontHeightInPoints((short) 10);
        // 設(shè)置字體顏色
        font.setColor(fontColorIndex);
        //字體加粗
        font.setBold(false);
        //在樣式用應(yīng)用設(shè)置的字體
        cellStyle.setFont(font);
        return cellStyle;
    }

    private void setTotalStyle(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell) {
        Workbook workbook = cell.getSheet().getWorkbook();
        //設(shè)置行高
        writeSheetHolder.getSheet().getRow(cell.getRowIndex()).setHeight((short) (1.4 * 256 * 2));
        // 單元格策略
        CellStyle cellStyle = workbook.createCellStyle();
        // 設(shè)置背景顏色灰色
        cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        // 設(shè)置垂直居中為居中對齊
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 設(shè)置左右對齊為靠右對齊
        cellStyle.setAlignment(HorizontalAlignment.RIGHT);
        // 自動換行
        cellStyle.setWrapText(true);
        // 設(shè)置邊框
        setBorderStyle(cellStyle);
        // 字體
        Font font = workbook.createFont();
        //設(shè)置字體名字
        font.setFontName("微軟雅黑");
        //設(shè)置字體大小
        font.setFontHeightInPoints((short) 10);
        //字體加粗
        font.setBold(false);
        //在樣式用應(yīng)用設(shè)置的字體
        cellStyle.setFont(font);
        //設(shè)置當(dāng)前單元格樣式
        cell.setCellStyle(cellStyle);
        // 這里要把 WriteCellData的樣式清空
        // 不然后面還有一個攔截器 FillStyleCellWriteHandler 默認(rèn)會將 WriteCellStyle 設(shè)置到cell里面去 會導(dǎo)致自己設(shè)置的不一樣
        cellDataList.get(0).setWriteCellStyle(null);
    }

    /**
     * 邊框樣式
     */
    private static void setBorderStyle(CellStyle cellStyle) {
        //設(shè)置底邊框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        //設(shè)置底邊框顏色
        cellStyle.setBottomBorderColor(IndexedColors.BLACK1.getIndex());
        //設(shè)置左邊框
        cellStyle.setBorderLeft(BorderStyle.THIN);
        //設(shè)置左邊框顏色
        cellStyle.setLeftBorderColor(IndexedColors.BLACK1.getIndex());
        //設(shè)置右邊框
        cellStyle.setBorderRight(BorderStyle.THIN);
        //設(shè)置右邊框顏色
        cellStyle.setRightBorderColor(IndexedColors.BLACK1.getIndex());
        //設(shè)置頂邊框
        cellStyle.setBorderTop(BorderStyle.THIN);
        //設(shè)置頂邊框顏色
        cellStyle.setTopBorderColor(IndexedColors.BLACK1.getIndex());
    }
}

設(shè)置自定義樣式后,一定要將原來的樣式清空(cellDataList.get(0).setWriteCellStyle(null);),否則會導(dǎo)致自定義的樣式設(shè)置不進(jìn)去

自動列寬

這個方法也不太準(zhǔn)確,有的情況下列會特別寬,如果有更好的方法,歡迎在評論區(qū)指出

package com.penga.demo.util;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.Cell;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CustomHandler extends AbstractColumnWidthStyleStrategy {
    /**
     * 最大列寬
     */
    private static final int MAX_COLUMN_WIDTH = 255;
    private static final Map<Integer, Map<Integer, Integer>> CACHE = new HashMap<>(8);
    public CustomHandler() {
    }
    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        boolean needSetWidth = isHead || !CollectionUtil.isEmpty(cellDataList);
        if (isHead) {
            // 如果不是最后一個表頭,則不改變列寬
            List<String> headNameList = head.getHeadNameList();
            if (CollectionUtil.isNotEmpty(headNameList)) {
                int size = headNameList.size();
                if (!cell.getStringCellValue().equals(headNameList.get(size - 1))) {
                    return;
                }
            }
        }
        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);
                    writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
                }
            }
        }
    }
    private Integer dataLength(List<WriteCellData<?>> cellDataList, Cell cell, Boolean isHead) {
        if (isHead) {
            return cell.getStringCellValue().getBytes().length;
        } else {
            WriteCellData<?> cellData = cellDataList.get(0);
            CellDataTypeEnum type = cellData.getType();
            if (type == null) {
                return -1;
            } else {
                switch (type) {
                    case STRING:
                        return cellData.getStringValue().getBytes().length;
                    case BOOLEAN:
                        return cellData.getBooleanValue().toString().getBytes().length;
                    case NUMBER:
                        return cellData.getNumberValue().toString().getBytes().length;
                    case DATE:
                        return cellData.getDateValue().toString().getBytes().length;
                    default:
                        return -1;
                }
            }
        }
    }
}

導(dǎo)出

使用API調(diào)試工具發(fā)送請求:

最終的導(dǎo)出效果如下:

以上就是Java EasyExcel實(shí)現(xiàn)導(dǎo)出多sheet并設(shè)置單元格樣式的詳細(xì)內(nèi)容,更多關(guān)于Java EasyExcel導(dǎo)出sheet的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MybatisPlus 自定義.vm模板的生成

    MybatisPlus 自定義.vm模板的生成

    為更加快捷方便的開發(fā)代碼,使用MybatisPlus的代碼自動生成功能,將一些繁瑣的操作自動生成,本文主要介紹了MybatisPlus 自定義.vm模板的生成,感興趣的可以了解一下
    2024-03-03
  • mybatis實(shí)現(xiàn)動態(tài)升降序的問題小結(jié)

    mybatis實(shí)現(xiàn)動態(tài)升降序的問題小結(jié)

    文章介紹了如何在MyBatis的XML文件中實(shí)現(xiàn)動態(tài)排序,使用$符號而不是#符號來引用變量,以避免SQL注入,同時,強(qiáng)調(diào)了在Java代碼中進(jìn)行防注入處理的重要性,感興趣的朋友一起看看吧
    2025-02-02
  • 徹底解決IDEA中SpringBoot熱部署無效的問題(推薦)

    徹底解決IDEA中SpringBoot熱部署無效的問題(推薦)

    這篇文章主要介紹了徹底解決IDEA中SpringBoot熱部署無效的問題,本文給大家?guī)韱栴}原因分析通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2020-09-09
  • Java多線程實(shí)現(xiàn)模擬12306火車站售票系統(tǒng)

    Java多線程實(shí)現(xiàn)模擬12306火車站售票系統(tǒng)

    12360火車票售票系統(tǒng)基本上大家都用過,那你知道是怎么實(shí)現(xiàn)的嗎,今天我們就模擬12306火車站售票系統(tǒng)來實(shí)現(xiàn),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Spring Security自定義登錄原理及實(shí)現(xiàn)詳解

    Spring Security自定義登錄原理及實(shí)現(xiàn)詳解

    這篇文章主要介紹了Spring Security自定義登錄原理及實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • SpringSecurity實(shí)現(xiàn)前后端分離登錄token認(rèn)證詳解

    SpringSecurity實(shí)現(xiàn)前后端分離登錄token認(rèn)證詳解

    目前市面上比較流行的權(quán)限框架主要實(shí)Shiro和Spring Security,這兩個框架各自側(cè)重點(diǎn)不同,各有各的優(yōu)劣,本文將給大家詳細(xì)介紹SpringSecurity如何實(shí)現(xiàn)前后端分離登錄token認(rèn)證
    2023-06-06
  • Java實(shí)現(xiàn)簡單的貪吃蛇小游戲

    Java實(shí)現(xiàn)簡單的貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡單的貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Spring BPP中如何優(yōu)雅的創(chuàng)建動態(tài)代理Bean詳解

    Spring BPP中如何優(yōu)雅的創(chuàng)建動態(tài)代理Bean詳解

    這篇文章主要給大家介紹了關(guān)于Spring BPP中如何優(yōu)雅的創(chuàng)建動態(tài)代理Bean的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 字節(jié)二面SpringBoot可以同時處理多少請求

    字節(jié)二面SpringBoot可以同時處理多少請求

    這篇文章主要為大家介紹了字節(jié)二面之SpringBoot可以同時處理多少請求面試分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • SpringBoot高級配置之臨時屬性、配置文件、日志、多環(huán)境配置詳解

    SpringBoot高級配置之臨時屬性、配置文件、日志、多環(huán)境配置詳解

    這篇文章主要介紹了SpringBoot高級配置之臨時屬性、配置文件、日志、多環(huán)境配置,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02

最新評論