EasyExcel重复多次写入,合并单元格功能详细实现

news2024/10/7 16:23:21

❤ 作者主页:李奕赫揍小邰的博客
❀ 个人介绍:大家好,我是李奕赫!( ̄▽ ̄)~*
🍊 记得点赞、收藏、评论⭐️⭐️⭐️
📣 认真学习!!!🎉🎉

文章目录

  • EasyExcel
    • 如何重复多次将相同的对象写入(写到单个Sheet),并且将列表数据中的某个属性数据排除在外
    • 如何重复多次将不同对象写入到同一个sheet中,且共用一个标题头
    • 如何合并单列重复数据
  • 总结:

  在公司中领导让给查询统计做出一个导出为excel的功能,第一时间想到了easyexcel,为什么?因为他真的很简单,也很容易写,EasyExcel 适用于简单数据的导入导出,因此不是很复杂的导出,都可以考虑使用easyexcel进行实现。但公司的查询统计让我在easyexcel官网中都没有找到合适的样例,因此接下来,我将介绍几种在easyexcel官网中没有记载的使用方式。

EasyExcel

  easyexel官网:https://easyexcel.opensource.alibaba.com/
  接下来,就默认大家都已经知道easyexcel基本的导出功能了。

 

如何重复多次将相同的对象写入(写到单个Sheet),并且将列表数据中的某个属性数据排除在外

  要导出的页面如下
在这里插入图片描述
 
 
  上述效果需要两个List才能实现,一个是各个业态的数量统计,一个是总数的统计,所以需要将这两个List导入到同一个sheet之中。
 
 

@RequestMapping(value = "/export",method = RequestMethod.GET)
public void exportData(HttpServletResponse response){
    List<ComprehensiveLicenseSummary> summarysheet=comprehensiveLicenseService.getSummarySheet();
    List<ComprehensiveLicenseSummary> summaryTotal = comprehensiveLicenseService.getSummarySheetTotal();
    
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    try {
        String fileName = URLEncoder.encode("汇总表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        //将列表数据中的某个属性数据排除在外不及进行统计,或者也可以直接在实体类中排除的属性数据上方加上@ExcelIgnore即可
        Set<String> excludeColumnFiledNames = new HashSet<String>();
        excludeColumnFiledNames.add("permitArea");
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), ComprehensiveLicenseSummary.class).excludeColumnFiledNames(excludeColumnFiledNames).build();
        WriteSheet sheet1 = EasyExcel.writerSheet("汇总表").build();
        excelWriter.write(summarysheet,sheet1);
        excelWriter.write(summaryTotal,sheet1);
        excelWriter.finish();
    }catch (Exception e){
        log.error("汇总表excel文件导出失败:"+e);
    }
}

 

如何重复多次将不同对象写入到同一个sheet中,且共用一个标题头

  效果图同上,但区别是两个List中的对象不同,因此实体类属性不一样的情况下,如何在导出后位置能够匹配上,共用同一个标题头。
 

