EasyExcel-一款好用的excel生成工具

EasyExcel是一款处理excel的工具类,主要特点如下(官方):

特点

  • 高性能读写:FastExcel 专注于性能优化,能够高效处理大规模的 Excel 数据。相比一些传统的 Excel 处理库,它能显著降低内存占用。
  • 简单易用:该库提供了简洁直观的 API,使得开发者可以轻松集成到项目中,无论是简单的 Excel 操作还是复杂的数据处理都能快速上手。
  • 流式操作:FastExcel 支持流式读取,将一次性加载大量数据的问题降到最低。这种设计方式在处理数十万甚至上百万行的数据时尤为重要。

我自己实践之后的感受如下:

  • 性能比较好,底层使用SXSSF,在大数据的情况下,会先往硬盘中插入,加快速度。(SXSSF 通过将数据写入磁盘而不是全部保留在内存中,来减少内存的使用。这种 “流式” 写入方式特别适合处理那些可能导致传统内存处理方式崩溃的大型 CSV 文件。SXSSF 可以在写入数据的同时,将数据保存在一个临时的文件中,这样即使处理非常大的数据集,内存的使用也会保持在可控范围内。)
  • 支持注解,可以在每个字段属性上添加注解,可以设置表格的表头/颜色/字体/合并单元格等属性。
  • 支持策略,针对复杂的表格,支持注入策略,针对表格进行各种加工。
  • 支持excel转pdf(仅支持xlsx,版本为1.0.0)

实践

引入依赖


<dependency><groupId>cn.idev.excel</groupId><artifactId>fastexcel</artifactId><version>1.1.0</version>
</dependency>
1.表头支持注解方式生成

比如,下方的示例:创建一个绿色背景,加边框的表头
在这里插入图片描述
代码的话可以直接这样写:
新增一个订单类:

@Data
// 表头背景设置
@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 17)
public class Order {@ExcelProperty("订单号")private String orderId;@ExcelProperty("渠道")private String searchChannel;@ExcelProperty("创建时间")private String createTime;@ExcelProperty("乘客姓名")private String name;@ExcelProperty("证件号")private String idCard;
}

创建表格


/*** 合并单元格* <p>* 1. 创建excel对应的实体对象 参照{@link DemoData} {@link DemoMergeData}* <p>* 2. 创建一个merge策略 并注册* <p>* 3. 直接写即可** @since 2.2.0-beta1*/
@Test
public void mergeOrderWrite() {//使用策略合并单元格try (FileOutputStream excel = new FileOutputStream("mergeOrderWrite.xlsx");BufferedOutputStream bos = new BufferedOutputStream(excel)) {// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭EasyExcel.write(bos, Order.class).sheet("模板").doWrite(buildData());System.out.println("导出完成");} catch (IOException e) {System.out.println("导出失败:" + e.getMessage());} catch (Exception e) {throw new RuntimeException(e);}
}//初始化数据
private List<Order> buildData() {List<Order> list = new ArrayList<>();for (int i = 0; i < 100; i++) {for (int j = 0; j < 2; j++) {Order user = new Order();user.setOrderId("orderId_" + i);user.setSearchChannel("searchChannel_" + i);user.setCreateTime(DateTimeUtil.nowString());user.setName("name_" + j);user.setIdCard("idCard_" + j);list.add(user);}}Order user1 = new Order();user1.setOrderId("orderId_99");user1.setSearchChannel("searchChannel_99");user1.setCreateTime(DateTimeUtil.nowString());user1.setName("name_a");user1.setIdCard("idCard_a");list.add(user1);return list;
}

上面代码执行之后,即可以生成效果图中的表格数据

2.通过添加策略,来支持复杂的表格处理

比如我们要处理一个表格,里面的数据涉及到动态合并单元格。需要将相邻的相同订单号合并到一起
在这里插入图片描述
支持添加策略实现:
思路:遍历每个row,如果两个orderid一样,则合并

