【EasyExcel】导出excel并支持自定义设置数据行背景颜色等

news2024/12/24 9:00:08

需求背景:

        根据查询条件将列表数据导出,并筛选出满足某个条件的数据,将满足条件的数据的背景颜色设置成黄色。
        (本文例子如:name出现的次数大于等于2,将相关数据背景颜色都设置为黄色)

一、技术选型:

        1、easyExcel的自定义写策略处理:CellWriteHandler

        2、poi自带的写数据行处理:Workbook

思考选定:

        由于目前系统中多处使用的是file插件导出类,是由统一形成的,直接改动,对其它项目引入,从而导出的性能产生一定的影响,所以选择自定义策略实现,故选1。

二、方案设计:(基于实现 CellWriteHandler 接口)

        1、在 beforeCellCreate 方法中统计出 每个数据行的 name 出现的次数,在 afterCellDispose 方法中处理满足设置背景颜色数据的背景颜色。

        2、直接传入数据行的索引,在 afterCellDispose 方法中处理满足设置背景颜色数据的背景颜色。

note:原本考虑的是选择1,但是在实现的时候,统计name出现次数一直会出现问题,在easeExcel的源码中:beforeCellCreate 操作数据出现问题,待处理。(码友们可自行尝试!!!)故暂选择 方案2 实现当前需求。

三、代码实现:

pom.xml:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>

API:

 @ApiOperation(value = "评论审核导出")
 @GetMapping(value = "/export")
 public void exportExcel(HttpServletResponse response, TestParam param) throws BaseException {
        service.export(response, param);
 }
实现层:
public class TestExcelService {

    private static final String FILE_NAME = "测试文件名字";
    private static final String SHEET_NAME = "测试";

    private final IEasyExcelService easyExcelService;
    public SeedDemandExcelService(IEasyExcelService easyExcelService) {
        this.easyExcelService = easyExcelService;
    }

    public void export(HttpServletResponse response, TestParam param) throws BaseException{
        // 根据查询参数获取查询到的数据(根据自己的查询方法在这里将数据查询出来)
        List<TestExcelData> exportData = this.getExportData(param);
        // Obtain data rows that require background color settings
        // 获取需要设置背景颜色的数据行索引
        List<Integer> index = getIndexList(exportData);
        // export
        try {
            easyExcelService.exportExcelWithBackGround(exportData, response, DemoExcelData.class, FILE_NAME, SHEET_NAME, index);
        } catch (Exception e) {
            throw new Exception(CodeEnum.FAILED, "导出异常,请联系开发人员!异常信息是:" + e.getMessage());
        }
    }
}
工具类:IEasyExcelService
public interface IEasyExcelService {
    /**
     * 导出excel方法
     * @param exportData 需要导出的数据
     * @param response response
     * @param tClass 导出excel的字段实体类
     * @param fileName 文件名字
     * @param sheetName sheet名字
     */
    <T> void exportExcel(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName);
    /**
     * 导出excel方法(支持设置背景颜色)
     * @param exportData 需要导出的数据
     * @param response response
     * @param tClass 导出excel的字段实体类
     * @param fileName 文件名字
     * @param sheetName sheet名字
     * @param backGroundIndex 需要设置背景的数据行
     * @param <T> t
     * @throws Exception Exception
     */
    <T> void exportExcelWithBackGround(List<T> exportData, HttpServletResponse response, Class<T> tClass , String fileName, String sheetName, List<Integer> backGroundIndex) throws Exception;
}
工具类:EasyExcelServiceImpl
@Service
@Slf4j
public class EasyExcelServiceImpl implements IEasyExcelService {

    @Override
    public <T> void exportExcel(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName){
        try{
            // 使用swagger 会导致各种问题,直接用浏览器或者用postman
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // fileName encoder
            String fileNameEncoder = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
            // write to excel
            EasyExcelFactory.write(response.getOutputStream(), tClass)
                    .autoCloseStream(Boolean.FALSE)
                    .sheet(sheetName)
                    .doWrite(exportData);
        }catch (Exception e){
            log.error("EasyExcelServiceImpl->exportExcel error, message is :{}", e.getMessage());
        }
    }

    @Override
    public <T> void exportExcelWithBackGround(List<T> exportData, HttpServletResponse response, Class<T> tClass,
                                              String fileName, String sheetName, List<Integer> backGroundIndex) throws Exception {
        // 使用swagger 会导致各种问题,直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // fileName encoder
        String fileNameEncoder = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
        // 自定义策略
        Set<Integer> yellowRowsSet = new HashSet<>(backGroundIndex);
        SeedDemandCellWriteHandler seedDemandCellWriteHandler = new SeedDemandCellWriteHandler(yellowRowsSet);
        // write to excel
        EasyExcelFactory.write(response.getOutputStream(), tClass)
                // 自定义背景颜色策略
                .registerWriteHandler(seedDemandCellWriteHandler)
                .inMemory(Boolean.TRUE)
                .autoCloseStream(Boolean.FALSE)
                .sheet(sheetName)
                .doWrite(exportData);
    }

}
(其中registerWriteHandler支持扩展多个,可以通过HorizontalCellStyleStrategy策略设置全局的配置,如背景颜色、字体、合并单元格等)

