EasyExcel的追加写入(新增POI、CSV)

总结:目前市面上流行的2种 EasyExcel和POI都不是真正的对物理excel文件进行追加导入。只是在缓存里面追加,最后一次性写入,并不能解决内存占用问题。

      • 1.EasyExcel
      • 2.POI
      • 3.CSV

无非就是下面两种逻辑:
1.for循环查询数据,将数据写入缓存,最后一次性写入excel。
2.将已有的excel通过FIleInputStream流读出来,加载到内存当中,然后获取对应sheet页的行数,进行追加操作。

PS:建议使用CSV文件格式,直接使用Java原生的FileUtils追加写入

FileUtils.writeStringToFile(file, sb.toString(), "GBK", true);

下面来讲讲easyExcel、POI、csv相关的代码写法:

要求:
1.对表头进行排序过滤
2.对列进行排序过滤

1.EasyExcel

官网地址:EasyExcel官网

我们使用新版本的,旧的对于字段排序/过滤都不支持<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>//此为线程池异步导出
commonExecutor.execute(() -> {File file = null;ExcelWriter excelWriter = null;try {file = File.createTempFile("a", ".xlsx");file.deleteOnExit();excelWriter = EasyExcel.write(file, UserVO.class).head(headlist)  // 表头,传入一个list集合.includeColumnFieldNames(showColumnList) // 对于UserVO要展示的列集合.orderByIncludeColumn(true) // 是否根据showColumnList集合的顺序排序.autoCloseStream(true) // 自动关闭流.build();WriteSheet writeSheet = EasyExcel.writerSheet("Sheet1").build();// 循环 200/页查询数据int pageNum = 1;int pageSize = 200;while (true) {List<UserVO> voList = getData(pageNum, pageSize); // getData根据业务实现// 将数据写入临时文件 此处循环追加就是写到内存里面excelWriter.write(voList , writeSheet);if (pageNum * pageSize >= count) {break;}pageNum++;}// 数据处理完毕后,刷盘写入物理文件excelWriter.finish();} catch (Exception e) {log.error("导出 异常:" + e.getMessage(), e);} finally {// 删除临时文件if (!Objects.isNull(file)) {file.delete();}}
});

2.POI

网传SXSSFWorkbook可以实现追加写入,然后实操后,其实是覆盖写入

//SXSSFWorkbook 和 XSSFWorkbook 都差不多,只是定义不同,写法都差不多import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;public class ExcelAppender {public static void main(String[] args) {String filePath = "C:\\Local\\Temp\\11.xlsx";// 构造一个查询数据的列表List<String> queryDataList = List.of("query4", "query5", "query6");// 加载已存在的 Excel 文件try (Workbook workbook = new SXSSFWorkbook(new FileInputStream(new File(filePath)))) {Sheet sheet = workbook.getSheetAt(0);// 获取已存在数据的最后一行索引int lastRowNum = sheet.getLastRowNum();// 在最后一行索引的下一行开始追加写入查询数据int rowNum = lastRowNum + 1;for (String queryData : queryDataList) {Row row = sheet.createRow(rowNum++);Cell cell = row.createCell(0);cell.setCellValue(queryData);}// 保存修改后的工作簿到文件try (FileOutputStream outputStream = new FileOutputStream(new File(filePath))) {workbook.write(outputStream); System.out.println("查询数据已覆盖写入到 Excel 文件:" + filePath);} catch (IOException e) {e.printStackTrace();}} catch (IOException e) {e.printStackTrace();}}
}

3.CSV

来写我最终选择的写法CSV,就是追加物理文件数据。很不错。

