easyExcel动态导出,合并指定单元格

news2025/1/12 1:37:28

如上图所示,需要使用easyExcel动态导出上述表格并指定合并其中的单元格,日期是动态的,每个月不相同,直接上实现代码,以demo形式展现,更好理解

/**
     * 考勤记录动态导出测试
     */
    @GetMapping("/export_excel_test.do")
    @ApiOperation(value = "考勤记录动态导出测试", httpMethod = "GET")
    @CrossOrigin
    public void attendRecordExcelOut(HttpServletResponse response)  throws Exception{

        modelService.testAttendRecordExcelOut(response);

    }

public void testAttendRecordExcelOut(HttpServletResponse response) throws Exception{
        DispatchAuditRecord auditRecord = new DispatchAuditRecord();
        auditRecord.setAbsentTotal(1L);
        auditRecord.setIllnessTotal(2L);
        auditRecord.setMatrimonyTotal(3L);
        auditRecord.setVisitFamilyTotal(4L);
        auditRecord.setAnnualLeaveTotal(5L);
        auditRecord.setWorkOvertimeTotal(6L);
        auditRecord.setNightShiftTotal(7L);
        auditRecord.setAttendDayTotal(8L);
        auditRecord.setOperationDayTotal(9L);
        List<DispatchAttendRecord> recordList = new ArrayList<>();
        DispatchAttendRecord attendRecord = new DispatchAttendRecord();
        attendRecord.setStaffName("张测试");
        attendRecord.setPostName("岗位");
        DispatchAttendStatus attendStatus1 = new DispatchAttendStatus();
        attendStatus1.setDay("1");
        attendStatus1.setAttendStatus("休息");
        DispatchAttendStatus attendStatus2 = new DispatchAttendStatus();
        attendStatus2.setDay("2");
        attendStatus2.setAttendStatus("加班");
        ArrayList<DispatchAttendStatus> attendStatuses = new ArrayList<>();
        attendStatuses.add(attendStatus1);
        attendStatuses.add(attendStatus2);
        attendRecord.setList(attendStatuses);
        attendRecord.setAbsent(1L);
        attendRecord.setIllness(2L);
        attendRecord.setMatrimony(3L);
        attendRecord.setVisitFamily(4L);
        attendRecord.setAnnualLeave(5L);
        attendRecord.setWorkOvertime(6L);
        attendRecord.setNightShift(7L);
        attendRecord.setAttendDay(8L);
        attendRecord.setOperationDay(9L);
        recordList.add(attendRecord);
        List<List<Object>> contents = generateContents(recordList,auditRecord);
        List<List<String>> head = generateHead(recordList);

String fileName = String.valueOf(System.currentTimeMillis()/1000);
        response.setContentType("application/octet-stream");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xls");
        EasyExcel.write(response.getOutputStream())
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .head(head).sheet("考勤记录列表")
                .doWrite(contents);

    }

/**
     * 生成动态表头
     * @param recordList
     * @return 数据结构 外面一层list是每一列的list,里面一层list是每一列对应的单元格的list
     */
    private List<List<String>> generateHead(List<DispatchAttendRecord> recordList){
        List<String> head1 = Arrays.asList("序号", "姓名", "职名或岗位");
        List<List<String>> headList = new ArrayList<>();
        for (String head : head1) {
            List<String> inside = new ArrayList<>();
            inside.add(head);
            inside.add(head);
            headList.add(inside);
        }
        DispatchAttendRecord record = recordList.get(0);
        List<DispatchAttendStatus> list = record.getList();
        for (DispatchAttendStatus day : list) {
            List<String> inside = new ArrayList<>();
            inside.add("日期");
            inside.add(day.getDay());
            headList.add(inside);
        }
        List<String> head3 = Arrays.asList("旷工", "病事", "婚产护丧","探亲","年休","加班","夜班","出勤天数","其中|高铁线作业天数");
        for (String head : head3) {
            List<String> inside = new ArrayList<>();
            inside.add("各种情况统计汇总");
            inside.add(head);
            headList.add(inside);
        }
        return headList;
    }

