EasyExcel設置首行自增需要(帶樣式)
EasyExcel優點不過多累述,本文主要分享實踐代碼,在使用EasyExcel之前建議先將項目從github克隆下來,然後根據其中的測試類跟蹤一下源碼,大致瞭解其思路,這樣能是大家更好的運用EasyExcel。
最終效果圖
代碼
- 單元格樣式的工具類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);不然顏色是填充不上的,我就在這遇到坑的。
- 非常重要的一點,定製攔截器,即實現WriteHandler 類,由於需求是在每行前加序號,所以需要實現其子類RowWriteHandler,這個也是在EasyExcel官方給的測試類中沒有給出。另外還有SheetWriteHandler、WorkbookWriteHandler等
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) {
}
}
- 實體類
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);
}
}
- 測試類
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還需要用心去研究其源碼,小小分享希望對大家能有所幫助。