@RequestMapping(value = "/exportFine",method = RequestMethod.GET)
    public void exportFine(HttpServletResponse response){
        List<BusinessDistrict> businessDistricts = summarySheetService.getFineProof();
        List<BusinessCountByDistrict> businessCountByDistricts = summarySheetService.getBusinessCountByDistrictLicense();
        
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        ExcelWriter excelWriter = null;
        try {
            String fileName = URLEncoder.encode("明细表", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            //不同的对象导出到同一个sheet中
            excelWriter = EasyExcel.write(response.getOutputStream()).build();
            WriteSheet sheet1 = EasyExcel.writerSheet("明细表").needHead(Boolean.FALSE).build();
            WriteTable writeTable0 = EasyExcel.writerTable(0).head(BusinessDistrict.class).needHead(Boolean.TRUE).build();
             //这是两个对象,两个标题头的写法.若是需要区分两个对象数据,可以这样尝试。下面再多写两行excelWriter。write()即可
            //WriteTable writeTable1 = EasyExcel.writerTable(1).head(BusinessCountByDistrict.class).needHead(Boolean.TRUE).build();
            excelWriter.write(businessDistricts,sheet1,writeTable0);
            excelWriter.write(businessCountByDistricts,sheet1);
        }catch (Exception e){
            log.error("汇总表excel文件导出失败:"+e);
        }finally {
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }
    }

 

如何合并单列重复数据

  接下来是最复杂的一种,导出数据后合并单列重复数据。,怎么能够将第一列重复数据合并成一个,展示成如下的格式呢?
在这里插入图片描述
 
 
  这次数据仅仅只有一个List,但却需要我们多写一个自定义easyExcel处理器,处理单列数据相同合并单元格。在每个单元格完全创建完之后执行合并的功能。可以在处理器里面规定好要合并哪一列。代码编写如下,注解很多应该可以看懂。
 

@RequestMapping(value = "/exportProofByBusiness", method = RequestMethod.GET)
public void exportProofByBusinessHandle(HttpServletResponse response) {
    List<BusinessHandleDetail> licenseList = summarySheetService.getDetailProofByBusiness();
    
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");
    ExcelWriter excelWriter = null;
    try {
        String fileName = URLEncoder.encode("明细表", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

        // 自定义easyExcel处理器 ,处理单列数据相同合并单元格
        excelWriter = EasyExcel.write(response.getOutputStream(),BusinessHandleDetail.class)
                               .registerWriteHandler(new SimpleExcelMergeUtil()).build();
        WriteSheet sheet = EasyExcel.writerSheet("办理明细表").build();
        excelWriter.write(licenseList,sheet);
    } catch (Exception e) {
        log.error("明细表excel文件导出失败:" + e);
    } finally {
        if (excelWriter != null) {
            excelWriter.finish();
        }
    }
}


//自定义easyExcel处理器,处理单列数据相同合并单元格
public class SimpleExcelMergeUtil implements CellWriteHandler {

    public SimpleExcelMergeUtil() {
    }
    /**
     * 创建每个单元格之前执行
     */
    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }
    /**
     * 创建每个单元格之后执行
     */
    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }
    /**
     * 每个单元格数据内容渲染之后执行
     */
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }
    /**
     * 每个单元格完全创建完之后执行
     */
    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<CellData> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        // 当前行
        int curRowIndex = cell.getRowIndex();
        // 当前列
        int curColIndex = cell.getColumnIndex();

        if (!isHead) {
            if (curRowIndex > 1 && curColIndex == 0) {
                // 从第二行数据行开始,获取当前行第一列数据
                Object curData = cell.getCellTypeEnum() == CellType.STRING ? cell.getStringCellValue() : cell.getNumericCellValue();
                // 获取上一行第一列数据
                Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
                Object preData = preCell.getCellTypeEnum() == CellType.STRING ? preCell.getStringCellValue() : preCell.getNumericCellValue();
                if (curData.equals(preData)) {
                    Sheet sheet = writeSheetHolder.getSheet();
                    List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
                    boolean isMerged = false;
                    for (int i = 0; i < mergedRegions.size() && !isMerged; i++) {
                        CellRangeAddress cellRangeAddr = mergedRegions.get(i);
                        // 若上一个单元格已经被合并,则先移出原有的合并单元,再重新添加合并单元
                        if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                            sheet.removeMergedRegion(i);
                            cellRangeAddr.setLastRow(curRowIndex);
                            sheet.addMergedRegion(cellRangeAddr);
                            isMerged = true;
                        }
                    }
                    // 若上一个单元格未被合并,则新增合并单元
                    if (!isMerged) {
                        CellRangeAddress cellRangeAddress = new CellRangeAddress(curRowIndex - 1, curRowIndex, curColIndex, curColIndex);
                        sheet.addMergedRegion(cellRangeAddress);
                    }
                }
            }
        }
    }
}

 