/**
     * 组装数据
     */
    private List<List<Object>> generateContents(List<DispatchAttendRecord> records,DispatchAuditRecord auditRecord) {
        List<List<Object>> contents = new ArrayList<>();
        // 将records转为导出需要的格式
        for (int i = 0; i <= records.size(); i++) {
            if (i < records.size()){
                DispatchAttendRecord e = records.get(i);
                // 手动按表格顺序写入
                List<Object> nodes = new ArrayList<>();
                // 序号
                nodes.add(String.valueOf(i+1));
                // 姓名
                nodes.add(e.getStaffName());
                // 职名或岗位
                nodes.add(e.getPostName());
                // 细分到每一日
                List<DispatchAttendStatus> list = e.getList();
                for (DispatchAttendStatus detail : list) {
                    nodes.add(detail.getAttendStatus());
                }
                //旷工
                nodes.add(e.getAbsent());
                //病事
                nodes.add(e.getIllness());
                //婚产护丧
                nodes.add(e.getMatrimony());
                //探亲
                nodes.add(e.getVisitFamily());
                //年休
                nodes.add(e.getAnnualLeave());
                //加班
                nodes.add(e.getWorkOvertime());
                //夜班
                nodes.add(e.getNightShift());
                //出勤天数
                nodes.add(e.getAttendDay());
                //其中|高铁线作业天数
                nodes.add(e.getOperationDay());
                contents.add(nodes);

}else {
                //合计
                DispatchAttendRecord e = records.get(i-1);
                // 手动按表格顺序写入
                List<Object> nodes = new ArrayList<>();
                // 序号
                nodes.add("合计");
                // 姓名
                nodes.add("");
                // 职名或岗位
                nodes.add("");
                // 细分到每一日
                List<DispatchAttendStatus> list = e.getList();
                for (DispatchAttendStatus detail : list) {
                    nodes.add("");
                }

//旷工
                nodes.add(auditRecord.getAbsentTotal());
                //病事
                nodes.add(auditRecord.getIllnessTotal());
                //婚产护丧
                nodes.add(auditRecord.getMatrimonyTotal());
                //探亲
                nodes.add(auditRecord.getVisitFamilyTotal());
                //年休
                nodes.add(auditRecord.getAnnualLeaveTotal());
                //加班
                nodes.add(auditRecord.getWorkOvertimeTotal());
                //夜班
                nodes.add(auditRecord.getNightShiftTotal());
                //出勤天数
                nodes.add(auditRecord.getAttendDayTotal());
                //其中|高铁线作业天数
                nodes.add(auditRecord.getOperationDayTotal());
                contents.add(nodes);

            }

        }
        return contents;
    }

将以上代码拷贝到idea中可以直接执行。替换掉其中的实体类,根据自己实际业务修改即可

   

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

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

相关文章

【Kotlin学习】R2DBC与MyBatis性能对比

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、测试框架选取Spring Webflux VS Spring MVCSpring Data R2DBC VS MyBatis 二、测试代码编写1. 项目1核心代码1.1 引入依赖1.2 接口代码 2. 项目2核心代码2.…

Layui图片上传

前端代码&#xff1a; <div class"layui-upload"> <button type"button" class"layui-btn" id"test1">上传图片</button> <div class"layui-upload-list"> <img class"lay…

如何一次性生成大量结构相同、内容不同的二维码

使用 批量模板数据 的方式&#xff0c;可 一次性生成大量结构相同&#xff0c;内容不同的活码 &#xff0c;大幅提升制码效率。 模板的样式&#xff0c;关联的表单状态等所有内容均可进行修改&#xff0c;修改后所有子码都将批量更新&#xff0c;且模板可重复使用&#xff0c;让…

页面加载进度条(VUE3)

通常我们希望在页面跳转加载中&#xff0c;页面顶部出现进度条。 &#xff08;1&#xff09; 下载依赖 npm install nprogress --save &#xff08;2&#xff09;在router中得index.js中引入 import NProgress from nprogress import nprogress/nprogress.css &#xff08;…

C++——类和对象(2)

作者&#xff1a;几冬雪来 时间&#xff1a;2023年4月25日 内容&#xff1a;C类和对象讲解 目录 前言&#xff1a; 1.this指针&#xff1a; 2.默认成员函数&#xff1a; 3.构造函数&#xff1a; 4.析构函数&#xff1a; 5.构造函数的问题&#xff1a; 结尾&#xff…

Transformer 代码详细解析

Transformer 代码详细解析 文章目录 Transformer 代码详细解析一、Transformer 背景介绍1.1 Transformer 的诞生1.2 Transformer 的优势1.3 Transformer 的市场 二、Transformer架构解析2.1 认识 Transformer 架构2.1.1 Transformer模型的作用2.1.2 Transformer 总体架构图 2.2…

全国计算机等级三级网络技术试卷详解(一)

请点击↑关注、收藏&#xff0c;本博客免费为你获取精彩知识分享&#xff01;有惊喜哟&#xff01;&#xff01; 1.下列关于RPR技术的描述中&#xff0c;错误的是&#xff08;&#xff09;。 A) RPR与FDDI一样使用双环结构 B) 在RPR环中&#xff0c;源节点向目的节点成功发出…

2023常用的10款电力电子系统仿真分析软件推荐

市场上有许多电子仿真器&#xff0c;那么对于电力电子项目来说&#xff0c;哪种仿真器最好呢&#xff1f;或者因为期望任何软件包在各个方面都是最好的是不合理的&#xff0c;那么用户如何确定哪个软件是项目的最佳选择&#xff1f; PSIM PSIM是一种模块化封装&#xff0c;专为…

华为认证实验篇-ENSP的安装(附下载地址)