commonExecutor.execute(() -> {File temp = null;try {temp = File.createTempFile("aaa", ".csv");temp.deleteOnExit();List<List<String>> fillData = new ArrayList<>();// 1.初始化表头,showNameList是表头集合,有顺序的哈~fillData.add(ImmutableList.of(showNameList.toString()));// 2.循环 200/页查询数据int pageNum = 1;int pageSize = 200;while (true) {List<UserVO> recordVOList = getData(pageNum, pageSize);// 3.填充业务数据 我用的反射fillData.addAll(ExcelUtil.convertSortEntityListToDataList(showColumnList, recordVOList));StringBuilder sb = new StringBuilder();for (List<String> rowData : fillData) {sb.append(String.join(",", rowData));sb.append(System.lineSeparator());}try {FileUtils.writeStringToFile(temp, outPutStr, "GBK", true);} catch (IOException e) {log.error("写入CSV 异常:{}", e.getMessage(), e);return;}if (pageNum * pageSize >= count) {break;}pageNum++;fillData.clear();}} catch (Exception e) {log.error("导出 异常:{}", e.getMessage(), e);} finally {// 4.删除临时文件if (!Objects.isNull(temp)) {temp.delete();}}
});

当然,会存在一定的问题,比如csv文件打开时,office全家桶会把日期格式转换,比如:
“2024-01-04 14:28:29” -> “2024/1/4 14:28:29”
就看大家能不能接受了。

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

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

相关文章

js中对数字,超大金额(千位符,小数点)格式化处理

前言 这个问题的灵感来自线上一个小bug&#xff0c;前两天刚看完同事写的代码&#xff0c;对数字类型处理的很好&#xff0c;之前一直都是用正则和toFixed(2)处理数字相关&#xff0c;后面发现使用numeral.js处理更完美。 对于下面这种数据的处理&#xff0c;你能想到几种方法…

燃情瞬间,智能酒精壁炉点亮户外聚会新潮流

在户外聚会中&#xff0c;一种备受瞩目的装饰品和功能性家居设备正逐渐崭露头角&#xff0c;那就是智能酒精壁炉。这种独特的户外装置不仅为聚会场合带来独特的氛围&#xff0c;还具有许多引人注目的优势。 其明亮的火焰不仅照亮整个场所&#xff0c;还散发出温暖迷人的光芒&am…

Git 大量log查看:git log --pretty=oneline

git log 是 Git 版本控制系统中的一个命令&#xff0c;用于展示一个或多个分支的提交历史记录。 当你在 git log 命令后面添加 --prettyoneline 选项时&#xff0c;它会以单行的形式显示提交历史。这意味着每个提交将会在一行内显示&#xff0c;而不是默认的多行显示格式。 具…

浅谈WPF之Popup弹出层

在日常开发中&#xff0c;当点击某控件时&#xff0c;经常看到一些弹出框&#xff0c;停靠在某些页面元素的附近&#xff0c;但这些又不是真正的窗口&#xff0c;而是页面的一部分&#xff0c;那这种功能是如何实现的呢&#xff1f;今天就以一个简单的小例子&#xff0c;简述如…

Python Matplotlib 库使用基本指南

简介 Matplotlib 是一个广泛使用的 Python 数据可视化库&#xff0c;它可以创建各种类型的图表、图形和可视化效果。无论是简单的折线图还是复杂的热力图&#xff0c;Matplotlib 提供了丰富的功能来满足我们的数据可视化需求。本指南将详细介绍如何安装、基本绘图函数以及常见…

FindTheIndexOfTheFirstOccurrenceInAString 【找到第一个匹配的下标】

双指针 字串的所有的字符都匹配完&#xff0c;匹配成功。 如果要与之匹配的字符串剩下的长度小于字串的长度&#xff0c;即剩下的已经不会再满足。 public int strStr(String haystack, String needle) {int index -1, i0, j0;for(i0; i<haystack.length()-needle.length(…

贪心算法Day06

#738.单调递增的数字 力扣题目链接(opens new window) 给定一个非负整数 N&#xff0c;找出小于或等于 N 的最大的整数&#xff0c;同时这个整数需要满足其各个位数上的数字是单调递增。 &#xff08;当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们…

【Redis】Redis面试热点

Redis 集群有哪些方案&#xff1f; 主从复制&#xff1a;解决了高并发问题 哨兵模式&#xff1a;解决了高并发&#xff0c;高可用问题 分片集群&#xff1a;解决了海量数据存储&#xff0c;高并发写的问题 主从复制 图示&#xff1a; 主从复制&#xff1a;单节点 Redis 并发…

NPN PNP SS8050 SS8550 S8050

SS8050的使用及引脚判断方法 今天讲的是NPN型三极管SS8050&#xff0c;主要分为以下几个方面&#xff1a; 一、前言 二、SS8050简介 三、NPN三极管与PNP三极管 四、三极管管脚识别方法 五、不拆卸三极管判断其好坏 六、S8050和SS8050的区别 七、三极管与MOS管的区别 八…

nginx基础面试题以及配置文件解析和命令控制

目录 1、nginx是什么 2、nginx的特点 3、为什么中国大陆有&#xff1a;百度、京东、新浪、网易、腾讯、淘宝等这么多用户使用nginx 4、nginx 的内部技术架构 上一期我们配置安装了nginx接着讲一下nginx配置文件的解析和nginx 命令控制 感谢观看&#xff01;希望能够帮助到…

mapper向mapper.xml传参中文时的乱码问题

1.起因&#xff1a; 在idea中进行模糊查询传参时&#xff0c;发现在idea中查中文查不出记录&#xff0c;在navicate中可以查出来。 2.猜测&#xff1a; 1.idea中的编码问题导致的乱码。 2.idea和navicate的编码一致性导致的乱码。 3.mapper向mapper.xml传参后出现乱码。 3.解…

Qt之数据转换与处理

从串口读取到的QByteAray数据一般需要进行提取和解析&#xff0c;此时就需要将QByteArray数拒转换为各种类型的数据。常用的转换包括&#xff1a; &#xff08;1&#xff09; 转为Hex&#xff0c;用于显示十六进制&#xff0c;这点在调试时特别有用&#xff0c;因为大多HEX码是…

【Vue技巧】Vue2和Vue3组件上使用v-model的实现原理

ChatGPT4.0国内站点&#xff0c;支持GPT4 Vision 视觉模型&#xff1a;海鲸AI 在Vue中&#xff0c;v-model 是一个语法糖&#xff0c;用于在输入框、选择框等表单元素上创建双向数据绑定。当你在自定义组件中实现 v-model 功能时&#xff0c;你需要理解它背后的原理&#xff1a…

DFA算法实战-敏感词过滤

前言 这里的项目实战, 我们使用的是 SpringBoot2.xJDK1.8搭建的,核心思想是借助了Hutool工具类的 WordTree。想了解更多DFA算法的实现可以参考DFA算法的实现 实战案例 1. 引入Hutool的工具类 <dependency><groupId>cn.hutool</groupId><artifactId>…

Python 基础【八】--数据类型-字典【2024.1.11】

1.定义 字典的内容在花括号 {} 内&#xff0c;键-值&#xff08;key-value&#xff09;之间用冒号 : 分隔&#xff0c;键值对之间用逗号 , 分隔&#xff0c;比如创建字典 &#xff0c;如下所示&#xff1a; d{name:小明,age:18}# 使用 dict 函数&#xff1a;强转 # 方式一&am…

mysql group by 之后要把名字放到一个字段里边

分组后的其他字段去重 count(DISTINCT(product)) num_sold,分组后数据存放到一个字段 &#xff08;带着排序&#xff0c;在保存到一个字段&#xff09; group_concat(distinct product order by product separator ‘,’) select sell_date,count(DISTINCT(product)) num_so…

PX4开源项目中遇到的问题

开源项目 kaiyuanxiangmkmonemati/PX4-ROS2-Gazebo-YOLOv8: Aerial Object Detection using a Drone with PX4 Autopilot and ROS 2. PX4 SITL and Gazebo Garden used for Simulation. YOLOv8 used for Object Detection. (github.com) 首先创建python虚拟环境&#xff0c;克…

【一文详解】知识分享:(ASP.Net Core基础学习及快速入门)

背景知识 相关术语 .Net .NET是微软的一个开发平台&#xff0c;这个平台的一大特点就是跨语言性&#xff0c;不管是什么语言&#xff0c;c、c、c#、F#、J#、vb等语言都可以用这个平台合作开发&#xff1b; .NET&#xff0c;它是微软创建的一个用于构建多种不同类型的应用程…

python——combinations()函数详解

combinations() 函数位于 Python 的 itertools 模块中&#xff0c;用于生成一个可迭代对象&#xff0c;包含输入集合中所有长度为 r 的组合。 定义&#xff1a; combinations(iterable, r) 函数接受一个可迭代对象 iterable 和一个整数 r&#xff0c;返回一个包含所有长度为 r…

书生·浦语大模型实战营-学习笔记2

目录 轻松玩转书生浦语大模型趣味Demo1. 大模型及 InternLM 模型介绍2. InternLM-Chat-7B 智能対话 Demo3. Lagent 智能体工具调用 Demo4. 浦语•灵笔图文创作理解 Demo5. 通用环境配置实验记录6. 课后作业 视频地址&#xff1a; (2)轻松玩转书生浦语大模型趣味Demo 文档教程&a…