EasyExcel 自定义头信息导出

需求:需要在导出 excel时,合并单元格自定义头信息(动态生成),然后才是字段列表头即导出数据。

EasyExcel - 使用table去写入:https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E4%BD%BF%E7%94%A8table%E5%8E%BB%E5%86%99%E5%85%A5

一、代码实现

1、查询导出数据

1.1 导出实体类

import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.converters.localdatetime.LocalDateTimeStringConverter;
import lombok.Data;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * 用户信息 导出DTO
 */
@Data
@ExcelIgnoreUnannotated
public class UserExportExcelDTO implements Serializable {
    private static final long serialVersionUID = -5255117385546252447L;

    /**
     * 用户ID
     */
    @ExcelIgnore
    private Long userId;

    /**
     * 用户名
     */
    @ExcelProperty(value = "用户名")
    private String username;

    /**
     * 年龄
     */
    @ExcelProperty(value = "年龄")
    private Integer age;

    /**
     * 电话号码
     */
    @ExcelProperty(value = "电话号码")
    private String phone;

    /**
     * 昵称
     */
    @ExcelProperty(value = "昵称")
    private String nickname;

    /**
     * 姓名
     */
    @ExcelProperty(value = "姓名")
    private String name;

    /**
     * 创建时间
     * 使用 converter或者 @DateTimeFormat格式化时间,如果两者同时使用,@DateTimeFormat优先级高
     */
    @ExcelProperty(value = "创建时间", converter = LocalDateTimeStringConverter.class) // yyyy-MM-dd HH:mm:ss
    @DateTimeFormat("yyyy年MM月dd日")
    private LocalDateTime createTime;

}

1.2 查询导出数据方法

    @Override
    public List<UserExportExcelDTO> listExportExcelData(UserPageQueryRequest pageRequest) {
        pageRequest.setCurrentPage(1L);
        pageRequest.setPageSize((long) Integer.MAX_VALUE);
        BasePageResult<UserPageDTO> basePageResult = pageQuery(pageRequest);
        if(!basePageResult.isSuccess()){
            return Collections.EMPTY_LIST;
        }
        return basePageResult.getPageList().stream().map(userPageDTO -> {
            UserExportExcelDTO exportExcelDTO = new UserExportExcelDTO();
            BeanUtils.copyProperties(userPageDTO, exportExcelDTO);
            return exportExcelDTO;
        }).collect(Collectors.toList());
    }

2、EasyExcel使用 table写入

    /**
     * 用户导出接口
     *
     * @param pageRequest 分页查询请求体
     */
    @SneakyThrows
    @ApiOperation(value = "用户导出接口")
    @GetMapping("/exportExcel")
    public void exportExcel(HttpServletResponse response, @RequestBody UserPageQueryRequest pageRequest) {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("用户信息", StandardCharsets.UTF_8.name()).replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 查询导出数据
        List<UserExportExcelDTO> exportExcelDataList = userService.listExportExcelData(pageRequest);

        // 自定义头信息
        StringBuilder headName = new StringBuilder();
        LocalDateTime startTime = pageRequest.getCreateTimeStart();
        LocalDateTime endTime = pageRequest.getCreateTimeEnd();
        if (startTime != null && endTime != null) {
            String startTimeStr = LocalDateTimeUtil.format(startTime, DatePattern.CHINESE_DATE_PATTERN);
            String endTimeStr = LocalDateTimeUtil.format(endTime, DatePattern.CHINESE_DATE_PATTERN);
            headName.append(startTimeStr).append("至").append(endTimeStr);
        }
        headName.append("时间段的用户信息");

        List<List<String>> headList = new ArrayList<>();
        List<String> head = new ArrayList<>();
        head.add(headName.toString());
        headList.add(head);

        /**
         * 创建 ExcelWriter
         * 1.创建写入的工作表,不需要表头。命名为"sheet1"。
         */
        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcelFactory.write(response.getOutputStream()).build();
        } catch (IOException e) {
            log.error("导出车辆在线率统计异常:e=", e);
        }
        WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").needHead(Boolean.FALSE).build();

        /**
         * 2.创建并写入表格数据,设置表头为 headList,需要表头。
         * tableNo:表格序号,从0开始。
         * OnceAbsoluteMergeStrategy:创建一个合并单元格策略。
         */
        WriteTable writeTable1 = EasyExcel.writerTable(0)
                .head(headList)
                .registerWriteHandler(new OnceAbsoluteMergeStrategy(0, 2, 0, 5))
                .needHead(Boolean.TRUE)
                .build();
        // 写入空数据到 writeSheet
        excelWriter.write(new ArrayList<>(), writeSheet, writeTable1);

        /**
         * 3.创建写入表格,基于AnysCarOfflineStatisticsVo类定义表头,需要表头。
         * writerTable(3):因为 writeTable1从0开始,并合并了 3行,所以 writeTable2是从第4个行(tableNo = 3)开始写入。
         * SimpleColumnWidthStyleStrategy:设置列宽策略
         */
        WriteTable writeTable2 = EasyExcel.writerTable(3)
                .head(UserExportExcelDTO.class)
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                .relativeHeadRowIndex(2)
                .needHead(Boolean.TRUE)
                .build();
        // 写入导出数据到 writeSheet
        excelWriter.write(exportExcelDataList, writeSheet, writeTable2);
        excelWriter.finish();
    }

