easyExcel多行表头设定不同样式和特定单元格设定样式的实现
前言
有个需求,需要设置Excel导出的样式,样式如下图所示,有三个表头行,第一个表头行需要加粗和灰色背景,另外两个表头行使用另外的样式,并且当测试结果单元格出现x或者未通过的时候,设置其为红色字体。

实现步骤
写入ExcelSheet的部分代码
for (Map.Entry<String, List<ExcelDTO>> entry : entries) {
String excelFileName = entry.getKey() + ".xlsx";
File tempFile = File.createTempFile(excelTempFolderPath + entry.getKey(), ".xlsx");
ExcelWriter excelWriter = EasyExcel.write(tempFile).build();
WriteSheet writeSheet = EasyExcel.
writerSheet("sheet")
.head(ReceiveCardExcelDTO.class)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new CustomWriteHandler("测试报告"))
.registerWriteHandler(new CustomCellWriteHandler())
.registerWriteHandler(getHeadStyleStrategy())
.build();
writeSheet.setRelativeHeadRowIndex(1);
List<List<String>> headTitles = Lists.newArrayList();
// 固定title
headTitles.add(Lists.newArrayList("工单号", "卡信息"));
headTitles.add(Lists.newArrayList(entry.getKey(), "升级固件"));
headTitles.add(Lists.newArrayList(entry.getKey(), "SDRAM"));
headTitles.add(Lists.newArrayList("型号", "HUB"));
headTitles.add(Lists.newArrayList(receiveCardOrderMap.get(entry.getValue().get(0).getMark()).getReceiveCardType(), "网口"));
headTitles.add(Lists.newArrayList("测试时间", "测试结果"));
headTitles.add(Lists.newArrayList(cn.hutool.core.date.DateUtil.format(entry.getValue().get(0).getTestTime(), "yyyy-MM-dd HH:mm:ss"), "详情"));
writeSheet.setHead(headTitles);
excelWriter.write(entry.getValue(), writeSheet);
excelWriter.finish();
重点是如下几个handler,下面会进行讲解
WriteSheet writeSheet = EasyExcel.
writerSheet("sheet")
.head(ReceiveCardExcelDTO.class)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.registerWriteHandler(new CustomWriteHandler("测试报告"))
.registerWriteHandler(new CustomCellWriteHandler())
.registerWriteHandler(getHeadStyleStrategy())
.build();
测试报告标题行的实现
这里对应的是CustomWriteHandler类
/********************************
* @interface : CustomWriteHandler
* @function : 添加excel head额外内容
* @date : 2024.04.23 11:13
* @author : zh
********************************/
public class CustomWriteHandler implements SheetWriteHandler {
private String title;
public CustomWriteHandler(String title) {
this.title = title;
}
@Override
public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
}
@Override
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
Workbook workbook = writeWorkbookHolder.getWorkbook();
Sheet sheet = workbook.getSheet(writeSheetHolder.getSheetName());
Row row1 = sheet.getRow(0);
if (row1 == null) {
row1 = sheet.createRow(0);
}
row1.setHeight((short) 500);
Cell cell1 = row1.getCell(0);
if (cell1 == null) {
cell1 = row1.createCell(0);
}
cell1.setCellValue(title);
CellStyle cellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
font.setFontHeight((short) 220);
font.setFontName("宋体");
sheet.addMergedRegionUnsafe(new CellRangeAddress(0, 0, 0, 6));
CellStyle headStyle = workbook.createCellStyle();
headStyle.setFont(font);
headStyle.setAlignment(HorizontalAlignment.CENTER);
headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 设置表头背景色为灰色
headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
CellStyle contentStyle = workbook.createCellStyle();
contentStyle.setAlignment(HorizontalAlignment.CENTER);
contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
contentStyle.setBorderTop(BorderStyle.THIN);
contentStyle.setBorderBottom(BorderStyle.THIN);
contentStyle.setBorderLeft(BorderStyle.THIN);
contentStyle.setBorderRight(BorderStyle.THIN);
for (Row row : sheet) {
if (row.getRowNum() == 0) {
for (Cell cell : row) {
// 表头
cell.setCellStyle(headStyle);
}
break;
}
}
}
}
在这里register并填入相关的标题,到此第一行标题头设置完毕。

这里其实就是相当于这行标题是独立开来设置的,先预留了第一行的位置,然后后续把标题插入这行,后面再针对这行设置独立的样式。