自定义Handle:(自定义设置数据行背景颜色)

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.util.BooleanUtils;
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 org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import java.util.Set;

/**
 * @author c
 */
public class CustomCellWriteHandler implements CellWriteHandler {

    /**
     * 标黄行宽集合
     */
    private final Set<Integer> yellowRowIndex;

    public CustomCellWriteHandler(Set<Integer> yellowRowIndex) {
        this.yellowRowIndex = yellowRowIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {
        // 源码context中row待优化:支持入参 获取需要字段的出现次数 从而设置背景颜色
        // to do:(row.getCell(columnIndex)失效)
    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // empty
    }

    @Override
    public void afterCellDispose(CellWriteHandlerContext context) {
        if (BooleanUtils.isNotTrue(context.getHead())) {
            // 获取当前行的行号
            Integer currentRowIndex = context.getRowIndex();
            // 判断当前行是否在yellowRowIndex's中
            if (yellowRowIndex.contains(currentRowIndex)) {
                // 设置背景颜色,也可以设置字体等其它元素
                WriteCellData<?> cellData = context.getFirstCellData();
                WriteCellStyle writeCellStyle = cellData.getOrCreateStyle();
                writeCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());
                writeCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
            }
        }
    }

}
DemoExcelData:(导出字段实体类)
@Data
@EqualsAndHashCode
public class DemoExcelData{

    @ExcelProperty(value = "TaskID", index = 0)
    private String name;
    @ExcelProperty(value = "taskName", index = 1)
    private String sex;
    @ExcelProperty(value = "taskName", index = 2)
    private String age;
}

End:

        👍如果对你有帮助,给博主一个免费的点赞以示鼓励
欢迎各位🔎点赞👍评论收藏⭐️

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

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

相关文章

代码签名证书是如何保护软件?

随着互联网的普及和技术的发展&#xff0c;软件开发已经成为了一个非常重要的行业。然而&#xff0c;软件安全问题也日益凸显&#xff0c;恶意软件、病毒、木马等威胁着用户的数据安全和隐私。为了确保软件的安全和可靠性&#xff0c;开发者需要采取一系列措施来保护他们的产品…

在线教育行业内卷突围,持续激活平台用户体验是关键

在线教育并不等同于K12教育。 众所周知&#xff0c;越来越卷的考试制度&#xff0c;已经被家长、学生们的谩骂和吐槽淹没了好几层。各种减负、杜绝课后补课等条例纷纷出台&#xff0c;不断的挤压着K12教育企业的生存空间。 于是乎&#xff0c;大家都认为&#xff0c;在线教育…

笔记62:注意力汇聚 --- Nadaraya_Watson 核回归

本地笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\3.循环神经网络\第10章&#xff1a;动手学深度学习~注意力机制 a a a a a a a a a a a a a a a a

一键换肤功能

使用css3的css变量来实现 示例&#xff1a; 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name&qu…

好用的IDEA插件推荐

前言 Idea 是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它可以帮助开发人员更加高效地编写、调试和部署软件应用程序,Idea 还具有许多插件和扩展&#xff0c;可以根据开发人员的需要进行定制和扩展&#xff0c;从而提高开发效率,今天我们就来介绍一款…

使用opencv的matchTemplate进行银行卡卡号识别