3、导出结果

在这里插入图片描述

– 求知若饥,虚心若愚。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++基础知识学习记录—模版和泛型编程

1、模板 概念&#xff1a; 模板可以让类或者函数支持一种通用类型&#xff0c;在编写时不指定固定的类型&#xff0c;在运行时才决定是什么类型&#xff0c;理论上讲可以支持任何类型&#xff0c;提高了代码的重用性。 模板可以让程序员专注于内部算法而忽略具体类型&#x…

Django 连接(sqlserver)数据库方法

文章目录 django 的SQL server适配器&#xff0c;例如django-pyodbc-azure 或 mssql-django1、django-pyodbc-azure2、mssql-django3、注意 Django只内置了几个 Database Backend&#xff08;mysql、oracle、sqllite3&#xff08;默认&#xff09;、postgresql_psycopg2&#x…

华为 eNSP:MSTP

一、MSTP是什么 MSTP是多业务传送平台&#xff08;Multi-Service Transport Platform&#xff09;的缩写&#xff0c;它是一种基于SDH&#xff08;同步数字体系&#xff09;技术的传输网络技术&#xff0c;用于同时实现TDM、ATM、以太网等多种业务的接入、处理和传送。 MSTP技…

Mac端homebrew安装配置

拷打了一下午o3-mini-high&#xff0c;不如这位博主的超强帖子&#xff0c;10分钟结束战斗 跟随该文章即可&#xff0c;2025/2/19亲测可行 mac 安装HomeBrew(100%成功)_mac安装homebrew-CSDN博客文章浏览阅读10w次&#xff0c;点赞258次&#xff0c;收藏837次。一直觉得自己写…

一台服务器将docker image打包去另一天服务器安装这个镜像

一台服务器将docker image打到去另一天服务器安装这个镜像 1. 打包2.另一台服务器执行 1. 打包 docker save -o nebula-graph-studio.tar harbor1.vm.example.lan/dockerio/vesoft/nebula-graph-studioxxx.tar 是打包好的文件 后面的是 docker image 2.另一台服务器执行 docke…

Web开发技术概述

Web开发技术涵盖了前端和后端开发&#xff0c;以及数据库技术。前端开发包括使用HTML、CSS、JavaScript等原生技术&#xff0c;以及jQuery、Bootstrap、AngularJS、React、Vue等框架。后端开发则涉及ASP.NET、PHP、Python Web&#xff08;Flask、Django&#xff09;、Java Web&…

【项目日记】仿RabbitMQ实现消息队列 --- 模块设计

你要的答案不在书本里&#xff0c; 也不能靠别人来解决&#xff0c; 除非你想一辈子当小孩。 你必须在自我内部找到答案&#xff0c; 感受到该做的正确事情。 --- 《献给阿尔吉侬的花束》--- 仿RabbitMQ实现消息队列 1 数据管理模块1.1 交换机数据管理模块1.2 队列数据管…

C++ Primer 构造函数再探

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

SQL 注入攻击详解[基础篇]:Web 应用程序安全漏洞与防御策略

目录 SQL注入的简介 现代 Web 应用程序中的数据库交互与 SQL 注入攻击 数据库管理系统&#xff08;DBMS&#xff09;架构与 SQL 注入 什么是 SQL 注入&#xff1f; SQL 注入的工作原理 SQL 注入的用例与影响 如何预防 SQL 注入&#xff1f; 数据库分类 数据库类型&am…

自制AirTag,支持安卓/鸿蒙/PC/Home Assistant,无需拥有iPhone

