EasyExcel为单个Cell设置样式 您所在的位置:网站首页 excel如何添加边框样式颜色 EasyExcel为单个Cell设置样式

EasyExcel为单个Cell设置样式

#EasyExcel为单个Cell设置样式| 来源: 网络整理| 查看: 265

InteliJ IDEA全家桶正版激活

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

Github:

然而我在使用的时候发现还是有很多坑,其中一个比较头疼的是对单个单元格样式的设置。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 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 // 该生已签到 for (int j = 0; j cell.setCellStyle(cellStyleMap.get("已签到")); } } } }

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

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



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有