InteliJ IDEA全家桶正版激活

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

Github:

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

/*** Excel基础模型* @author jipengfei*/
public class BaseRowModel {/*** 每列样式*/private Map<Integer,CellStyle> cellStyleMap = new HashMap<Integer,CellStyle>();public void addStyle(Integer row, CellStyle cellStyle){cellStyleMap.put(row,cellStyle);}public CellStyle getStyle(Integer row){return cellStyleMap.get(row);}public Map<Integer, CellStyle> getCellStyleMap() {return cellStyleMap;}public void setCellStyleMap(Map<Integer, CellStyle> 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<Workbook, Map<String, CellStyle>> 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<String,List<? extends BaseRowModel>> data, WriteHandler handler,Map<Integer, Integer> columnWidthMap, List<CellStyleEnum> cellStyleEnums) throws IOException {File file = new File(path);if (!file.getParentFile().exists()) {file.getParentFile().mkdirs();}OutputStream out = new FileOutputStream(path);// ExcelWriter用于导出ExcelExcelWriter 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数据来创建sheetfor (Map.Entry<String, List<? extends BaseRowModel>> 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<CellStyleEnum> cellStyleEnums) {Map<String, CellStyle> 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<Workbook, Map<String, CellStyle>> 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 {@Overridepublic void sheet(int i, Sheet sheet) {}@Overridepublic void row(int i, Row row) {}@Overridepublic void cell(int i, Cell cell) {// 获取当前workbook对应的CellStyle集合Map<String, CellStyle> 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("已签到"));}}}
}

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

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

EasyExcel为单个Cell设置样式相关推荐

  1. easypoi导出excel不设置样式_EasyExcel为单个Cell设置样式

    EasyExcel是阿里巴巴对POI封装的一个库,号称解决了POI的OOM问题,并且在使用上也更方便一些 然而我在使用的时候发现还是有很多坑,其中一个比较头疼的是对单个单元格样式的设置.EasyExc ...

  2. aspose.cell 设置样式 java_Aspose.Cell怎么单独给表格加外边框?

    问题描述 在做导出报表时候,想给导出的表格做个边框 问题出现的环境背景及自己尝试过哪些方法 但是看到aspose.cell 好像都是一个单元格一设置,没有对于整个表格设置的 相关代码 // 请把代码文 ...

  3. java excel cell 设置样式_java中对Excel的创建、样式修改

    public static String createExcel(ArrayList list, ArrayList>DataList, String dateStr) {//创建一个excel ...

  4. easyExcel实现动态表头设置以及单元格样式设置

    easyexcel实现文件导入导出请看上篇博客:springboot集成easyExcel实现文件导入导出 上篇文章已经知道如何使用easyExcel实现简单的文件导入导出,但是导出的表头和格式都是固 ...

  5. easyExcel 导出文件时,设置单元格样式,自适应列宽

    目录 1.自适应列宽实现类 2.单元格样式实现类 3.导出的时候,特殊数据类型,需要设置转换类,不然注解导出方式会报错 注解使用方式 日期转换类 4.web导出excel(将excel数据写入到res ...

  6. Primefaces dataTable设置某个cell的样式问题

    设置primefaces dataTable的源网段列的Cell可以编辑,当回车键保存时,判断是否输入的网段合法,如果不合法就显示警告信息,并将这个不合法的数据用红色表示.问题是,怎么给这一个cell ...

  7. hutool工具ExcelWriter设置单个单元格样式

    官网自定义样式: ExcelWriter writer = ...;// 定义单元格背景色 StyleSet style = writer.getStyleSet(); // 第二个参数表示是否也设置 ...

  8. easyExcel导出数据并设置单元格下拉数据

    easyExcel由于导出和导入的注解差异,所以实现不了标题功能 此处不在介绍导出导出的注解 entity: @DropDownSetField自行封装注解:稍后解释 public class Sal ...

  9. EasyExcel 使用和背景颜色样式(3.0以上的版本)

    谈到新技术,每个人都会有点恐惧,怕处理不好,确实第一次使用新技术会遇到很多坑,本人以前使用poi也遇到了很多的坑,但是很快就解决了,这次使用EasyExcel这个新技术去做excel表的导出,还要给表 ...

最新文章

  1. 代码中配置log4j (同时输出不同级别的log到不同终端)
  2. ibatis中isEquals、isNotEmpty的用法
  3. android软件更新模块实现的技术和方法,Android APK签名原理及方法
  4. C语言文件操作(一)产生0~M范围内的N个随机数
  5. 有效前沿—让你的投资收益最大化
  6. js合并同类数组里面的对象_通过同类群组保留估算客户生命周期价值
  7. python内存消耗大吗_如何减少python内存的消耗?
  8. RabbitMQ 资料整理
  9. c语言 自动化办公,办公自动化快捷键大全
  10. 设计模式:观察者(Observer)模式
  11. 全解电磁流量计功能和精度性能
  12. 驱动蜂鸣器电路-可参考
  13. 台式计算机检测不到无线网卡,台式机检测不到无线网卡怎么办
  14. C#-Winform - 调用笔记本摄像头实现拍照并保存
  15. 云服务器需要芯片吗,什么时候手机不再需要芯片——计算云端化是不可逆转的未来...
  16. 网页设计项目5穿搭速递_小个子穿搭指南,学以下六种服装的穿搭超时髦,轻松驾驭各种风格...
  17. 肠道微生物群与心血管疾病:机遇与挑战
  18. 培训-从学员的角度思考问题
  19. 支付宝常用接口统一封装,可直接支付参数使用(适用于H5、PC、APP)
  20. 中华英才网爬虫程序(3)-queue和threading模块的结合使用

热门文章

  1. 【算法讲26:特征方程】求齐次线性一阶递推与二阶递推通项公式 | HDU 2021多校一 Pass!
  2. 2021-2027全球与中国医疗物联网服务市场现状及未来发展趋势
  3. 微信的账号连接服务器失败怎么回事,微信无法连接到服务器的原因和6个解决方法...
  4. android 皮肤包换肤之Resources加载(一)
  5. 毕业设计-基于微信小程序的临沂旅游应用系统
  6. 一分钟完全关闭Antimalware Service Executable(windows defender)任务管理器程序
  7. 新春特别策划:新春观影 与科幻电影难分舍的IT元素
  8. 跨数据中心场景下,kafka集群部署模式
  9. 聊聊新加坡的工作和生活
  10. 机器视觉算法工程师试题