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

news/2024/7/21 6:06:45 标签: excel

需求背景:

        根据查询条件将列表数据导出,并筛选出满足某个条件的数据,将满足条件的数据的背景颜色设置成黄色。
        (本文例子如: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.niftyadmin.cn/n/5219381.html

相关文章

二维数值型数组例题

1、单位矩阵初始化 题目描述 对用作单位矩阵的数组初始化。单位矩阵在主对角线上的值为1&#xff0c;而其他的地方的值为0&#xff0c;并且主对角线上的行、列下标是一样的。 输入要求 输入一个整数n表示矩阵的行数 输出要求 输出n*n的单位矩阵。数据之间以空格间隔&…

AIGC系列之:Vision Transformer原理及论文解读

目录 相关资料 模型概述 Patch to Token Embedding Token Embedding Position Embedding ViT总结 相关资料 论文链接&#xff1a;https://arxiv.org/pdf/2010.11929.pdf 论文源码&#xff1a;https://github.com/google-research/vision_transformer PyTorch实现代码…

JOSEF 综合继电器 HJZZ-32/2 AC220V 合闸延时整定0.02-9.99S

系列型号&#xff1a; HJZZ-91分闸、合闸、电源监视综合装置&#xff1b; HJZZ-92/1分闸、合闸、电源监视综合装置&#xff1b; HJZZ-92/2分闸、合闸、电源监视综合装置&#xff1b; HJZZ-92/2A分闸、合闸、电源监视综合装置&#xff1b; HJZZ-92/3分闸、合闸、电源监视综…

Ubuntu18.04磁盘取证-中难度篇

涉及的镜像文件&#xff1a; sdb.vhd uac.tar ubuntu.20211208.mem 需要利用的工具&#xff1a; volatility3 volatility2.6.1 FTK/Autopsy Strings 题干 容器是一个Ubuntu Linux 蜜罐&#xff0c;用来观察利用 CVE-2021-41773 的漏洞攻击者想要做什么。 您将看到一个 cr…

羊大师早餐小贴士

羊大师早餐小贴士 早餐是一天中最重要的一餐&#xff0c;它为我们提供了所需的能量和营养。许多人喜欢搭配牛奶&#xff0c;但你知道吗&#xff1f;羊奶也是一个很好的选择&#xff01;羊奶富含蛋白质、钙和维生素B12&#xff0c;而且容易消化&#xff0c;适合各个年龄段的人饮…

【多线程】-- 04 静态代理模式

多线程 3 静态代理 这里以一个现实生活中的例子来解释并实现所谓的静态代理模式&#xff0c;即结婚者雇用婚庆公司来帮助自己完成整个婚礼过程&#xff1a; package com.duo.lambda;interface Marry {void HappyMarry();//人生四大乐事&#xff1a;久旱逢甘霖&#xff1b;他…

【古诗生成AI实战】之一——实战项目总览

[1] 总览 【古诗生成AI实战】系列共五篇文章&#xff1a; 【古诗生成AI实战】之一——实战项目总览   【古诗生成AI实战】之二——项目架构设计   【古诗生成AI实战】之三——任务加载器与预处理器   【古诗生成AI实战】之四——模型包装器与模型的训练   【古诗生成AI…

【JavaScript】3.2 JavaScript性能优化

文章目录 1. 避免全局查找2. 避免不必要的属性查找3. 使用快速的JavaScript方法4. 避免不必要的DOM操作5. 使用Web Workers进行后台处理总结 性能优化是任何编程语言的重要组成部分&#xff0c;JavaScript也不例外。在这个章节中&#xff0c;我们将探讨如何优化JavaScript代码&…