【EasyExcel】导出excel冻结表头和冻结指定列并支持筛选器

news2024/12/28 5:15:54

需求背景:

        导出excel的同时冻结表头和前两列基础信息,方便导出后用户查看信息。

一、技术选型:

        easyExcel的自定义写策略处理:SheetWriteHandler

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

        1、重写afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder)方法

        2、通过 writeSheetHolder.getSheet() 获取 sheet,通过 sheet.createFreezePane() 方法设置导出excel指定冻结行和列,通过 sheet.setAutoFilter() 给指定导出的excel单元格设置自动筛选器.

三、代码实现:

3.1:pom.xml
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.3.2</version>
</dependency>
3.2: API
 @ApiOperation(value = "导出")
 @GetMapping(value = "/export")
 public void exportExcel(HttpServletResponse response,@RequestBody TestParam param) {
        service.export(response, param);
 }
3.3:工具类 IEasyExcelServicey
import com.alibaba.excel.write.handler.WriteHandler;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author c
 */
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 HttpServletResponse
     * @param tClass 导出excel的字段实体类
     * @param fileName 文件名字
     * @param sheetName sheet名字
     * @param writeHandler 自定义策略(可扩展多个)
     * @param <T> T
     */
    <T> void exportExcelWithHandler(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName, WriteHandler writeHandler);
}

 工具类:EasyExcelServiceImpl

@Slf4j
public class EasyExcelServiceImpl implements IEasyExcelService {

    /**
     * 本地转:response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileNameEncoder + ".xlsx");
     * @param exportData 需要导出的数据
     * @param response   response
     * @param tClass     导出excel的字段实体类
     * @param fileName   文件名字
     * @param sheetName  sheet名字
     * @param <T> T
     */
    @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");
            response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
            // 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 exportExcelWithHandler(List<T> exportData, HttpServletResponse response, Class<T> tClass, String fileName, String sheetName, WriteHandler writeHandler){
        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");
            response.setHeader("Access-Control-Expose-Headers", "Content-disposition");
            // write to excel
            EasyExcelFactory.write(response.getOutputStream(), tClass)
                    .autoCloseStream(Boolean.FALSE)
                    // 自定义策略(支持扩展多个)
                    .registerWriteHandler(writeHandler)
                    .sheet(sheetName)
                    .doWrite(exportData);
        }catch (Exception e){
            log.error("EasyExcelServiceImpl->exportExcel error, message is :{}", e.getMessage());
        }
    }


}
3.4: 自定义Handle:(自定义设置导出excel设置冻结列和列以及是否自动加筛选器)
/**
 * easyExcel:export handle
 * freeze row and col with set auto filter range
 * @author c
 * @date: 2024-1-5 13:44:26
 */
public class FreezeRowColHandler implements SheetWriteHandler {

    private final FreezeRowColOptions options;

    public FreezeRowColHandler(FreezeRowColOptions options) {
        this.options = options;
    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        Sheet sheet = writeSheetHolder.getSheet();
        sheet.createFreezePane(options.getColSplit(), options.getRowSplit(), options.getLeftmostColumn(), options.getTopRow());
        if (null != options.getAutoFilterRange()) {
            sheet.setAutoFilter(CellRangeAddress.valueOf(options.getAutoFilterRange()));
        }
    }

}
参数:FreezeRowColOptions
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FreezeRowColOptions {
    /**
     * Horizontal position of split
     */
    private Integer colSplit;
    /**
     * Vertical position of split
     */
    private Integer rowSplit;
    /**
     * Left column visible in right pane
     */
    private Integer leftmostColumn;
    /**
     * Top row visible in bottom pane
     */
    private Integer topRow;
    /**
     * auto filter range
     */
    private String autoFilterRange;
}
参数解释和示例:
四个参数分别代表:
colSplit:表示要冻结的列数;
rowSplit:表示要冻结的行数;
leftmostColumn:表示被固定列右边第一列的列号;
topRow:表示被固定行下边第一列的行号;

举例:
CreateFreezePane(0,1,0,1):冻结第一行,冻结行下侧第一行的左边框显示“2”
CreateFreezePane(1,0,1,0):冻结第一列,冻结列右侧的第一列为B列
CreateFreezePane(2,0,5,0):冻结左侧两列,冻结列右侧的第一列为F列

可以自定义 FreezeRowColConstant 方便维护,如下

/**
 * handle constant:export FreezeRowColConstant
 * freeze row and col with set auto filter range constant
 * @author c
 * @date: 2024-1-5 14:22:21
 */
public class FreezeRowColConstant {
    /**
     * TEST_ONE  export
     */
    public static final FreezeRowColOptions TEST_ONE = new FreezeRowColOptions(2, 2, 0, 0, "A2:BH2");
    /**
     * TEST_TWO  export
     */
    public static final FreezeRowColOptions TEST_TWO = new FreezeRowColOptions(2, 2, 0, 0, "A2:AC2");
    /**
     * TEST_THREE  export
     */
    public static final FreezeRowColOptions TEST_THREE = new FreezeRowColOptions(2, 2, 0, 0, "A2:T2");
}