@Slf4j
public class LoopOrderMergeStrategy implements RowWriteHandler {/*** 订单号*/private String orderId;/*** 当前订单号起始坐标*/private Integer indexStart;/*** 合并策略,订单号和创建时间合并** @author zhouxy* @date 2025/4/3 17:27*/public void afterRowDispose(RowWriteHandlerContext context) {log.info("进来,,,{},{}", context.getRow().getRowNum(), context.getRelativeRowIndex());//遍历每个row,如果两个orderid一样,则合并//这里是获取每一行数据Cell cell = context.getRow().getCell(0);String currentOrderId = cell.getStringCellValue();if (Strings.isEmpty(this.orderId)) {this.orderId = currentOrderId;indexStart = context.getRowIndex();} else if (Objects.equals(this.orderId, currentOrderId)) {//合并单元格//订单号CellRangeAddress orderCellRangeAddress = new CellRangeAddress(indexStart,context.getRowIndex(),cell.getColumnIndex(),cell.getColumnIndex());context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(orderCellRangeAddress);//渠道Cell searchChannelCell = context.getRow().getCell(1);CellRangeAddress searchChannelCellRangeAddress = new CellRangeAddress(indexStart,context.getRowIndex(),searchChannelCell.getColumnIndex(),searchChannelCell.getColumnIndex());context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(searchChannelCellRangeAddress);//创建时间Cell createtimeCell = context.getRow().getCell(2);CellRangeAddress createTimeCellRangeAddress = new CellRangeAddress(indexStart,context.getRowIndex(),createtimeCell.getColumnIndex(),createtimeCell.getColumnIndex());context.getWriteSheetHolder().getSheet().addMergedRegionUnsafe(createTimeCellRangeAddress);} else if (!Objects.equals(this.orderId, currentOrderId)) {this.orderId = currentOrderId;indexStart = context.getRowIndex();}}}

生成表格的时候,将该策略设置进去


/*** 合并单元格* <p>* 1. 创建excel对应的实体对象 参照{@link DemoData} {@link DemoMergeData}* <p>* 2. 创建一个merge策略 并注册* <p>* 3. 直接写即可** @since 2.2.0-beta1*/
@Test
public void mergeOrderWrite() {//使用策略合并单元格try (FileOutputStream excel = new FileOutputStream("mergeOrderWrite.xlsx");BufferedOutputStream bos = new BufferedOutputStream(excel)) {LoopOrderMergeStrategy loopMergeStrategy = new LoopOrderMergeStrategy();// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭EasyExcel.write(bos, Order.class).registerWriteHandler(loopMergeStrategy).sheet("模板").doWrite(buildData());System.out.println("导出完成");} catch (IOException e) {System.out.println("导出失败:" + e.getMessage());} catch (Exception e) {throw new RuntimeException(e);}
}
3.支持excel转pdf,但是只有1.0.0版本有,新版本去掉了。
   @Testpublic void excelToPdf() {FastExcel.convertToPdf(new File("excel1.xlsx"),new File("pdfFile"),null,null);}
4.性能

相同数据生成用时比较:ExsyExcel > SXSSF > HSSF. 但是HSSF最大行数为65565行,再大就超出范围报错
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
HSSF可写入行数
在这里插入图片描述
easyexcel和SXSSF可写入行数
在这里插入图片描述

综合比较用时的话,,EasyExcel和SX SSF的用时差不多,HSSF的用时相当于前两者的三分之一。但是HSSF数据量支持较小,但是综合下来的话,从用时,代码简洁度来说,建议使用EasyExcel

其他功能可以看官方的github,里面有很多示例。比如支持转图片,根据模板写入excel等。

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

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

相关文章

视频分析设备平台EasyCVR携手高空抛物AI智能分析技术,打造住宅小区头顶安全智能防线

一、背景介绍 随着城市化进程的高速推进&#xff0c;城市天际线不断被刷新&#xff0c;高楼大厦密密麻麻。然而&#xff0c;高空抛物问题也逐渐显现&#xff0c;这一行为不仅严重影响城市文明的形象&#xff0c;更带来很多安全隐患&#xff0c;威胁居民的生命财产安全&#xf…

Spring MVC 操作会话属性详解(@SessionAttributes 与 @SessionAttribute)

Spring MVC 操作会话属性详解&#xff08;SessionAttributes 与 SessionAttribute&#xff09; 1. 核心注解对比 注解作用范围功能SessionAttributes类级别声明控制器中需要持久化的模型属性&#xff08;存入 HttpSession&#xff09;SessionAttribute方法参数/返回值显式绑定…

Python字典实战: 三大管理系统开发指南(班级+会议+购物车)(附源码)

目录 摘要 一、班级管理系统&#xff08;含成绩模块&#xff09; 1. 功能概述 2. 完整代码与解析 3. 代码解析与亮点 二、会议管理系统 1. 功能概述 2. 完整代码 3. 代码解析与亮点 三、购物车管理系统 1. 功能概述 2. 完整代码 3. 代码解析与亮点 四、总结与扩…

北京自在科技:让万物接入苹果Find My网络的″钥匙匠″

在AirTag掀起全球防丢热潮的今天&#xff0c;越来越多的第三方产品开始接入苹果Find My网络——从充电宝到电动车&#xff0c;从行李箱到保温杯&#xff0c;用户只需打开iPhone的「查找」App&#xff0c;就能实时定位这些物品。 北京自在科技有限责任公司早在苹果推出Find My开…

Vue进行前端开发流程

一、创建vue项目 创建vue项目&#xff1a;先进入要操作的目录下&#xff0c;注意本项目是用vue2开发的。 vue create vue项目名 二、项目开发 1.创建项目结构 2.开发功能模块 主入口App.vue <template><div class"boss-app"><Header /><m…

网络带宽测速工具选择指南iperf3 nttcp tcpburn jperf使用详解

简介 本文主要介绍内网&#xff08;局域网&#xff09;与外网&#xff08;互联网&#xff09;的网络带宽测速工具下载地址、选择指南、参数对比、基本使用。 测速工具快速选择指南 测速工具下载地址 iperf 官网下载链接&#xff1a;iperf.fr/iperf-download.php该链接提供了不…

微软的 Copilot 现在可以浏览网页并为您执行操作

在庆祝其 50 岁生日之际&#xff0c;微软正在向其人工智能驱动的 Copilot 聊天机器人传授一些新技巧。 从 BASIC 到 AI&#xff0c;改变世界的公司&#xff1a;微软 微软表示&#xff0c;Copilot 现在可以在“大多数网站”上采取行动&#xff0c;使其能够预订门票、预订餐厅等…

Docker学习--网络相关命令

docker network 命令的作用&#xff1a; 用于管理 Docker 网络。这些命令可以创建、列出、删除和检查网络&#xff0c;帮助用户在 Docker 容器之间建立通信。 常用命令&#xff1a; ①列出所有网络&#xff1a; docker network ls。 输出&#xff1a; NETWORK ID NA…

【Vue3知识】组件间通信的方式

组件间通信的方式 概述**1. 父子组件通信****父组件向子组件传递数据&#xff08;Props&#xff09;****子组件向父组件发送事件&#xff08;自定义事件&#xff09;** **2. 兄弟组件通信****通过父组件中转****使用全局状态管理&#xff08;如 Pinia 或 Vuex&#xff09;** **…

[蓝桥杯] 挖矿(CC++双语版)

题目链接 P10904 [蓝桥杯 2024 省 C] 挖矿 - 洛谷 题目理解 我们可以将这道题中矿洞的位置理解成为一个坐标轴&#xff0c;以题目样例绘出坐标轴&#xff1a; 样例&#xff1a; 输入的5为矿洞数量&#xff0c;4为可走的步数。第二行输入是5个矿洞的坐标。输出结果为在要求步数…

2025年Python的主要应用场景

李升伟 编译 Python在2025年仍是最受欢迎和强大的编程语言之一。其简洁易读的语法以及庞大的库生态系统&#xff0c;使其成为各行业开发者的首选。无论是构建复杂的数据管道&#xff0c;还是自动化重复性任务&#xff0c;Python都能提供广泛的应用场景&#xff0c;以实现快速、…

fastapi完全离线环境(无外网)的访问Swagger所做特殊处理

在互联网环境中&#xff0c;只要 启动FastAPI 服务运行在本地机器上&#xff0c;访问 http://localhost:8000/docs&#xff08;Swagger UI&#xff09;就可以访问到Swagger界面&#xff0c;但是在完全离线环境&#xff08;无外网&#xff09;下如何访问Swagger页面呢&#xff1…

Ubuntu 20.04 出现问号图标且无法联网 修复

在 Ubuntu 中遇到网络连接问题&#xff08;如出现问号图标且无法联网&#xff09;&#xff0c;可以通过以下命令尝试重启网络服务&#xff1a; 1. 推荐先修改DNS 编辑 -> 虚拟机网络编辑器-> VMnet8 ->NAT 设置 -> DNS 设置 -> 设置DNS 服务器 DNS填什么 取决…

哈希表(开散列)的实现

目录 引入 开散列的底层实现 哈希表的定义 哈希表的扩容 哈希表的插入 哈希表查找 哈希表的删除 引入 接上一篇&#xff0c;我们使用了闭散列的方法解决了哈希冲突&#xff0c;此篇文章将会使用开散列的方式解决哈希冲突&#xff0c;后面对unordered_set和unordered_map的…

机器学习(八):K-Means聚类原理与实战

声明&#xff1a;未经允许禁止转载与抄袭。 前言 k k k均值&#xff08; k k k-means&#xff09;聚类算法是一种经典的无监督聚类算法&#xff0c;本文将深入解析其理论原理&#xff0c;并在真是数据集上进行算法实践&#xff0c;话不多说&#xff0c;请看下文。 算法原理 …

判断矩阵A和矩阵B是否相似?

【例题1】 &#xff08;1&#xff09;方法1 &#xff08;2&#xff09;方法2 &#xff08;3&#xff09;方法3 好题\(^o^)/~ 【注意】当二次多项式有重根时&#xff0c;即判别式为零&#xff0c;此时二次多项式是完全平方。

【10】搭建k8s集群系列(二进制部署)之安装Dashboard和CoreDNS

一、部署Dashboard 1.1、创建kubernetes-dashboard.yaml文件 完整的yaml配置文件信息如下&#xff1a; # Copyright 2017 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in …

大数据技术与Scala

集合高级函数 过滤 通过条件筛选集合元素&#xff0c;返回新集合。 映射 对每个元素应用函数&#xff0c;生成新集集合 扁平化 将嵌套集合展平为单层集合。 扁平化映射 先映射后展平&#xff0c;常用于拆分字符串。 分组 按规则将元素分组为Map结构。 归约 …

数据驱动可视化实战:图表狐精准生成图表的完整数据范式

一、数据输入黄金法则 图表狐 - AI图表生成工具,在线数据可视化要求数据描述必须包含三个核心要素&#xff1a; [主体对象] [量化指标] [维度划分] 错误示例 ❌&#xff1a; "展示各部门销售额对比" 正确示例 ✅&#xff1a; "2023年Q1-Q4各部门销售额&a…

苍穹外卖(1)-部分环境配置(git、数据库)

首先配置git 创建好本地仓库之后 把项目弄到远程仓库里去 先进行提交 &#xff0c;后进行推送 &#xff0c;然后gitee创建一个仓库 把这个url复制好 推送后会出来一个 点击推送&#xff0c;会让你输入gitee账号密码&#xff0c;输入自己的账号密码&#xff0c;就可以连接远程仓…