总结:

  上述只是我在实现导出为excel遇到的问题,因为官网没有具体实例,所以我记录了下来,其他正常的导入导出官方文档都有记载,大家可以多看看官方文档

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

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

相关文章

TensorFlow Lite中文本分类在Android上的实践

#1 Tensorflow Lite TensorFlow Lite(后续简称TFL) 是 Google 开发的一个用于移动设备和嵌入式设备的开源库,旨在为移动终端设备提供机器学习推断。它是 TensorFlow 框架的轻量级版本,专门优化了模型的大小和性能,以适应资源受限的移动设备和嵌入式系统。 TFL 提供了一种在移…

力扣hot100 每日温度 单调递减栈

Problem: 739. 每日温度 文章目录 思路复杂度&#x1f49d; 单调栈 思路 &#x1f469;‍&#x1f3eb; 参考题解 复杂度 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) &#x1f49d; 单调栈 class Solution {public int[] dailyTem…

贝锐蒲公英全新网页认证,保障企业访客无线网络安全

随着企业规模的不断扩大、人员的增长、无线终端数量/类型的增加&#xff0c;传统WiFi无线网络会暴露出越来越多的问题&#xff0c;导致无线网络管理困难。 比如&#xff1a;采用弱密码、安全防护不到位的默认设置、员工缺乏信息安全意识、未经授人员权访问无线网络…… 这些问…

力扣日记1.28-【回溯算法篇】93. 复原 IP 地址

力扣日记&#xff1a;【回溯算法篇】93. 复原 IP 地址 日期&#xff1a;2023.1.28 参考&#xff1a;代码随想录、力扣 93. 复原 IP 地址 题目描述 难度&#xff1a;中等 有效 IP 地址 正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&…

(蓝桥杯每日一题)求最长回文串

问题描述 给出一个长度为 n 的小写字符串&#xff0c;求一个最长的子串 S&#xff0c;满足SXY,X&#xff0c;Y>1&#xff0c;且X,Y 均为回文串。 输入格式 输入包括一行: 第一行是一个长度为 n 的小写字符串。 输出格式 输出包括一行&#xff1a; 一行一个整数&#xff0c;表…

数据湖技术之应用场景篇

数据湖技术有较多的应用场景&#xff0c;本篇文章是针对一些典型的痛点场景做了一些介绍和说明。比如说在线数据抽取场景原有模式对线上库表产生较大压力&#xff0c;flink多流join维护的大状态导致的稳定性问题等等&#xff0c;具体场景如下图所示&#xff1a; 场景1:在线数据…

Mysql-InnoDB-数据落盘

概念 1 什么是脏页&#xff1f; 对于数据库中页的修改操作&#xff0c;则首先修改在缓冲区中的页&#xff0c;缓冲区中的页与磁盘中的页数据不一致&#xff0c;所以称缓冲区中的页为脏页。 2 脏页什么时候写入磁盘&#xff1f; 脏页以一定的频率将脏页刷新到磁盘上。页从缓冲区…

十大排序算法之冒泡排序

冒泡排序 冒泡排序是最基础的排序算法之一&#xff0c;但它并不是最优的排序算法。 1. 算法思想 冒泡排序是将数据中的每个数与相邻数进行比较并交换&#xff0c;大数往上冒&#xff0c;小数往下沉&#xff0c;每个数都遍历一次后便可以排出顺序。 2. 算法步骤 &#xff0…

【极数系列】Flink环境搭建Linux版本 (03)

文章目录 引言01 Linux部署JDK11版本1.下载Linux版本的JDK112.创建目录3.上传并解压4.配置环境变量5.刷新环境变量6.检查jdk安装是否成功 02 Linux部署Flink1.18.0版本1.下载Flink1.18.0版本包2.上传压缩包到服务器3.修改flink-config.yaml配置4.启动服务5.浏览器访问6.停止服务…

R语言学习case6:ggplot基础画图(Scatter散点图)