ITestExportService:(这里可以根据自己的业务进行自定义,本文定义这个是因为在同一个业务里面有几个类似的导出可以共用这个导出接口)

public interface ITestExportService {
    /**
     * export data
     * @param response HttpServletResponse
     * @param param export common param
     * @throws BaseException ex
     */
    default void exportData(HttpServletResponse response, TestParam param) {}
}

下面给出其中一个导出的实现方法:

@Service
@Slf4j
public class TestOneServiceImpl implements ITestExportService {

    private static final String FILE_NAME_TEST = "测试";
    private final IEasyExcelService easyExcelService;
  
    public TestOneServiceImpl (IEasyExcelService easyExcelService) {
        this.easyExcelService = easyExcelService; 
    }

    @Override
    public void exportData(HttpServletResponse response, TestParam param) {
        // 这里是根据查询参数param获取需要导出的数据
        // get data
        List<DemoExcelData> data = this.ExportData(param);
        // export:调用 exportExcelWithHandler 导出
        easyExcelService.exportExcelWithHandler(data, response, DemoExcelData.class, FILE_NAME_TEST, FILE_NAME_TEST,
                new FreezeRowColHandler(FreezeRowColConstant.TEST_ONE));
    }
}

实现效果:(都加上了自动筛选器 )

下面是示例,在TestOneServiceImpl 方法中调用exportExcelWithHandler方法的时候实际用的是FreezeRowColConstant.TEST_ONE,其中 FreezeRowColConstant.TEST_ONE 设置的是 new FreezeRowColOptions(2, 2, 0, 0, "A2:BH2"),其含义是:

        第一个参数:表示冻结前两行

        第二个参数:表示冻结前两列 

        "A2:BH2":表示单元格"A2:BH2"区间设置添加自动筛选器

表头固定效果:

 前两列固定效果:

相关文章推荐:

【EasyExcel】导出excel并支持自定义设置数据行背景颜色等_easyexcel rrg背景-CSDN博客

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

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

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

相关文章

歌词滚动显示

歌词滚动显示 环境准备htmldata.js歌词css 解析歌词为对象数组查找指定时间点的歌词创建歌词元素li计算偏移量监听播放时间执行偏移计算 模仿音乐软件实现歌词随播放时间滚动显示 环境准备 html <!DOCTYPE html> <html lang"en"> <head><meta…

Redis基本原理和基础知识

目录 一、基本原理 &#xff08;一&#xff09;非关系型数据库 &#xff08;二&#xff09;关系型数据库与非关系型数据库的区别 &#xff08;三&#xff09;Redis简介 1.什么是Redis 2.数据存储结构 3.默认端口号 4.数据类型 &#xff08;1&#xff09;五大基础类型 …

test fuzz-02-模糊测试 JQF + Zest Semantic Fuzzing for Java

拓展阅读 开源 Auto generate mock data for java test.(便于 Java 测试自动生成对象信息) 开源 Junit performance rely on junit5 and jdk8.(java 性能测试框架。性能测试。压测。测试报告生成。) test fuzz-01-模糊测试&#xff08;Fuzz Testing&#xff09; test fuzz-…

软件概要设计(word)原件

1引言 1.1编写目的 1.2项目背景 1.3参考资料 2系统总体设计 2.1整体架构 2.2整体功能架构 2.3整体技术架构 2.4运行环境设计 2.5设计目标 3系统功能模块设计 3.1个人办公 4性能设计 4.1响应时间 4.2并发用户数 5接口设计 5.1接口设计原则 5.2接口实现方式 6运行设计 6.1运行模块…

Linux ls命令

目录 一. 配置项1.1 ls -l1.2 ls -a1.3 ls -lrt1.4 ls -ld .?* 二. 案例2.1 查看指定文件夹下文件的数量2.2 查看多个文件夹下文件信息 一. 配置项 1.1 ls -l ⏹ ls 列出当前文件夹下所有文件名称(不包含隐藏文件) jmw_num_00 jmw_num_02 jmw_num_04 jmw_num_06 jmw_n…

跨平台的文件传输协议@windows端服务器的配置@smb协议共享方案@ftp服务器设置

文章目录 abstractrefs ftp server下面是核心步骤FAQ smb server设置方法 共享文件夹的访问控制补充匿名访问问题协议相关信息参考android客户端推荐FAQ不同用户文件无法访问 比较和总结传输速率问题 abstract 文件传输协议是很常用的协议特别是跨平台的协议,往往更加受欢迎,应…

VS2022 | 调整适配虚幻5的设置

VS2022 | 调整适配虚幻5的设置

小米4A千兆版路由器刷入OpenWRT教程结合内网穿透远程访问

文章目录 前言1. 安装Python和需要的库2. 使用 OpenWRTInvasion 破解路由器3. 备份当前分区并刷入新的Breed4. 安装cpolar内网穿透4.1 注册账号4.2 下载cpolar客户端4.3 登录cpolar web ui管理界面4.4 创建公网地址 5. 固定公网地址访问 前言 OpenWRT是一个高度模块化、高度自…

