easypoi导出excel不设置样式_EasyExcel为单个Cell设置样式
EasyExcel是阿里巴巴對(duì)POI封裝的一個(gè)庫,號(hào)稱解決了POI的OOM問題,并且在使用上也更方便一些
然而我在使用的時(shí)候發(fā)現(xiàn)還是有很多坑,其中一個(gè)比較頭疼的是對(duì)單個(gè)單元格樣式的設(shè)置。EasyExcel提供了一個(gè)BaseRowModel作為每行數(shù)據(jù)的一個(gè)模型,并且其中有一個(gè)屬性cellStyleMap代表每列樣式的集合,本來我以為這個(gè)只要在自己定義模型的時(shí)候,也把CellStyle定義進(jìn)去就行了,然而,還是我想多了……定義了CellStyle并沒有什么卵用,這是第一個(gè)蛋疼的地方
/**
* Excel基礎(chǔ)模型
* @author jipengfei
*/
public class BaseRowModel {
/**
* 每列樣式
*/
private Map cellStyleMap = new HashMap();
public void addStyle(Integer row, CellStyle cellStyle){
cellStyleMap.put(row,cellStyle);
}
public CellStyle getStyle(Integer row){
return cellStyleMap.get(row);
}
public Map getCellStyleMap() {
return cellStyleMap;
}
public void setCellStyleMap(Map cellStyleMap) {
this.cellStyleMap = cellStyleMap;
}
}
后來測試半天,才發(fā)現(xiàn)創(chuàng)建CellStyle時(shí)必須通過一個(gè)Workbook對(duì)象來創(chuàng)建,而這個(gè)Workbook不能隨便新建一個(gè)對(duì)象完事兒,得用你當(dāng)前寫入的Workbook來創(chuàng)建對(duì)應(yīng)的CellStyle樣式才能起作用。然而……事情并沒有那么簡單,經(jīng)過我對(duì)源碼的反復(fù)查看,EasyExcel生成excel表的步驟是用一個(gè)ExcelWriter來寫入數(shù)據(jù),并沒有提供獲取Workbook的方法,不知道什么原因讓阿里巴巴不提供這樣一個(gè)接口……這是第二個(gè)蛋疼的地方
既然沒有提供接口,那就只能用反射來硬剛了,下面就直接上代碼了
我這里是在開始寫數(shù)據(jù)之前就將每張表的CellStyle與每張表關(guān)聯(lián)起來,再在后面的handler中獲取到這個(gè)CellStyle進(jìn)行設(shè)置
package edu.uddp.util;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.context.WriteContext;
import com.alibaba.excel.event.WriteHandler;
import com.alibaba.excel.metadata.BaseRowModel;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.ExcelBuilderImpl;
import com.sun.corba.se.spi.orbutil.threadpool.Work;
import edu.uddp.enums.CellStyleEnum;
import edu.uddp.model.SignExcelRow;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
/**
* 生成Excel表
*
* @author Juzi
* @date 2018/12/23 12:37
* Blog https://juzibiji.top
*/
public class ExcelUtil {
private static Map> cellStyles = new HashMap<>();
/**
* 使用java對(duì)象模型創(chuàng)建excel,并使用handler
* 生成Excel格式為xlsx
*
* @param path Excel生成路徑
* @param headLineMun 表頭占幾行
* @param data 傳入的鍵值對(duì)數(shù)據(jù)(key為sheet名,value為sheet數(shù)據(jù))
* @param handler 自定義的EasyExcel Handler,不使用傳入null即可
* @param columnWidthMap 每列寬度
* @throws IOException
*/
public static void createExcelWithModelAndHandler(
String path, int headLineMun, Map
List extends BaseRowModel>> data, WriteHandler handler,
Map columnWidthMap, List cellStyleEnums) throws IOException {
File file = new File(path);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
OutputStream out = new FileOutputStream(path);
// ExcelWriter用于導(dǎo)出Excel
ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(null, out,
ExcelTypeEnum.XLSX, true, handler);
// 構(gòu)造單元格樣式
Workbook workbook = getWorkbook(writer);
cellStyles.put(workbook, createCellStyle(workbook, cellStyleEnums));
// sheet的序號(hào),從1開始
int i = 1;
// 遍歷傳入的sheet名和sheet數(shù)據(jù)來創(chuàng)建sheet
for (Map.Entry> entry : data.entrySet()) {
Sheet sheet = new Sheet(i, headLineMun, entry.getValue().get(0).getClass(), entry.getKey(), null);
sheet.setColumnWidthMap(columnWidthMap);
writer.write(entry.getValue(), sheet);
i++;
}
// 必須要調(diào)用finish(),否則數(shù)據(jù)不會(huì)寫入文件
writer.finish();
out.close();
}
/**
* **獲取workbook**
* 因?yàn)镋asyExcel這個(gè)庫設(shè)計(jì)的原因
* 只能使用反射獲取workbook
*
* @param writer
* @return
*/
private static Workbook getWorkbook(ExcelWriter writer) {
Workbook workbook = null;
try {
Class> clazz1 = Class.forName("com.alibaba.excel.ExcelWriter");
Field[] fs = clazz1.getDeclaredFields();
for (Field field : fs) {
// 要設(shè)置屬性可達(dá),不然會(huì)拋出IllegalAccessException異常
field.setAccessible(true);
if ("excelBuilder".equals(field.getName())) {
ExcelBuilderImpl excelBuilder = (ExcelBuilderImpl) field.get(writer);
Class> clazz2 = Class.forName("com.alibaba.excel.write.ExcelBuilderImpl");
Field[] fs2 = clazz2.getDeclaredFields();
for (Field field2 : fs2) {
field2.setAccessible(true);
if ("context".equals(field2.getName())) {
WriteContext context = (WriteContext) field2.get(excelBuilder);
workbook = context.getWorkbook();
}
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return workbook;
}
public static Map createCellStyle(Workbook workbook, List cellStyleEnums) {
Map map = new HashMap<>();
for (CellStyleEnum cellStyleEnum : cellStyleEnums) {
if (cellStyleEnum.getNo() == 1) {
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
cellStyle.setBorderLeft(BorderStyle.THIN);//左邊框
cellStyle.setBorderTop(BorderStyle.THIN);//上邊框
cellStyle.setBorderRight(BorderStyle.THIN);//右邊框
cellStyle.setAlignment(HorizontalAlignment.CENTER);
map.put(cellStyleEnum.getName(), cellStyle);
} else if (cellStyleEnum.getNo() == 2) {
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
cellStyle.setBorderLeft(BorderStyle.THIN);//左邊框
cellStyle.setBorderTop(BorderStyle.THIN);//上邊框
cellStyle.setBorderRight(BorderStyle.THIN);//右邊框
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
map.put(cellStyleEnum.getName(), cellStyle);
}
}
return map;
}
public static Map> getCellStyles() {
return cellStyles;
}
}
EasyExcel提供了一個(gè)WriteHandler,我們實(shí)現(xiàn)這個(gè)接口,就可以在每個(gè)單元格寫入之后或者每行寫入之前來進(jìn)行攔截(這個(gè)handler設(shè)計(jì)的也很蛋疼),并注入我們自己的業(yè)務(wù)邏輯(設(shè)置單元格樣式)。
package edu.uddp.handler;
import com.alibaba.excel.event.WriteHandler;
import edu.uddp.util.ExcelUtil;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import java.util.Map;
/**
* 第三方庫EasyExcel的Handler
* 教師端生成簽到歷史表Excel時(shí)
* 將未簽到學(xué)生進(jìn)行特殊標(biāo)識(shí)
*
* @author Juzi
* @since 2018/12/22 22:07
* Blog https://juzibiji.top
*/
public class SignRecordExcelHandler implements WriteHandler {
@Override
public void sheet(int i, Sheet sheet) {
}
@Override
public void row(int i, Row row) {
}
@Override
public void cell(int i, Cell cell) {
// 獲取當(dāng)前workbook對(duì)應(yīng)的CellStyle集合
Map cellStyleMap = ExcelUtil.getCellStyles().get(cell.getSheet().getWorkbook());
// 從第二行開始設(shè)置格式,第一行是表頭
if (cell.getRowIndex() > 0) {
if (i == 7 && "未簽到".equals(cell.getStringCellValue())) {
// 該生未簽到
for (int j = 0; j < 8; j++) {
cell.getRow().getCell(j).setCellStyle(cellStyleMap.get("未簽到"));
}
} else if (i == 8 && "已簽到".equals(cell.getRow().getCell(7).getStringCellValue())) {
// 該生已簽到
for (int j = 0; j < 9; j++) {
cell.getRow().getCell(j).setCellStyle(cellStyleMap.get("已簽到"));
}
}else if(i == 8 && "未簽到".equals(cell.getRow().getCell(7).getStringCellValue())){
cell.setCellStyle(cellStyleMap.get("已簽到"));
}
}
}
}
上面有一些簡單的邏輯處理,就不一一介紹了。
若文章有任何問題,歡迎留言指出——作者博客:桔子筆記
總結(jié)
以上是生活随笔為你收集整理的easypoi导出excel不设置样式_EasyExcel为单个Cell设置样式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java中引用一个文件数据_JAVA-基
- 下一篇: java 700c corsa_JAVA