其他标题行的设置
可以看到每个list都有两个元素
List<List<String>> headTitles = Lists.newArrayList();
// 固定title
headTitles.add(Lists.newArrayList("工单号", "卡信息"));
headTitles.add(Lists.newArrayList(entry.getKey(), "升级固件"));
headTitles.add(Lists.newArrayList(entry.getKey(), "SDRAM"));
headTitles.add(Lists.newArrayList("型号", "HUB"));
对比excel标题

可以看到其实每个list都是两行标题竖着的两个内容,第一个列标题两行就分别是工单号,卡信息;第二列因为涉及到合并,所以出现了两个entry.getKey()对应不同的两个内容(升级固件和SDRAM),依次类推;
标题行样式的设定
对应这个registerWriteHandler(getHeadStyleStrategy())
调getHeadStyleStrategy()方法,返回了一个策略,这里只设置了header的样式
public static HorizontalCellStyleStrategy getHeadStyleStrategy() {
// 头的策略 样式调整
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
// 水平对齐方式
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
headWriteCellStyle.setFillPatternType(FillPatternType.NO_FILL);
WriteFont headWriteFont = new WriteFont();
headWriteFont.setBold(false);
headWriteFont.setFontHeightInPoints((short) 12);
headWriteCellStyle.setWriteFont(headWriteFont);
// 垂直对齐方式
headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return new HorizontalCellStyleStrategy(headWriteCellStyle, (List<WriteCellStyle>) null);
}
特定单元格样式的修改
对应了这个.registerWriteHandler(new CustomCellWriteHandler())
/********************************
* @interface : CustomCellWriteHandler
* @function : 处理excel特定内容格式
* @date : 2024.04.23 11:13
* @author : zh
********************************/
public class CustomCellWriteHandler implements CellWriteHandler {
Map<String,CellStyle> cellStyleMap = new HashMap<>();
@Override
public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
}
@Override
public void afterCellDispose(CellWriteHandlerContext context) {
Cell cell = context.getCell();
int rowIndex = cell.getRowIndex();
int cellIndex = cell.getColumnIndex();
// 自定义样式处理
// 当前事件会在 数据设置到poi的cell里面才会回调
// 判断不是头的情况 如果是fill 的情况 这里会==null 所以用not true
if (BooleanUtils.isNotTrue(context.getHead())) {
if (cell.getStringCellValue().contains("×") || cell.getStringCellValue().contains("未通过")) {
CellStyle cellStyle = null;
if (cellStyleMap.get("red") != null) {
cellStyle = cellStyleMap.get("red");
} else {
// 拿到poi的workbook
Workbook workbook = context.getWriteWorkbookHolder().getWorkbook();
// 这里能复用的地方缓存起来 一个表格最多创建6W个样式
// 不同单元格传同一个cellStyle
cellStyle = workbook.createCellStyle();
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
Font font = workbook.createFont();
font.setColor(Font.COLOR_RED);
cellStyle.setFont(font);
cellStyleMap.put("red", cellStyle);
}
cell.setCellStyle(cellStyle);
// 由于这里没有指定dataformat 最后展示的数据 格式可能会不太正确
// 这里要把 WriteCellData的样式清空, 不然后面还有一个拦截器 FillStyleCellWriteHandler 默认会将 WriteCellStyle 设置到
// cell里面去 会导致自己设置的不一样
context.getFirstCellData().setWriteCellStyle(null);
}
}
}
}
到此就可以实现上述excel样式了。
easyExcel多行表头设定不同样式和特定单元格设定样式的实现的更多相关文章
- NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel
NPOI.dll 用法.单元格,样式,字体,颜色,行高,宽度.读写excel 转载:http://yuncode.net/code/c_531e679b3896495 view source prin ...
- ExtJs GridPanel 给表格行或者单元格自定义样式
Ext.onReady(function(){ Ext.create('Ext.data.Store', { storeId:'simpsonsStore', fields:['name', 'ema ...
- java POI excel 导出复合样式(一个单元格两个字体)
前言:java poi 导出 excel 时,需要设置一个单元格有多个字体样式,有点类似于富文本. 想要达到的效果(一个单元格里): 我使用的 poi 版本是 <dependency> & ...
- python excel单元格及样式
python excel单元格及样式: #!/usr/bin/env python # -*- coding: utf-8 -*-” #只对当前文件的中文编码有效 # Filename : Write ...
- zclip结合easyui实现复制datagrid每行特定单元格数据的功能
在easyui的datagrid里面,实现复制每行特定单元格的功能,关键是想想如何获取到每个单元格的数据,功能是点击按钮"复制",然后复制object的下载地址,截图如下所示: 进 ...
- 转载 NPOI.dll 用法。单元格,样式,字体,颜色,行高,宽度。读写excel
我用的版本是1.25的.每个版本用法有一点不同 using System; using System.Collections.Generic; using System.ComponentModel; ...
- C# Excel行高、列宽、合并单元格、单元格边框线、冻结
private _Workbook _workBook = null;private Worksheet _workSheet = null;private Excel.Application _ex ...
- [Xcode 实际操作]五、使用表格-(8)自定义UITableView单元格Accessory样式(附件图标)
目录:[Swift]Xcode实际操作 本文将演示如何自定义单元格的附件图标. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit //首先添 ...
- datagrid单元格格式化样式化
本文体验datagrid单元格的格式化和样式化. datagrid显示的DOM结构 <td field="code"> <div style="te ...
- C#_Excel数据读取与写入_自定义解析封装类_支持设置标题行位置&使用excel表达式收集数据&单元格映射&标题映射&模板文件的参数数据替换
本篇博客园是被任务所逼,而已有的使用nopi技术的文档技术经验又不支持我需要的应对各种复杂需求的苛刻要求,只能自己造轮子封装了,由于需要应对很多总类型的数据采集需求,因此有了本篇博客的代码封装,下面一 ...
随机推荐
- Linux编写Shell脚本获取指定目录下所有文件并处理
Linux编写Shell脚本获取指定目录下所有文件进行处理并保存到新目录 #!/bin/bash app_name="shell" path="/dir" #原 ...
- #根号分治,动态规划#洛谷 5616 [MtOI2019]恶魔之树
题目传送门 分析 最小公倍数最终一定会被表示成若干个质数指数幂的情况(1的情况就直接乘上二的次幂) 然后每个数的加入相当于对每个质数的指数取最大值,但是如果将每个质数的次数都表示出来状态数很多, 考虑 ...
- Mysql Order 排序的时候占用很长时间解决思路
MySQL中的连表查询(JOIN)在进行ORDER BY排序时可能会变得很慢,尤其是当处理大量数据时.以下是一些优化策略,可以帮助减少排序操作的时间: 索引优化: 确保参与排序的列上有索引.如果排序的 ...
- 一文总结ACE代码框架
一.前言 ACE_Engine框架是OpenAtom OpenHarmony(简称"OpenHarmony")的UI开发框架,为开发者提供在进行应用UI开发时所必需的各种组件,以及 ...
- OpenHarmony Liteos_A内核之iperf3移植心得
一.iperf3工作原理 iperf3主要的功能是测试基于特定路径的带宽,在客户端和服务器端建立连接(三次握手)后,客户端发送一定大小的数据报并记下发送的时间,或者客户端在一定的时间内发送数据并记下发 ...
- abcde =(ab+cd)的平方
int i, a, b; for (i = 1000; i < 10000; i++) { a = i / 100; b = i % 100; if ((a + b) * (a + b) == ...
- Windows系统编译libhv带SSL,开启WITH_OPENSSL
需要开发一个https的服务,使用libhv来做,需要重新编译libhv,需要开启 WITH_OPENSSL,前面编译一直很顺利,但是打开VS生成动态库的时候,报错,找不到ssl相关的文件,看了官方的 ...
- HarmonyOS线上Codelabs系列挑战赛第二期:调用三方库,制作酷炫的视觉效果
HarmonyOS线上Codelabs系列挑战赛正如火如荼进行中,开发者们可以通过体验基于HarmonyOS特性和能力的应用开发,快速构建有趣.有用的应用程序.火速加入,与众多开发者一起碰撞想法, ...
- HarmonyOS自动化测试框架—Hypium
原文:https://mp.weixin.qq.com/s/nb5txfDcmGn_VZJXRPEYUQ,点击链接查看更多技术内容. 应用开发过程中,要确保应用的功能和界面能满足预期,往往需要通过测试 ...
- 纯钧chunjun的http-x插件修复
简介 chunjun是一款基于flink的开源数据同步工具,官方文档,其提供了很多flink官方未提供的插件供大家来使用,特别是达梦插件在国产化环境中很方便! 本次介绍的是chunjun中的一款htt ...