数组中元素的插入和查找算法探究

数组的查找 线性查找 概念 线性查找也叫顺序查找&#xff0c;这是最基本的一种查找方法&#xff0c;从给定的值中进行搜索&#xff0c;从一端开始逐一检查每个元素&#xff0c;直到找到所需元素的过程。 元素序列的排列可以有序&#xff0c;也可以无序。 代码实现 public cl…

vulhub中的Apache HTTPD 换行解析漏洞(CVE-2017-15715)详解

Apache HTTPD 换行解析漏洞&#xff08;CVE-2017-15715&#xff09; 1.cd到CVE-2017-15715 cd vulhub/httpd/CVE-2017-15715 2.运行docker-compose build docker-compose build 3.运行docker-compose up -d 4.查看docker-compose ps 5.访问 出现这个表示安装成功 6.漏洞复现…

16-20.Python语言进阶

Python语言进阶 重要知识点 生成式&#xff08;推导式&#xff09;的用法 prices {AAPL: 191.88,GOOG: 1186.96,IBM: 149.24,ORCL: 48.44,ACN: 166.89,FB: 208.09,SYMC: 21.29 } # 用股票价格大于100元的股票构造一个新的字典 prices2 {key: value for key, value in prices…

Github 2024-01-09Python开源项目日报 Top10

根据Github Trendings的统计&#xff0c;今日(2024-01-09统计)共有10个项目上榜。根据开发语言中项目的数量&#xff0c;汇总情况如下&#xff1a; 开发语言项目数量Python项目10Jupyter Notebook项目1 Payloads All The Things - 有用的Web应用程序安全负载和绕过列表 创建…

Unity 编辑器篇|(二)GenericMenu自定义弹出式菜单

目录 1. 前言2. Scene视图添加自定义菜单3. Hierarchy视图添加自定义菜单4. Project视图添加自定义菜单5. Game视图添加自定义菜单 1. 前言 GenericMenu 是 Unity 中的一个强大的类&#xff0c;用于创建和管理自定义上下文菜单&#xff08;也称为弹出菜单&#xff09;。可以使…

Django配置日志系统的最佳实践

概要 日志是跟踪应用行为、监控错误、性能分析和安全审计的重要工具。在Django框架中&#xff0c;合理配置日志系统可以帮助开发者有效管理项目运行过程中的关键信息。本文将详细介绍Django日志系统的最佳实践。 日志系统概述 Django使用Python的 logging 模块来实现日志系统…

苹果快捷指令在哪?详细使用教程送给大家!

快捷指令是苹果公司推出的一个实用功能&#xff0c;然而&#xff0c;可能还有很多新手用户不知道苹果快捷指令在哪。其实&#xff0c;快捷指令中心是iOS系统自带的应用&#xff0c;它一般就位于手机的主屏幕中。今天&#xff0c;小编将针对此问题来给大家分享一下有关苹果快捷指…

虚拟机Linux硬盘扩容

扩容前(20G)&#xff1a; 扩容后(60G)&#xff1a; 步骤&#xff1a; 1. 点击 虚拟机 -> 设置 -> 硬件 -> 硬盘(SCSI) -> 扩展(E)... -> 输入想要扩容大大小 -> 扩展(E) 2. 运行虚拟机&#xff0c;查看根目录属于那个文件系统&#xff0c;我的是 /dev/sda1…

前端八股文(网络篇)一

目录 1.Get和Post的请求的区别 2.常见的HTTP请求头和响应头 3.常见的HTTP请求方法 4.HTTP与HTTPS协议的区别 5.对keep-alive的理解 6.页面有多张图片&#xff0c;HTTP是怎样的加载表现&#xff1f; 7.HTTP请求报文是什么样的&#xff1f; 8.HTTP响应报文是什么样&#x…

【数据结构】数据结构中应用题大全(完结)

自己在学习过程中总结了DS中几乎所有的应用题&#xff0c;可以用于速通期末考/考研/各种考试。很多方法来源于B站大佬&#xff0c;底层原理本文不做过多介绍&#xff0c;建议自己研究。例题大部分选自紫皮严书。pdf版在主页资源 一、递归时间/空间分析 1.时间复杂度的分析 设…

与AI合作 -- 写一个modern c++单例工厂

目录 前言 提问 bard给出的答案 AI答案的问题 要求bard改进 人类智能 AI VS 人类 前言 通过本文读者可以学到modern C单例模式工厂模式的混合体&#xff0c;同时也能看到&#xff1a;如今AI发展到了怎样的智能程度&#xff1f;怎样让AI帮助我们快速完成实现头脑中的想法&…

如何下载和处理Sentinel-2数据

Sentinel-2是欧洲空间局&#xff08;ESA&#xff09;Copernicus计划中的一组地球观测卫星&#xff0c;主要用于提供高分辨率的光学遥感数据。Sentinel-2卫星组成了一个多光谱成像系统&#xff0c;可用于监测地球表面的陆地变化、植被覆盖、水域和自然灾害等。它具有以下特性&am…