ENSP&#xff08;Enterprise Network Simulation Platform&#xff09;是华为公司开发的一款网络仿真软件&#xff0c;它可以帮助网络工程师进行网络拓扑设计、网络配置、网络测试等工作。本篇文章将介绍如何在Windows操作系统上安装ENSP。后续会在专栏陆续更新ENSP的实验&…

MACH SYSTEMS操作手册 SAEJ2716(SENT) to RS-232/CAN Gateway怎么使用?

双通道SAE J2716 (SENT)至RS-232/CAN总线网关&#xff0c;具有两个双向SENT通道和RS-232 (SENT-RS232) 或CAN总线 (SENT-CAN) 接口。两种变体还提供两个模拟输出&#xff0c;可以直接将输入SENT数据转换为模拟电压。该网关配备了一个免费的PC应用程序&#xff0c;用于SENT通信分…

VS同时调试主程序和子程序工具

VS要想要实现同时调试主程序和子程序&#xff0c;可使用工具 Microsoft Child Process Debugging power Tool 来实现。 我的环境和官方使用说明 环境&#xff1a;VS2019 官方使用说明&#xff1a;Introducing the Child Process Debugging Power Tool - Azure DevOps Blogh…

Swagger 版本控制 注释展示(.NET)

版本控制 项目创建 以Visual Studio 2022为例&#xff0c;创建Web API项目&#xff0c;如下图所示。 在创建时勾选启用OpenAPI支持&#xff0c;默认安装Swashbuckle.AspNetCore库&#xff0c;并配置相关信息。 创建版本枚举类 /// <summary>/// 版本枚举/// </su…

新版Fluent默认保存的h5文件无法用Tecplot打开的解决办法(亲试有效,评论区是重点)

文章目录 Ansys Fluent简介Fluent 输入/出 文件格式新版Fluent的输出压缩文件&#xff08;.cas.h5文件&#xff09;解决办法 Ansys Fluent简介 Ansys Fluent &#xff0c;是国际上比较流行的商用CFD软件包&#xff0c;在美国的市场占有率为60%&#xff0c;凡是和流体、热传递和…

IP地址的分配

一、ip地址的作用 用IP地址来标识Internet的主机&#xff1b;IP协议可以根据路由选择协议提供的路由信息对IP数据报进行转发&#xff0c;直至抵达目的主机。IP地址和MAC地址的匹配&#xff1b;数据链路层使用MAC地址来发送数据帧&#xff0c;因此在实际发送IP报文时&#xff0…

分布式消息队列Kafka(四)- 消费者

1.Kafka消费方式 2.Kafka消费者工作流程 &#xff08;1&#xff09;总体工作流程 &#xff08;2&#xff09;消费者组工作流程 3.消费者API &#xff08;1&#xff09;单个消费者消费 实现代码 package com.zrclass.kafka.consumer; import org.apache.kafka.clients.consum…

【Golang项目实战】手把手教你写一个备忘录程序|附源码——建议收藏

博主简介&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;数据结构、Go&#xff0c;Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: Go语言核心编程近期目标&#xff1a;写好专栏的每一篇文章 前几天瑶瑶子…

0Ω电阻在PCB板中的5大常见作用

在PCB板中&#xff0c;时常见到一些阻值为0Ω的电阻。我们都知道&#xff0c;在电路中&#xff0c;电阻的作用是阻碍电流&#xff0c;而0Ω电阻显然失去了这个作用。那它存在于PCB板中的原因是什么呢&#xff1f;今天我们一探究竟。 1、充当跳线 在电路中&#xff0c;0Ω电阻…

CCF-CSP 2013-12-3 最大的矩形(暴力枚举)

首先我们可以先根据数据范围反推时间复杂度&#xff0c;比如&#xff0c;数据范围n < 1000,我们可以将时间复杂度控制在O(n), O(n)logn 思路上比较容易想到的是枚举所有情况&#xff0c;然后输出面积最大的情况即可 可以在第一重循环枚举i&#xff0c;表示从第i个矩形开始往…

云HIS系统源码,部署云端,支持多租户,实现医疗数据共享与交换

云HIS系统源码&#xff0c;医院信息管理系统源码。采用云端SaaS服务的方式提供&#xff0c;采用前后端分离架构&#xff0c;前端由Angular语言、JavaScript开发&#xff1b;后端使用Java语言开发。 文末获取联系&#xff01; 基于云计算技术的B/S架构的云HIS系统&#xff0c;采…

zynqmp 外接fpga linux内核驱动修改

325t配置: 使用内核自带的linux-xlnx-xilinx-v2021.2/drivers/fpga/xilinx-spi驱动&#xff0c;做serial slave模式&#xff0c;设备树更改如下(根据 linux-xlnx-xilinx-v2021.2/Documentation/devicetree/bindings/fpga/xilinx-slave-serial.txt,修改)slave-serial需要将fpga的…