EasyExcel設置首行自增需要(帶樣式)

EasyExcel設置首行自增需要(帶樣式)

github地址

EasyExcel優點不過多累述,本文主要分享實踐代碼,在使用EasyExcel之前建議先將項目從github克隆下來,然後根據其中的測試類跟蹤一下源碼,大致瞭解其思路,這樣能是大家更好的運用EasyExcel。

最終效果圖

代碼
  1. 單元格樣式的工具類CellStyleUtil
package com.jesse.commons;

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.*;

/**
 * excel 樣式工具類
 * @author jesse
 * @date 2020/03/08 19:08
 */
public class CellStyleUtil {

    /**
     * excel首列序號列樣式
     * @param workbook
     * @return
     */
    public static CellStyle firstCellStyle(Workbook workbook) {
        CellStyle cellStyle = workbook.createCellStyle();
        //居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        //設置邊框
        cellStyle.setBorderBottom(BorderStyle.THIN);
        cellStyle.setBorderLeft(BorderStyle.THIN);
        cellStyle.setBorderRight(BorderStyle.THIN);
        cellStyle.setBorderTop(BorderStyle.THIN);
        //文字
        Font font = workbook.createFont();
        font.setBold(Boolean.TRUE);
        cellStyle.setFont(font);
        return cellStyle;
    }

    /**
     * 用於設置excel導出時的樣式
     * easyexcel 導出樣式
     * @return
     */
    public static HorizontalCellStyleStrategy getHorizontalCellStyleStrategy() {
        // 頭的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景設置爲紅色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.getIndex());
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short)12);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 內容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 這裏需要指定 FillPatternType 爲FillPatternType.SOLID_FOREGROUND 不然無法顯示背景顏色.頭默認了 FillPatternType所以可以不指定
        contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 背景綠色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //邊框
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        //文字
        WriteFont contentWriteFont = new WriteFont();
        // 字體大小
        contentWriteFont.setFontHeightInPoints((short)12);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 這個策略是 頭是頭的樣式 內容是內容的樣式 其他的策略可以自己實現
        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    }

}


注意: 普通cell設置填充顏色時一定要設置填充類型,即cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);不然顏色是填充不上的,我就在這遇到坑的。

  1. 非常重要的一點,定製攔截器,即實現WriteHandler 類,由於需求是在每行前加序號,所以需要實現其子類RowWriteHandler,這個也是在EasyExcel官方給的測試類中沒有給出。另外還有SheetWriteHandlerWorkbookWriteHandler
package com.alibaba.excel.write.handler;

import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import org.apache.poi.ss.usermodel.Row;

public interface RowWriteHandler extends WriteHandler {
    void beforeRowCreate(WriteSheetHolder var1, WriteTableHolder var2, Integer var3, Integer var4, Boolean var5);

    void afterRowCreate(WriteSheetHolder var1, WriteTableHolder var2, Row var3, Integer var4, Boolean var5);

    void afterRowDispose(WriteSheetHolder var1, WriteTableHolder var2, Row var3, Integer var4, Boolean var5);
}

以上可看出該類有三個方法,即在創建行之前執行、之後執行、處理後執行,所以我們只需要重寫創建行之後執行的方法即可。

package com.jesse.configuration;

import com.alibaba.excel.write.handler.RowWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.xdf.bling.cloud.tutor.commons.CellStyleUtil;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 自定義行攔截器
 * @author jesse
 * @date 2020/03/08 12:57
 */
public class CustomRowWriteHandler implements RowWriteHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(CustomRowWriteHandler.class);
    /**
    * 一定將樣式設置成全局變量 
    * 首行只需要創建一次樣式就可以 不然每行都創建一次 數據量大的話會保錯
    * 異常信息:The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx Workbook
    */
	private CellStyle firstCellStyle;

    /**
     * 列號
     */
    private int count = 0;

    @Override
    public void beforeRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Integer integer, Integer integer1, Boolean aBoolean) {

    }

    @Override
    public void afterRowCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("第{}行創建完畢!", row.getRowNum());
        }
        Cell cell = row.createCell(0);
        if (firstCellStyle == null) {
            Workbook workbook = writeSheetHolder.getSheet().getWorkbook();
            firstCellStyle = ExportUtil.firstCellStyle(workbook);
            LOGGER.info("設置首列樣式成功");
        }
        cell.setCellStyle(firstCellStyle);
        //設置列寬  0列   10個字符寬度
        writeSheetHolder.getSheet().setColumnWidth(0, 10 * 256);
        if (row.getRowNum() == 0) {
            cell.setCellValue("序號");
            return;
        }
        cell.setCellValue(++count);
    }

    @Override
    public void afterRowDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Integer integer, Boolean aBoolean) {

    }
}

  1. 實體類
package com.jesse.pojo;

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.excel.annotation.write.style.HeadRowHeight;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.util.Date;

/**
 * 基礎數據類
 *
 * @author Jiaju Zhuang
 **/
@ContentRowHeight(16)
@HeadRowHeight(16)
@ColumnWidth(16)
public class DemoData {
    @ExcelProperty(value = "字符串標題", index = 1)
    private String string;
    @ExcelProperty(value = "日期標題", index = 2)
    private Date date;
    @ExcelProperty(value = "數字標題", index = 3)
    private Double doubleData;
    /**
     * 忽略這個字段
     */
    @ExcelIgnore
    private String ignore;

    public String getString() {
        return string;
    }

    public void setString(String string) {
        this.string = string;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Double getDoubleData() {
        return doubleData;
    }

    public void setDoubleData(Double doubleData) {
        this.doubleData = doubleData;
    }

    public String getIgnore() {
        return ignore;
    }

    public void setIgnore(String ignore) {
        this.ignore = ignore;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
    }
}

  1. 測試類
package com.jesse.service;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.xdf.bling.cloud.service.tutor.pojo.DemoData;
import com.xdf.bling.cloud.service.tutor.pojo.WidthAndHeightData;
import com.xdf.bling.cloud.tutor.commons.CellStyleUtil;
import com.xdf.bling.cloud.tutor.configuration.CustomRowWriteHandler;
import org.apache.poi.ss.usermodel.*;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wpx
 * @date 2020/03/07 23:29
 */
public class EasyExcelTest {

    @Test
    public void customHandlerWrite() {
        String fileName = "C:\\Users\\Administrator\\Desktop\\customHandlerWrite" + System.currentTimeMillis() + ".xlsx";
        // 這裏 需要指定寫用哪個class去寫,然後寫到第一個sheet,名字爲模板 然後文件流會自動關閉
        EasyExcel.write(fileName, DemoData.class)
                .registerWriteHandler(CellStyleUtil.getHorizontalCellStyleStrategy())
                .registerWriteHandler(new CustomRowWriteHandler())
                .sheet("模板").doWrite(data());
    }

    private List<DemoData> data() {
        List<DemoData> list = new ArrayList<DemoData>();
        for (int i = 0; i < 10; i++) {
            DemoData data = new DemoData();
            data.setString("字符串" + i);
            data.setDate(new Date());
            data.setDoubleData(0.56);
            list.add(data);
        }
        return list;
    }

}

注意: 一定要將攔截器註冊registerWriteHandler(new CustomRowWriteHandler())

真正用好EasyExcel還需要用心去研究其源碼,小小分享希望對大家能有所幫助。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章