苹果的AirTag很贵&#xff0c;虽然某强北有平价代替品&#xff0c;但是仍需要苹果设备才能绑定&#xff0c;才能查看位置。不支持安卓/鸿蒙/PC&#xff0c;也不支持集成到Home Assistant中。 AirTag 的原理 每个AirTag都会发送一个蓝牙信号&#xff0c;其可以被临近的苹果设备…

网络技术变迁:从IPv4走向IPv6

目录 前言 旧时代产物&#xff1a;IPv4 什么是IPv4&#xff1f; IPv4的工作方式 IPv4的缺点 为什么要从IPv4过渡到IPv6&#xff1f; 走向IPv6&#xff1a;新一代互联网协议 IPv6的技术特性 我们需要过渡技术 双栈&#xff08;Dual Stack&#xff09; 隧道技术&#…

uniapp 滚动尺

scale组件代码&#xff08;部分class样式使用到了uview1.0的样式&#xff09; <template><view><view class"scale"><view class"pointer u-flex-col u-col-center"><u-icon name"arrow-down-fill" size"26&qu…

模型量化初始知识

原文网址&#xff1a;知乎原文-量化基础知识 背景 PyTorch对量化的支持目前有如下三种方式&#xff1a; Post Training Dynamic Quantization&#xff0c;模型训练完毕后的动态量化&#xff1b; Post Training Static Quantization&#xff0c;模型训练完毕后的静态量化&…

在项目中调用本地Deepseek(接入本地Deepseek)

前言 之前发表的文章已经讲了如何本地部署Deepseek模型&#xff0c;并且如何给Deepseek模型投喂数据、搭建本地知识库&#xff0c;但大部分人不知道怎么应用&#xff0c;让自己的项目接入AI模型。 文末有彩蛋哦&#xff01;&#xff01;&#xff01; 要接入本地部署的deepsee…

Redis7——基础篇(五)

前言&#xff1a;此篇文章系本人学习过程中记录下来的笔记&#xff0c;里面难免会有不少欠缺的地方&#xff0c;诚心期待大家多多给予指教。 基础篇&#xff1a; Redis&#xff08;一&#xff09;Redis&#xff08;二&#xff09;Redis&#xff08;三&#xff09;Redis&#x…

【爬虫基础】第一部分 网络通讯 P1/3

前言 1.知识点碎片化&#xff1a;每个网站实现的技术相似但是有区别&#xff0c;要求我们根据不同的网站使用不同的应对手段。主要是常用的一些网站爬取技术。 2.学习难度&#xff1a;入门比web简单&#xff0c;但后期难度要比web难&#xff0c;在于爬虫工程师与网站开发及运维…

揭秘区块链隐私黑科技:零知识证明如何改变未来

文章目录 1. 引言&#xff1a;什么是零知识证明&#xff1f;2. 零知识证明的核心概念与三大属性2.1 完备性&#xff08;Completeness&#xff09;2.2 可靠性&#xff08;Soundness&#xff09;2.3 零知识性&#xff08;Zero-Knowledge&#xff09; 3. 零知识证明的工作原理4. 零…

R软件用潜在类别混合模型LCM分析老年人抑郁数据轨迹多变量建模研究

全文链接&#xff1a; tecdat.cn/?p40283 潜在类别混合模型假设总体具有异质性&#xff0c;由 GG 个潜在类别组成。在多变量的情况下&#xff0c;潜在类别是根据 KK 个纵向结果来定义的&#xff0c;从而形成 GG 个组&#xff0c;每个组的特征由 KK 个轨迹均值轮廓集表示&#…

【Rust中级教程】1.11. 生命周期(进阶) Pt.1:回顾、借用检查器、泛型生命周期

喜欢的话别忘了点赞、收藏加关注哦&#xff08;加关注即可阅读全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 这篇文章在Rust初级教程的基础上对生命周期这一概念进行了补充&#xff0c;建议先看【Rust自…

【DeepSeek服务器部署全攻略】Linux服务器部署DeepSeek R1模型、实现API调用、搭建Web页面以及专属知识库

DeepSeek R1模型的Linux服务器搭建、API访问及Web页面搭建 1&#xff0c;引言2&#xff0c;安装Ollama工具3&#xff0c;下载DeepSeek R1 模型4&#xff0c;DeepSeek命令行对话5&#xff0c;DeepSeek API接口远程调用6&#xff0c;DeepSeek结合Web-ui实现图形化界面远程访问6.1…