EasyExcel是阿里巴巴对POI封装的一个库,号称解决了POI的OOM问题,并且在使用上也更方便一些

然而我在使用的时候发现还是有很多坑,其中一个比较头疼的是对单个单元格样式的设置。EasyExcel提供了一个BaseRowModel作为每行数据的一个模型,并且其中有一个属性cellStyleMap代表每列样式的集合,本来我以为这个只要在自己定义模型的时候,也把CellStyle定义进去就行了,然而,还是我想多了……定义了CellStyle并没有什么卵用,这是第一个蛋疼的地方

/**

* Excel基础模型

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

}

}

后来测试半天,才发现创建CellStyle时必须通过一个Workbook对象来创建,而这个Workbook不能随便新建一个对象完事儿,得用你当前写入的Workbook来创建对应的CellStyle样式才能起作用。然而……事情并没有那么简单,经过我对源码的反复查看,EasyExcel生成excel表的步骤是用一个ExcelWriter来写入数据,并没有提供获取Workbook的方法,不知道什么原因让阿里巴巴不提供这样一个接口……这是第二个蛋疼的地方

既然没有提供接口,那就只能用反射来硬刚了,下面就直接上代码了

我这里是在开始写数据之前就将每张表的CellStyle与每张表关联起来,再在后面的handler中获取到这个CellStyle进行设置

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对象模型创建excel,并使用handler

* 生成Excel格式为xlsx

*

* @param path Excel生成路径

* @param headLineMun 表头占几行

* @param data 传入的键值对数据(key为sheet名,value为sheet数据)

* @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用于导出Excel

ExcelWriter writer = EasyExcelFactory.getWriterWithTempAndHandler(null, out,

ExcelTypeEnum.XLSX, true, handler);

// 构造单元格样式

Workbook workbook = getWorkbook(writer);

cellStyles.put(workbook, createCellStyle(workbook, cellStyleEnums));

// sheet的序号,从1开始

int i = 1;

// 遍历传入的sheet名和sheet数据来创建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++;

}

// 必须要调用finish(),否则数据不会写入文件

writer.finish();

out.close();

}

/**

* **获取workbook**

* 因为EasyExcel这个库设计的原因

* 只能使用反射获取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) {

// 要设置属性可达,不然会抛出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提供了一个WriteHandler,我们实现这个接口,就可以在每个单元格写入之后或者每行写入之前来进行拦截(这个handler设计的也很蛋疼),并注入我们自己的业务逻辑(设置单元格样式)。

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时

* 将未签到学生进行特殊标识

*

* @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) {

// 获取当前workbook对应的CellStyle集合

Map cellStyleMap = ExcelUtil.getCellStyles().get(cell.getSheet().getWorkbook());

// 从第二行开始设置格式,第一行是表头

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("已签到"));

}

}

}

}

上面有一些简单的逻辑处理,就不一一介绍了。

若文章有任何问题,欢迎留言指出——作者博客:桔子笔记

easypoi导出excel不设置样式_EasyExcel为单个Cell设置样式相关推荐

  1. easypoi导出excel不设置样式_EasyPOI 导出excel设置边框,背景颜色,字体样式

    EasyPOI 导出excel设置边框,背景颜色,字体样式 EasyPOI 导出代码示例ExportParams exportParams = new ExportParams(); exportPa ...

  2. 编码技巧——使用Easypoi导出Excel、多sheet

    本文主要介绍easypoi导出Excel的代码示例:自己之前手动实现过导出工具类<编码技巧--导出工具类>,基于实体和注解,通过反射来映射实体字段和exce列的关系:在部分工程里面看到了e ...

  3. 使用EasyPOI导出Excel模板数据(含图片)

    使用EasyPOI导出Excel模板数据(含图片) EasyPOI功能如同名字Easy,主打的功能就是容易,让一个没接触过POI的人员可以方便的写出Excel导出,Excel模板导出,Excel导入, ...

  4. EasyPoi导出Excel实现标记颜色

    EasyPoi导出Excel实现标记颜色 PS:不知道EasyPoi 的可以看快速上手文档 <dependency><groupId>cn.afterturn</grou ...

  5. 使用easypoi导出excel实现动态列

    使用easypoi导出excel实现动态列 说明 使用的是easypoi进行导出 行头是动态生成 依据key进行列匹配,进行数据填充 第一列进行纵向动态合并 自己的一个使用,记录一下 工具依赖 < ...

  6. 用easyPoi导出excel,带多sheet,合并单元格,合计,单元格金额类型

    用easyPoi导出excel,带多sheet,合并单元格,合计,单元格金额类型 文档连接:http://easypoi.mydoc.io/ 1.引入依赖 <!-- 导出文件工具 EasyPoi ...

  7. JAVA导出Excel通用工具类——第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选、动态合并横向(纵向)单元格等多种复杂情况——保姆级别,真的不能再详细了,代码拿来即用)

    JAVA导出Excel通用工具--第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选.动态合并横向(纵向)单元格等多种复杂情况--保姆级别,真的不能再详细了,封装通用工具类,代码拿 ...

  8. EasyPoi导出excel文件总是1kb,且打不开

    EasyPoi导出excel文件总是1kb,且打不开 excel文件下载成功后打开文件遇到错误 之前的下载代码 private static void downLoadExcel(String fil ...

  9. 用EasyPoi导出Excel中单元格图片(线上阿里云)

    用EasyPoi导出Excel中单元格图片(线上阿里云): 导出数据需要包含图片 问题描述 提示:这里描述项目中遇到的问题: 数据库中存储图片格式是阿里云(oss)的图片url,导出excel显示图片 ...

最新文章

  1. android handler的机制和原理_一文搞懂handler:彻底明白Android消息机制的原理及源码
  2. Vs2005+VSS 2005 老是出问题
  3. asp.net去掉HTML标记代码
  4. 获奖公布 | Hello,SDK!数据采集黑客松大赛完美落幕!(含活动预告)
  5. 前端接入HTTP协议浅析
  6. 抓包工具 tcpdump tshark
  7. 计算机网络基础系列(三)网络应用
  8. 台达a2_台达伺服ASDA-A2系列解决五轴CNC方案助力雕刻机行业换代升级
  9. 2021年5月12日17点49分 绿盟极光
  10. 高数 | 利用定积分定义求极限
  11. Vivado2018.3手把手详细下载
  12. 推荐一个清理自己电脑磁盘的磁盘容量图形化软件--WinDirStat
  13. 高德地图——输入经纬度查找
  14. 《国富论》阅读笔记05
  15. 告诉你如何回答线上CPU100%排查面试问题
  16. 程序员的英文代号_构建一个代号为1的聊天应用程序4
  17. 食物链 (利用并查集的两种解决方法)
  18. win10找不到文件无法卸载的解决方法
  19. 动态水印跟踪去除_视频动态水印如何去除 视频中不定时出现的图片加文字广告如何尽量模糊处理...
  20. sql语句语法数据定义语句alter table

热门文章

  1. 编码和解码、调制与解调
  2. canvas中的getContext()方法 以及 webgl中的getContext()方法
  3. C++输入输出运算符重载(“”“”)
  4. Android socket 编程 实现消息推送(一)
  5. opencv用haartraining训练出现的一些问题
  6. 全云端万能小程序_万能门店全云端独立版微信小程序源码V4.0.10,全五端源码下载...
  7. 小程序支持php版本是多少,小程序体验版本什么意思
  8. iOS 7 标签栏控制器进行模态视图跳转后变成透明
  9. linux下前一天时间格式
  10. 虚拟主机IIS防范入侵常见问答