当前位置: 首页 > news >正文

easyexcel合并单元格底色

一、效果图

二、导出接口代码

 @PostMapping("selectAllMagicExport")public void selectAllMagicExport(HttpServletRequest request, HttpServletResponse response) throws IOException {ServiceResult<SearchResult<TestMetLineFe2o3Export>> result = success(searcher.search(TestMetLineFe2o3Export.class, MapUtils.flat(request.getParameterMap())));SearchResult<TestMetLineFe2o3Export> searchResult = result.getData();List<TestMetLineFe2o3Export> dataList = searchResult.getDataList();// Excel格式:入厂日期相同日期合并// 设置响应头信息response.setContentType("application/vnd.ms-excel");response.setCharacterEncoding("utf-8");response.setHeader("Content-disposition", "attachment;filename=chatEduExport.xlsx");// 使用EasyExcel进行导出ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), TestMetLineFe2o3Export.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).registerWriteHandler(new ExcelFillCellMergeStrategy(1, new int[]{1, 4, 5, 6, 12, 14})).build();WriteSheet writeSheet = EasyExcel.writerSheet("铁红").build();excelWriter.write(dataList, writeSheet);excelWriter.finish();}

三、拦截器


import cn.hutool.core.util.ReUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.handler.context.CellWriteHandlerContext;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.ciih.workshop.entity.TestMetLineFe2o3Export;
import com.ciih.workshop.utils.HexToRGB;
import com.ejlchina.searcher.BeanSearcher;
import lombok.Data;
import org.apache.poi.hssf.usermodel.HSSFPalette;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;/*** 合并单元格*/
@Component
@Data
public class ExcelFillCellMergeStrategy implements CellWriteHandler {@Resourceprivate BeanSearcher searcher;// 先声明一个对象private static ExcelFillCellMergeStrategy excelFillCellMergeStrategy;//启动注入@PostConstructpublic void init() {excelFillCellMergeStrategy = this;excelFillCellMergeStrategy.searcher = this.searcher;}/*** 合并字段的下标,如第一到五列new int[]{0,1,2,3,4}*/private int[] mergeColumnIndex;/*** 从第几行开始合并,如果表头占两行,这个数字就是2*/private int mergeRowIndex;public ExcelFillCellMergeStrategy() {}public ExcelFillCellMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {this.mergeRowIndex = mergeRowIndex;this.mergeColumnIndex = mergeColumnIndex;}@Overridepublic void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,Head head, Integer integer, Integer integer1, Boolean aBoolean) {}@Overridepublic void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,Head head, Integer integer, Boolean aBoolean) {}@Overridepublic void afterCellDispose(CellWriteHandlerContext context) {// 当前单元格Cell cell = context.getCell();//当前行int curRowIndex = context.getCell().getRowIndex();//当前列int curColIndex = context.getCell().getColumnIndex();if (curRowIndex > mergeRowIndex) {for (int i = 0; i < mergeColumnIndex.length; i++) {if (curColIndex == mergeColumnIndex[i]) {// 合并单元格mergeWithPrevRow(context.getWriteSheetHolder(), context.getCell(), curRowIndex, curColIndex);break;}}}// 设置内容居中WriteCellData<?> cellData = context.getFirstCellData();WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();writeCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);writeCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);// 设置边框writeCellStyle.setBorderBottom(BorderStyle.THIN);writeCellStyle.setBorderLeft(BorderStyle.THIN);writeCellStyle.setBorderRight(BorderStyle.THIN);writeCellStyle.setBorderTop(BorderStyle.THIN);// 忽略表头if (cell.getRowIndex() > 0) {// 底色coloring(context, writeCellStyle, cell, curRowIndex, curColIndex);}}/*** 着色** @param writeCellStyle* @param cell* @param curRowIndex    当前行* @param curColIndex    当前列*/private void coloring(CellWriteHandlerContext context, WriteCellStyle writeCellStyle, Cell cell, int curRowIndex, int curColIndex) {// 设置单元格颜色// 拿到当前行的所有数据Cell curInDateCell = cell.getSheet().getRow(curRowIndex).getCell(0); // 唯一编号double id = curInDateCell.getNumericCellValue();// 完整数据HashMap<String, Object> flat = new HashMap<>();flat.put("id", (long) id);TestMetLineFe2o3Export fe2o3Export = excelFillCellMergeStrategy.searcher.searchFirst(TestMetLineFe2o3Export.class, flat);// 渲染入场批号的颜色if (cell.getColumnIndex() == 4) {coloringAction(fe2o3Export.getTestMetInnumStandardColor(), writeCellStyle);// 加批注noteAction(context, cell, fe2o3Export.getTestMetInnumStandardLevel());}// 氯根着色if (cell.getColumnIndex() == 7) {coloringAction(fe2o3Export.getLgStandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getLgStandardLevel());}// 水分着色if (cell.getColumnIndex() == 8) {coloringAction(fe2o3Export.getWaterStandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getWaterStandardLevel());}// 粒度着色if (cell.getColumnIndex() == 10) {coloringAction(fe2o3Export.getLdStandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getLdStandardLevel());}// Na2O着色if (cell.getColumnIndex() == 17) {coloringAction(fe2o3Export.getNa2oStandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getNa2oStandardLevel());}// Al2O3着色if (cell.getColumnIndex() == 19) {coloringAction(fe2o3Export.getAl2o3StandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getAl2o3StandardLevel());}// SiO2着色if (cell.getColumnIndex() == 20) {coloringAction(fe2o3Export.getSio2StandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getSio2StandardLevel());}// CaO着色if (cell.getColumnIndex() == 24) {coloringAction(fe2o3Export.getCaoStandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getCaoStandardLevel());}// Cr2O3着色if (cell.getColumnIndex() == 26) {coloringAction(fe2o3Export.getCr2o3StandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getCr2o3StandardLevel());}// MnO着色if (cell.getColumnIndex() == 27) {coloringAction(fe2o3Export.getMnoStandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getMnoStandardLevel());}// Fe2O3着色if (cell.getColumnIndex() == 28) {coloringAction(fe2o3Export.getFe2o3StandardColor(), writeCellStyle);noteAction(context, cell, fe2o3Export.getFe2o3StandardLevel());}}/*** 批注*/private void noteAction(CellWriteHandlerContext context, Cell cell, String content) {if (StrUtil.isBlank(content)) {return;}Sheet sheet = context.getWriteSheetHolder().getSheet();ClientAnchor anchor = new XSSFClientAnchor();//关键修改anchor.setDx1(0);anchor.setDx2(0);anchor.setDy1(0);anchor.setDy2(0);anchor.setCol1(cell.getColumnIndex());anchor.setRow1(cell.getRowIndex());anchor.setCol2(cell.getColumnIndex());anchor.setRow2(cell.getRowIndex());Drawing<?> drawingPatriarch = sheet.createDrawingPatriarch();Comment cellComment = drawingPatriarch.createCellComment(anchor);cellComment.setString(new XSSFRichTextString(content));cell.setCellComment(cellComment);}/*** 着色动作*/private void coloringAction(String color, WriteCellStyle writeCellStyle) {if (color == null) {return;}Integer r = null;Integer g = null;Integer b = null;//if (color.startsWith("#")) {int[] ints = HexToRGB.hexToRGB(color);r = ints[0];g = ints[1];b = ints[2];} else {List<String> all01 = ReUtil.findAll("(?<=\\().*?(?=\\))", color, 0);if (all01 != null && all01.size() > 0 && all01.get(0).split(",").length >= 3) {String[] split = all01.get(0).split(",");// RGB颜色转换r = Integer.parseInt(split[0].trim());g = Integer.parseInt(split[1].trim());b = Integer.parseInt(split[2].trim());}}if (r != null && g != null && b != null) {HSSFWorkbook wb = new HSSFWorkbook();HSSFPalette palette = wb.getCustomPalette();HSSFColor hssfColor = palette.findSimilarColor(r, g, b);
//                writeCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());writeCellStyle.setFillForegroundColor(hssfColor.getIndex());writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);}}private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {//获取当前行的当前列的数据和上一行的当前列列数据,通过上一行数据是否相同进行合并Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() :cell.getNumericCellValue();Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() :preCell.getNumericCellValue();// 如果是日期列,即第一列,只要相同就合并if (cell.getColumnIndex() == 1) {if (curData.equals(preData)) {Sheet sheet = writeSheetHolder.getSheet();List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();boolean isMerged = false;for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {CellRangeAddress cellRangeAddr = mergeRegions.get(i);// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {sheet.removeMergedRegion(i);cellRangeAddr.setLastRow(curRowIndex);sheet.addMergedRegion(cellRangeAddr);isMerged = true;}}// 若上一个单元格未被合并,则新增合并单元if (!isMerged) {CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,curColIndex);sheet.addMergedRegion(cellRangeAddress);}}} else {// 如果日期和批号与上一行的日期和批号相同。则进行当前行列的合并// 当前行的日期和批号Cell curInDateCell = cell.getSheet().getRow(curRowIndex).getCell(1);Object curInDate = curInDateCell.getCellTypeEnum() == CellType.STRING ? curInDateCell.getStringCellValue() : curInDateCell.getNumericCellValue();Cell curInNumCell = cell.getSheet().getRow(curRowIndex).getCell(4);Object curInNum = curInNumCell.getCellTypeEnum() == CellType.STRING ? curInNumCell.getStringCellValue() : curInNumCell.getNumericCellValue();// 上一行的日期和批号Cell preInDateCell = cell.getSheet().getRow(curRowIndex - 1).getCell(1);Object preInDate = preInDateCell.getCellTypeEnum() == CellType.STRING ? preInDateCell.getStringCellValue() : preInDateCell.getNumericCellValue();Cell preInNumCell = cell.getSheet().getRow(curRowIndex - 1).getCell(4);Object preInNum = preInNumCell.getCellTypeEnum() == CellType.STRING ? preInNumCell.getStringCellValue() : preInNumCell.getNumericCellValue();if (curInDate.equals(preInDate) && curInNum.equals(preInNum)) {Sheet sheet = writeSheetHolder.getSheet();List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();boolean isMerged = false;for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {CellRangeAddress cellRangeAddr = mergeRegions.get(i);// 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {sheet.removeMergedRegion(i);cellRangeAddr.setLastRow(curRowIndex);sheet.addMergedRegion(cellRangeAddr);isMerged = true;}}// 若上一个单元格未被合并,则新增合并单元if (!isMerged) {CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex,curColIndex);sheet.addMergedRegion(cellRangeAddress);}}}}
}

相关文章:

easyexcel合并单元格底色

一、效果图 二、导出接口代码 PostMapping("selectAllMagicExport")public void selectAllMagicExport(HttpServletRequest request, HttpServletResponse response) throws IOException {ServiceResult<SearchResult<TestMetLineFe2o3Export>> result …...

OpenCV图片校正

OpenCV图片校正 背景几种校正方法1.傅里叶变换 霍夫变换 直线 角度 旋转3.四点透视 角度 旋转4.检测矩形轮廓 角度 旋转参考 背景 遇到偏的图片想要校正成水平或者垂直的。 几种校正方法 对于倾斜的图片通过矫正可以得到水平的图片。一般有如下几种基于opencv的组合方…...

数字孪生流域共建共享相关政策解读

当前数字孪生技术在水利方面的应用刚起步&#xff0c;2021年水利部首次提出“数字孪生流域”概念&#xff0c;即以物理流域为单元、时空数据为底座、数学模型为核心、水利知识为驱动&#xff0c;对物理流域全要素和水利治理管理活动全过程的数字映射、智能模拟、前瞻预演&#…...

FSC147数据集格式解析

一. 引言 在研究很多深度学习框架的时候&#xff0c;往往需要使用到FSC147格式数据集&#xff0c;若要是想在自己的数据集上验证深度学习框架&#xff0c;就需要自己制作数据集以及相关标签&#xff0c;在论文Learning To Count Everything中&#xff0c;该数据集首次被提出。 …...

el-element中el-tabs案例的使用

el-element中el-tabs的使用 代码呈现 <template><div class"enterprise-audit"><div class"card"><div class"cardTitle"><p>交易查询</p></div><el-tabs v-model"activeName" tab-cl…...

tomcat结构目录有哪些?

bin 启动&#xff0c;关闭和其他脚本。这些 .sh文件&#xff08;对于Unix系统&#xff09;是这些.bat文件的功能副本&#xff08;对于 Windows系统&#xff09;。由于Win32命令行缺少某些功能&#xff0c;因此此处包含一些其他文件。 比如说&#xff1a;windows下启动tomcat用的…...

生成式AI系列 —— DCGAN生成手写数字

1、模型构建 1.1 构建生成器 # 导入软件包 import torch import torch.nn as nnclass Generator(nn.Module):def __init__(self, z_dim20, image_size256):super(Generator, self).__init__()self.layer1 nn.Sequential(nn.ConvTranspose2d(z_dim, image_size * 32,kernel_s…...

vscode-vue项目格式化+语法检验-草稿

Vue学习笔记7 - 在Vscode中配置Vetur&#xff0c;ESlint&#xff0c;Prettier_vetur规则_Myron.Maoyz的博客-CSDN博客...

【Java从0到1学习】10 Java常用类汇总

1. System类 System类对读者来说并不陌生&#xff0c;因为在之前所学知识中&#xff0c;需要打印结果时&#xff0c;使用的都是“System.out.println();”语句&#xff0c;这句代码中就使用了System类。System类定义了一些与系统相关的属性和方法&#xff0c;它所提供的属性和…...

第三届人工智能与智能制造国际研讨会(AIIM 2023)

第三届人工智能与智能制造国际研讨会&#xff08;AIIM 2023&#xff09; The 3rd International Symposium on Artificial Intelligence and Intelligent Manufacturing 第三届人工智能与智能制造国际研讨会&#xff08;AIIM 2023&#xff09;将于2023年10月27-29日在成都召开…...

层次分析法

目录 一&#xff1a;问题的引入 二&#xff1a;模型的建立 1.分析系统中各因素之间的关系&#xff0c;建立系统的递阶层次结构。 2.对于同一层次的各元素关于上一层次中某一准则的重要性进行两两比较&#xff0c;构造两两比较矩阵&#xff08;判断矩阵&#xff09;。 3.由判…...

Error Handling

有几个特定的异常类允许用户代码对与CAN总线相关的特定场景做出反应: Exception (Python standard library)+-- ...+-- CanError (python-can)+-- CanInterfaceNotImplementedError+-- CanInitializationError...

leetcode:字符串相乘(两种方法)

题目&#xff1a; 给定两个以字符串形式表示的非负整数 num1 和 num2&#xff0c;返回 num1 和 num2 的乘积&#xff0c;它们的乘积也表示为字符串形式。 注意&#xff1a;不能使用任何内置的 BigInteger 库或直接将输入转换为整数。 示例 1: 输入: num1 "2", nu…...

【爬虫练习之glidedsky】爬虫-基础2

题目 链接 爬虫往往不能在一个页面里面获取全部想要的数据&#xff0c;需要访问大量的网页才能够完成任务。 这里有一个网站&#xff0c;还是求所有数字的和&#xff0c;只是这次分了1000页。 思路 找到调用接口 可以看到后面有个参数page来控制页码 代码实现 import reques…...

03.有监督算法——决策树

1.决策树算法 决策树算法可以做分类&#xff0c;也可以做回归 决策树的训练与测试&#xff1a; 训练阶段&#xff1a;从给定的训练集构造出一棵树&#xff08;从根节点开始选择特征&#xff0c;如何进行特征切分&#xff09; 测试阶段&#xff1a;根据构造出来的树模型从上…...

网络协议详解之STP

目录 一、STP协议&#xff08;生成树&#xff09; 1.1 生成树协议核心知识点&#xff1a; 1.2 生成树协议与导致问题&#xff1a; 生成树含义&#xff1a; 1.3 802.1D 规则&#xff1a; 802.1D 缺点&#xff1a; 1.4 PVST cisco私有 1.5 PVST 1.6 快速生成树 快速的原…...

Eltima USB Network Gate 10.0 Crack

USB Network Gate -通过网络共享USB 设备 USB Network Gate (前身为以太网USB控制器USB) 轻松的通过网络(Internet/LAN/WAN)分享您的一个或者多个连接到您计算机的USB设备。 无论您身处异国还是近在隔壁办公室&#xff0c;您都可以轻松使用远程扫描仪、打印机、摄像头、调制解…...

SpringCloudGateway网关实战(一)

SpringCloudGateway网关实战&#xff08;一&#xff09; 目前对cloud的gateway功能还是不太熟悉&#xff0c;因此特意新建了对应的应用来尝试网关功能。 网关模块搭建 首先我们新建一个父模块用于添加对应的springboot依赖和cloud依赖。本模块我们的配置读取使用的是nacos&a…...

django中使用ajax发送请求

1、ajax简单介绍 浏览器向网站发送请求时 是以URL和表单的形式提交的post 或get 请求&#xff0c;特点是&#xff1a;页面刷新 除此之外&#xff0c;也可以基于ajax向后台发送请求&#xff08;异步&#xff09; 依赖jQuery 编写ajax代码 $.ajax({url: "发送的地址"…...

C++之std::list<string>::iterator迭代器应用实例(一百七十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存

文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏

一、引言 在深度学习中&#xff0c;我们训练出的神经网络往往非常庞大&#xff08;比如像 ResNet、YOLOv8、Vision Transformer&#xff09;&#xff0c;虽然精度很高&#xff0c;但“太重”了&#xff0c;运行起来很慢&#xff0c;占用内存大&#xff0c;不适合部署到手机、摄…...

离线语音识别方案分析

随着人工智能技术的不断发展&#xff0c;语音识别技术也得到了广泛的应用&#xff0c;从智能家居到车载系统&#xff0c;语音识别正在改变我们与设备的交互方式。尤其是离线语音识别&#xff0c;由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力&#xff0c;广…...

华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)

题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

FOPLP vs CoWoS

以下是 FOPLP&#xff08;Fan-out panel-level packaging 扇出型面板级封装&#xff09;与 CoWoS&#xff08;Chip on Wafer on Substrate&#xff09;两种先进封装技术的详细对比分析&#xff0c;涵盖技术原理、性能、成本、应用场景及市场趋势等维度&#xff1a; 一、技术原…...

Linux操作系统共享Windows操作系统的文件

目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项&#xff0c;设置文件夹共享为总是启用&#xff0c;点击添加&#xff0c;可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download&#xff08;这是我共享的文件夹&#xff09;&…...