![字体文件](https://img-blog.csdnimg.cn/3a16c87cf4d34aceb0778c4b20ddadb2.png#pic_center import cv2 import numpy as npdef show_img(img, name"temp"):img cv2.resize(img, (0, 0), fx3, fy3)cv2.imshow(name, img)cv2.waitKey(0)cv2.destroyAllWindows()de…

Windows10-用户账户控制、Windows远程桌面

Windows10用户账户控制怎么设置白名单 问题引出&#xff1a; 安装低版本搜狗输入法后经常弹出用户账户控制 解决方案&#xff1a; 全局模式&#xff1a; UAC控制最早出现在Windows Vista中&#xff0c;用户帐户控制&#xff08;UAC&#xff09;是一项旨在防止对您的计算机…

2024年进入-1/12的世界

1.从一段与AI的对话开始 cj: 1234...无限的&#xff0b;下去结果是无穷大吗&#xff1f; chatgpt: 是的&#xff0c;从常规的数学观点来看&#xff0c;级数 1234… 无限相加的结果是正无穷。 这是因为每一项都是正数&#xff0c;并且随着项数的增加&#xff0c;部分和会趋近…

校园虚拟化部署与横向扩展统一存储

项目背景 这所隶属教育部直属重点大学&#xff0c;学校设有11个学科体系&#xff0c;现有本硕博学生共29000余人&#xff0c;为积极响应“中国教育现代化2023战略部署”&#xff0c;校方制定教育信息化2.0发展目标&#xff0c;通过平台融合&#xff0c;数据驱动、技术赋能等措…

时间序列预测 — LSTM实现单变量滚动风电预测(Keras)

目录 1 数据处理 1.1 数据集简介 1.2 数据集处理 2 模型训练与预测 2.1 模型训练 2.2 模型滚动预测 2.3 结果可视化 1 数据处理 1.1 数据集简介 实验数据集采用数据集5&#xff1a;风电机组运行数据集&#xff08;下载链接&#xff09;&#xff0c;包括风速、风向、温…

【MySQL】binlog数据恢复

binlog概述 binlog二进制日志记录保存了所有执行过的修改操作语句&#xff0c;不保存查询操作。如果 MySQL 服务意外停止&#xff0c;可通过二进制日志文件排查&#xff0c;用户操作或表结构操作&#xff0c;从而来恢复数据库数据。binlog 是逻辑日志&#xff0c;记录的是这个…

网页设计--第5次课后作业

1、快速学习JavaScript的基本知识第1-10章 JavaScript入门 - 绿叶学习网 2、使用所学的知识完成以下练习。需求如下3个&#xff1a; 1&#xff09;点亮灯泡 2&#xff09;将所有的div标签的标签体内容后面加上&#xff1a; very good 3&#xff09;使所有的复选框呈现被选…

编程在现代社会中的重要性

文章目录 编程的重要性引言编程在现代社会中的重要性常见的编程应用场景结语 编程的重要性 引言 编程在现代社会中的重要性是不言而喻的&#xff0c;它可以让我们创造出各种有用的软件&#xff0c;解决各种复杂的问题&#xff0c;甚至改变世界。 编程在现代社会中的重要性 编…

【Unity细节】用代码控制Rigibody的约束RigidbodyConstraints(刚体约束)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! 本文由 秩沅 原创 &#x1f636;‍&#x1f32b;️收录于专栏&#xff1a;unity细节和bug &#x1f636;‍&#x1f32b;️优质专栏 ⭐【…

我对自动化测试的一些认识

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

〔005〕虚幻 UE5 像素流多用户部署

✨ 目录 ▷ 为什么要部署多用户▷ 开启分发服务器▷ 配置启动多个信令服务器▷配置启动客户端▷多用户启动整体流程和预览▷注意事项▷ 为什么要部署多用户 之前的像素流部署,属于单用户,是有很大的弊端的打开多个窗口访问,可以看到当一个用户操作界面的时候,另一个界面也会…

软件工程--面向对象分析用通俗语言20小时爆肝总结!(包含用例图、活动图、类图、时序图......)

面向对象方法分为面向对象分析&#xff08;OOA&#xff09;、面向对象设计&#xff08;OOD&#xff09;、面向对象编程&#xff08;OOP&#xff09;&#xff0c;本文详细介绍面向对象分析 本文参考教材&#xff1a;沈备军老师的《软件工程原理》大多图片来源其中 目录 面向对…

51单片机项目(14)——基于51单片机的烟雾报警系统

1.设计内容 本次设计的系统功能描述如下&#xff1a; 1.可以测量烟雾浓度并且在屏幕显示&#xff0c;同时显示浓度阈值。 2.可以通过按键对阈值进行加减调节。 3.浓度大于阈值时&#xff0c;蜂鸣器报警&#xff0c;风扇转动&#xff0c;发送报警信息&#xff08;“to high”…

国标GB28181安防视频平台EasyGBS现场突发播放中断是什么原因?

视频流媒体安防监控国标GB28181平台EasyGBS视频能力丰富&#xff0c;部署灵活&#xff0c;既能作为业务平台使用&#xff0c;也能作为安防监控视频能力层被业务管理平台调用。国标GB28181视频EasyGBS平台可提供流媒体接入、处理、转发等服务&#xff0c;支持内网、公网的安防视…

自动驾驶中的LFM(LED 闪烁缓解)问题

自动驾驶中的LFM Reference: 自动驾驶系统如何跨越LFM这道坎&#xff1f; 从路灯、交通灯&#xff0c;到车载照明&#xff0c;低功耗、长寿命、高可靠的 LED 正在快速取代传统照明方式。但 LED 在道路上的普遍使用&#xff0c;却带来“LED闪烁”现象。“LED闪烁”是由 LED 驱…