step1: 导入ggplot2库文件 library(ggplot2)step2&#xff1a;带入自带的iris数据集 iris <- datasets::irisstep3&#xff1a;查看数据信息 dim(iris)维度为 [150,5] head(iris)查看数据前6行的信息 step4&#xff1a;利用ggplot工具包绘图 plot1 <- ggplot(iris…

5G_RACH(一)

什么是RACH RACH 代表 Random Access Channel。这是开机时UE发给eNB的第一条消息。 为什么选择RACH &#xff1f;&#xff08;RACH 的功能是什么&#xff1f; 当你第一次听到RACH或RACH Process这个词时&#xff0c;你脑海中浮现的第一个问题是“为什么是RACH&#xff1f;”…

蓝桥杯-循环节长度

两个整数做除法&#xff0c;有时会产生循环小数&#xff0c;其循环部分称为: 循环节。比如&#xff0c;11/136>0.8461553846153..... 其循环节为[846153] 共有 6 位。下面的方法&#xff0c;可以求出循环节的长度。请仔细阅读代码&#xff0c;并填写划线部分缺少的代码。 注…

贪吃蛇游戏的实现

一.技术要点: 贪吃蛇需要掌握: c语言函数,枚举,结构体,动态内存管理,预处理指令,链表,Win32 API等 二.Win32 API 1.Win32 API简介 windows可以帮应用程序卡其视窗,描绘图案,使用周边设备,,Win32 API就是windows32位平台上的应用程序编程接口 2.控制台程序 (1).使用cmd命令…

Matlab绘图技巧-NAN元素绘图出现锯齿状解决办法

Matlab绘图技巧-NAN元素绘图出现锯齿状解决办法 想必有很多同学遇到绘制3维曲面热力图&#xff0c;有一些数据是nan&#xff0c;绘制出来的图会出现锯齿状&#xff1a;如下图&#xff1a;    如果用matlab直接绘制带nan的矩阵的话&#xff0c;则会像上图一样&#xff0c;当然…

Flink Checkpoint 超时问题详解

第一种、计算量大&#xff0c;CPU密集性&#xff0c;导致TM内线程一直在processElement&#xff0c;而没有时间做CP【过滤掉部分数据&#xff1b;增大并行度】 代表性作业为算法指标-用户偏好的计算&#xff0c;需要对用户在商城的曝光、点击、订单、出价、上下滑等所有事件进…

数据变换

数据变换 对数变换傅里叶变换Box-Cox 变换 对数变换 对数变换是一种常见的数据变换方法&#xff0c;它将原始数据取对数&#xff0c;常用的是自然对数&#xff08;以 e 为底&#xff09;或者以 10 为底的对数。对数变换的作用包括&#xff1a; 降低数据的尺度&#xff1a;对数…

《HTML 简易速速上手小册》第3章:HTML 的列表与表格(2024 最新版)

文章目录 3.1 创建无序和有序列表&#xff08;&#x1f4dd;&#x1f31f;&#x1f44d; 信息的时尚搭配师&#xff09;3.1.1 基础示例&#xff1a;创建一个简单的购物清单3.1.2 案例扩展一&#xff1a;创建一个旅行计划清单3.1.3 案例扩展二&#xff1a;创建一个混合列表 3.2 …

【AI绘画】Stable Diffusion 本地部署教程!小白必收藏!!

******手把手教你入门绘图超强的AI绘画&#xff0c;用户只需要输入一段图片的文字描述&#xff0c;即可生成精美的绘画。给大家带来了全新保姆级教程资料包 &#xff08;文末可获取&#xff09; ** **** 1.前言&#xff1a; 最近看Stable Diffusion开源了&#xff0c;据说比D…

LaTeX 多样列表:enumitem 宏包

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…

PID校正

一、Introduction to PID Control PID控制是一种应用非常广泛的控制算法。小到控制一个元件的温度&#xff0c;大到控制无人机的飞行姿态和飞行速度等等&#xff0c;都可以使用PID控制。PID(proportion integration differentiation)其实就是指比例&#xff0c;积分&#xff0…