easyexcel合并单元格底色

news2024/11/24 6:46:41

一、效果图

二、导出接口代码

 @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 {
    @Resource
    private BeanSearcher searcher;
    // 先声明一个对象
    private static ExcelFillCellMergeStrategy excelFillCellMergeStrategy;

    //启动注入
    @PostConstruct
    public 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;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row,
                                 Head head, Integer integer, Integer integer1, Boolean aBoolean) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell,
                                Head head, Integer integer, Boolean aBoolean) {

    }

    @Override
    public 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);
                }
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/892041.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

企业百家号蓝V认证后,百度营销基木鱼落地页如何嵌入百家号中

首先搭建百度营销基木鱼落地页 在我们的百度营销后台&#xff0c;点击基木鱼跳转至百度营销基木鱼页面&#xff0c;在我的站点位置&#xff0c;可以创建H5站点&#xff0c;PC站点等&#xff0c;创建完成后可以点击复制基木鱼落地页的链接。 注意事项 1、企业百家号需要进行…

【C++ 记忆站】命名空间

文章目录 命名空间概念命名空间的定义1、正常的命名空间定义2、命名空间可以嵌套3、同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中 命名空间的使用1、加命名空间名称及作用域限定符2、使用using将命名空间中某个成员引入3、使用using namespac…

计算机竞赛 python的搜索引擎系统设计与实现

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python的搜索引擎系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;5分创新点&#xff1a;3分 该项目较为新颖&#xff…

C++基础语法——继承

1.继承是什么&#xff1f; 继承是一种面向对象编程的概念&#xff0c;它允许一个类&#xff08;称为子类或派生类&#xff09;从另一个类&#xff08;称为基类或父类&#xff09;继承属性和方法。继承使得子类能够使用基类已有的代码&#xff0c;并且可以在此基础上进行扩展或修…

【IEEE会议】第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023)

第二届IEEE云计算、大数据应用与软件工程国际学术会议 (CBASE2023&#xff09; 随着大数据时代的到来&#xff0c;对数据获取的随时性和对计算的需求也在逐渐增长。为推动大数据时代的云计算与软件工程的发展&#xff0c;促进该领域学术交流&#xff0c;在CBASE 2022成功举办的…

ChatGpt开源项目完美运行配置-ChatGml2

任务描述 本节任务是安装和配置chatgpt项目所需的软件以及chatgpt项目所需要的python库包&#xff0c;同时编写python代码来完成chatgpt项目的人机对话功能。 实验工具 显卡GTX1070&#xff08;专用内存需要大于等于6G&#xff09;以上电脑、Pycharm软件、Python3.10软件、cud…

船舶法兰盘法兰管件3D扫描尺寸测量|三维扫描检测|CAV测量-CASAIM

第一章 服务背景 船舶建造多采用分段建造法&#xff0c;即将零件、预装好的部件在胎架上组合焊接成分段或总段&#xff0c;然后由船台装配成整船的建造方法。而当船体合拢组装时&#xff0c;在船体上遍布着各种各样的管道&#xff0c;这些管道都需要互相完全适配以确保船体安装…

python print 输出格式化的几种方式

# 对浮点数&#xff0c;保留小数点后几位 print({:0.3f}.format(50.5 / 220.5)) # print 格式化字符串 num int(input(请输入一个十进制的整数&#xff1a;)) # 将str 转为int类型 print(num, 的二进制数为&#xff1a;, bin(num)) # 第一种写法使用了个数可变的位置参数 pr…

JavaWeb_LeadNews_Day6-Kafka

JavaWeb_LeadNews_Day6-Kafka Kafka概述安装配置kafka入门kafka高可用方案kafka详解生产者同步异步发送消息生产者参数配置消费者同步异步提交偏移量 SpringBoot集成kafka 自媒体文章上下架实现思路具体实现 来源Gitee Kafka 概述 对比 选择 介绍 producer: 发布消息的对象称…

JVM——配置常用参数,GC调优策略

文章目录 JVM 配置常用参数Java内存区域常见配置参数概览堆参数回收器参数项目中常用配置常用组合 常用 GC 调优策略GC 调优原则GC 调优目的GC 调优策略 JVM 配置常用参数 Java内存区域常见配置参数概览堆参数&#xff1b;回收器参数&#xff1b;项目中常用配置&#xff1b;常…

一、数学建模之线性规划篇

1.定义 2.例题 3.使用软件及解题 一、定义 1.线性规划&#xff08;Linear Programming&#xff0c;简称LP&#xff09;是一种数学优化技术&#xff0c;线性规划作为运筹学的一个重要分支&#xff0c;专门研究在给定一组线性约束条件下&#xff0c;如何找到一个最优的决策&…

YOLOv1基础

目录 深度学习经典检测方法指标分析核心思想网络架构损失函数非极大值抑制优缺点 深度学习经典检测方法 预选框&#xff0c;在论文中叫RPN&#xff0c;也就是区域建议网络 指标分析 核心思想 网络架构 损失函数 非极大值抑制 优缺点

【java毕业设计】基于Spring Boot+Vue+mysql的论坛管理系统设计与实现(程序源码)-论坛管理系统

基于Spring BootVuemysql的论坛管理系统设计与实现&#xff08;程序源码毕业论文&#xff09; 大家好&#xff0c;今天给大家介绍基于Spring BootVuemysql的论坛管理系统设计与实现&#xff0c;本论文只截取部分文章重点&#xff0c;文章末尾附有本毕业设计完整源码及论文的获取…

ssh远程连接慢解决方法

一、关闭SERVER上的GSS认证 将GSSAPIAuthentication改为no ,如果在配置文件中&#xff0c;以下值是被注释的就拿掉注释&#xff0c;因为默认开关就是yes # vi /etc/ssh/sshd_config GSSAPIAuthentication no二、关闭SERVER上DNS反向解析 在linux中&#xff0c;默认就是开启了S…

java代码审计11.1之反序列化基础学习

文章目录 1、 序列化与反序列化2、序列化与反序列化案例2.1、使用idea生成代码与serialVersionUID2.2、实例化对象2.3、序列化对象2.4、反序列化 3、稍微深入serialVersionUID综上小结&#xff0c; 4、transient 作⽤5、反序列化漏洞 之前的文章&#xff0c; php代码审计15.1之…

部署piwigo网页 通过cpolar分享本地电脑上的图片

通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页 文章目录 通过cpolar分享本地电脑上有趣的照片&#xff1a;发布piwigo网页前言1. 设定一条内网穿透数据隧道2. 与piwigo网站绑定3. 在创建隧道界面填写关键信息4. 隧道创建完成 总结 前言 首先在本地电脑上部署…

微服务最佳实践,零改造实现 Spring Cloud Apache Dubbo 互通

作者&#xff1a;孙彩荣 很遗憾&#xff0c;这不是一篇关于中间件理论或原理讲解的文章&#xff0c;没有高深晦涩的工作原理分析&#xff0c;文后也没有令人惊叹的工程数字统计。本文以实际项目和代码为示例&#xff0c;一步一步演示如何以最低成本实现 Apache Dubbo 体系与 S…

k8s集群监控方案--node-exporter+prometheus+grafana

目录 前置条件 一、下载yaml文件 二、部署yaml各个组件 2.1 node-exporter.yaml 2.2 Prometheus 2.3 grafana 2.4访问测试 三、grafana初始化 3.1加载数据源 3.2导入模板 四、helm方式部署 前置条件 安装好k8s集群&#xff08;几个节点都可以&#xff0c;本人为了方便实验k8s集…

搭载KaihongOS的工业平板、机器人、无人机等产品通过3.2版本兼容性测评,持续繁荣OpenHarmony生态

近日&#xff0c;搭载深圳开鸿数字产业发展有限公司&#xff08;简称“深开鸿”&#xff09;KaihongOS软件发行版的工业平板、机器人、无人机等商用产品均通过OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;3.2 Release版本兼容性测评&#xff0c;获颁O…

探索Perfetto:开源性能追踪工具的未来之光

探索Perfetto&#xff1a;开源性能追踪工具的未来之光 1. 引言 A. 介绍Perfetto的背景和作用 随着移动应用、桌面软件和嵌入式系统的不断发展&#xff0c;软件性能优化变得愈发重要。在这个背景下&#xff0c;Perfetto作为一款开源性能追踪工具&#xff0c;日益引起了开发者…