当前位置: 首页 > news >正文

POI实现百万数据导出

1、概述

​ 我们都知道Excel可以分为早期的Excel2003版本(使用POI的HSSF对象操作)和Excel2007版本(使用POI的XSSF操作),两者对百万数据的支持如下:
​ Excel 2003:在POI中使用HSSF对象时,excel 2003最多只允许存储65536条数据,一般用来处理较少的数据量。这时对于百万级别数据,Excel肯定容纳不了。
​ Excel 2007:当POI升级到XSSF对象时,它可以直接支持excel2007以上版本,因为它采用ooxml格式。这时excel可以支持1048576条数据,单个sheet表就支持近百万条数据。但实际运行时还可能存在问题,原因是执行POI报表所产生的行对象,单元格对象,字体对象,他们都不会销毁,这就导致OOM的风险。

2、解决方案分析

​ 对于百万数据量的Excel导入导出,只讨论基于Excel2007的解决方法。在ApachePoi 官方提供了对操作大数据量的导入导出的工具和解决办法,操作Excel2007使用XSSF对象,可以分为三种模式:

java代码解析xml

dom4j:一次性加载xml文件再解析

SAX:逐行加载,逐行解析

用户模式: 用户模式有许多封装好的方法操作简单,但创建太多的对象,非常耗内存(之前使用的方法)

事件模式: 基于SAX方式解析XML,SAX全称Simple API for XML,它是一个接口,也是一个软件包。它是一种XML解析的替代方法,不同于DOM解析XML文档时把所有内容一次性加载到内存中的方式,它逐行扫描文档,一边扫描,一边解析。

SXSSF对象:是用来生成海量excel数据文件,主要原理是借助临时存储空间生成excel
在这里插入图片描述

3、原理分析

在实例化SXSSFWorkBook这个对象时,可以指定在内存中所产生的POI导出相关对象的数量(默认100),一旦内存中的对象的个数达到这个指定值时,就将内存中的这些对象的内容写入到磁盘中(XML的文件格式),就可以将这些对象从内存中销毁,以后只要达到这个值,就会以类似的处理方式处理,直至Excel导出完成。

4、百万数据的导出

4.1、模拟数据

第一步、创建表

CREATE TABLE `tb_user2` (`id` bigint(20) NOT NULL  COMMENT '用户ID',`user_name` varchar(100) DEFAULT NULL COMMENT '姓名',`phone` varchar(15) DEFAULT NULL COMMENT '手机号',`province` varchar(50) DEFAULT NULL COMMENT '省份',`city` varchar(50) DEFAULT NULL COMMENT '城市',`salary` int(10) DEFAULT NULL,`hire_date` datetime DEFAULT NULL COMMENT '入职日期',`dept_id` bigint(20) DEFAULT NULL COMMENT '部门编号',`birthday` datetime DEFAULT NULL COMMENT '出生日期',`photo` varchar(200) DEFAULT NULL COMMENT '照片路径',`address` varchar(300) DEFAULT NULL COMMENT '现在住址' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

2、创建存储过程

DELIMITER $$    -- 重新定义“;”分号
DROP PROCEDURE IF EXISTS test_insert $$   -- 如果有test_insert这个存储过程就删除
CREATE PROCEDURE test_insert()			  -- 创建存储过程BEGINDECLARE n int DEFAULT 1;				    -- 定义变量n=1SET AUTOCOMMIT=0;						    -- 取消自动提交while n <= 5000000 do					INSERT INTO `tb_user2` VALUES ( n, CONCAT('测试', n), '13800000001', '北京市', '北京市', '11000', '2001-03-01 21:18:29', '1', '1981-03-02 00:00:00', '\\static\\user_photos\\1.jpg', '北京市西城区宣武大街1号院');SET n=n+1;END while;COMMIT;
END $$

3、开始执行

CALL test_insert();

插入500W数据大概需要200至300秒左右

4.2、思路分析

导出时使用的是SXSSFWorkBook这个类,一个工作表sheet最多只能放1048576行数据, 当我们的业务数据已超过100万了,一个sheet就不够用了,必须拆分到多个工作表。

导出百万数据时有两个弊端:

1、不能使用模板

2、不能使用太多的样式

也就是说导出的数据太多时必须要放弃一些。

4.3、代码实现

UserController代码

@GetMapping(value = "/downLoadMillion",name = "导出用户百万数据的导出")
public void downLoadMillion(Long id,HttpServletRequest request,HttpServletResponse response) throws Exception{userService.downLoadMillion(request,response);
}

UserService代码

public void downLoadMillion(HttpServletRequest request, HttpServletResponse response) throws Exception {
//        创建一个空的工作薄Workbook workbook = new SXSSFWorkbook();int page = 1;int pageSize=200000;int rowIndex = 1; //每一个工作页的行数int num = 0; //总数据量Row row = null;Cell cell = null;Sheet sheet = null;while (true){  //不停地查询List<User> userList = this.findPage(page,pageSize);if(CollectionUtils.isEmpty(userList)){  //如果查询不到就不再查询了break;}if(num%1000000==0){  //每100W个就重新创建新的sheet和标题rowIndex = 1;//        在工作薄中创建一个工作表sheet = workbook.createSheet("第"+((num/1000000)+1)+"个工作表");
//        设置列宽sheet.setColumnWidth(0,8*256);sheet.setColumnWidth(1,12*256);sheet.setColumnWidth(2,15*256);sheet.setColumnWidth(3,15*256);sheet.setColumnWidth(4,30*256);//            处理标题String[] titles = new String[]{"编号","姓名","手机号","入职日期","现住址"};//        创建标题行Row titleRow = sheet.createRow(0);for (int i = 0; i < titles.length; i++) {cell = titleRow.createCell(i);cell.setCellValue(titles[i]);}}//        处理内容for (User user : userList) {row = sheet.createRow(rowIndex);cell = row.createCell(0);cell.setCellValue(user.getId());cell = row.createCell(1);cell.setCellValue(user.getUserName());cell = row.createCell(2);cell.setCellValue(user.getPhone());cell = row.createCell(3);cell.setCellValue(simpleDateFormat.format(user.getHireDate()));cell = row.createCell(4);cell.setCellValue(user.getAddress());rowIndex++;num++;}page++;// 继续查询下一页}
//            导出的文件名称String filename="百万数据.xlsx";
//            设置文件的打开方式和mime类型ServletOutputStream outputStream = response.getOutputStream();response.setHeader( "Content-Disposition", "attachment;filename="  + new String(filename.getBytes(),"ISO8859-1"));response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");workbook.write(outputStream);}

4.4、测试结果

导出的这个文档大概需要3-5分钟的时间,有105 MB,内容如下
在这里插入图片描述

注意:使用附件的形式下载,前端访问必须通过window.open(),否则附件可能无法下载。

相关文章:

POI实现百万数据导出

1、概述 ​ 我们都知道Excel可以分为早期的Excel2003版本&#xff08;使用POI的HSSF对象操作&#xff09;和Excel2007版本&#xff08;使用POI的XSSF操作&#xff09;&#xff0c;两者对百万数据的支持如下&#xff1a; ​ Excel 2003&#xff1a;在POI中使用HSSF对象时&#…...

如何制作党建专题汇报片

通过展示党组织的凝聚力和战斗力&#xff0c;增强党员的组织归属感和团结合作意识。通过宣传片&#xff0c;可以加强党组织的凝聚力&#xff0c;推动党的事业发展。制作党建专题汇报片需要一定的前期准备和后期制作技巧。下面是由深圳党建专题汇报片制作公司老友记小编为您整理…...

沉浸式VR虚拟实景样板间降低了看房购房的难度

720 全景是一种以全景视角为特点的虚拟现实展示方式&#xff0c;它通过全景图像和虚拟现实技术&#xff0c;将用户带入一个仿佛置身其中的沉浸式体验中。720 全景可以应用于旅游、房地产、展览等多个领域&#xff0c;为用户提供更为直观、真实的体验。 在房地产领域&#xff0c…...

如何在Linux环境下给Web应用配置HTTPS证书

如何在Linux环境下给Web应用配置HTTPS证书 在当今互联网时代&#xff0c;保护用户数据的安全性至关重要。为你的Web应用启用HTTPS协议是确保数据传输加密和身份验证的一种有效方式。本文将指导你如何在Linux环境下为Web应用程序配置HTTPS证书。 1. 获取SSL证书 首先&#xf…...

面试题-React(七):React组件通信

在React开发中&#xff0c;组件通信是一个核心概念&#xff0c;它使得不同组件能够协同工作&#xff0c;实现更复杂的交互和数据传递。常见的组件通信方式&#xff1a;父传子和子传父 一、父传子通信方式 父组件向子组件传递数据是React中最常见的一种通信方式。这种方式适用…...

MASM32编程调用 API函数RtlIpv6AddressToString,Windows 10 容易,Windows 7 折腾

一、需求分析 最近用MASM32编程更新SysInfo&#xff0c;增加对IPv6连接信息的收集功能&#xff0c;其中涉及到 MIB_TCP6ROW_OWNER_MODULE 结构体&#xff1a; ;typedef struct _MIB_TCP6ROW_OWNER_MODULE { ; UCHAR ucLocalAddr[16]; ; DWORD dwLocalScope…...

为什么使用Nacos而不是Eureka(Nacos和Eureka的区别)

文章目录 前言一、Eureka是什么&#xff1f;二、Nacos是什么&#xff1f;三、Nacos和Eureka的区别3.1 支持的CAP3.2连接方式3.3 服务异常剔除3.4 操作实例方式 总结 前言 为什么如今微服务注册中心用Nacos相对比用Eureka的多了&#xff1f;本文章将介绍他们之间的区别和优缺点…...

Python作业一

目录 1、用循环语句求122333444455555的和 2、求出2000-2100的所有闰年&#xff0c;条件是四年一闰&#xff0c;百年不闰&#xff0c;四百年再闰 3、输入两个正整数&#xff0c;并求出它们的最大公约数和最小公倍数 4、求出100以内的所有质数 5、求100以内最大的10个质数的…...

protobuf概览

protobuf protobuf是由谷歌推出的二进制序列化与反序列化库对象。也是著名GRPC的底层依赖&#xff0c;它独立于平台及语言的序列化与反序列化标准库。 相关网址 protobuf IDL描述protobuf 开源库grpc-知乎grpc官方示例 安装protobuf可以使用vcpkg进行简易安装依赖&#xff…...

<C++> SSE指令集

SSE指令集 include库 #include <mmintrin.h> //MMX #include <xmmintrin.h> //SSE(include mmintrin.h) #include <emmintrin.h> //SSE2(include xmmintrin.h) #include <pmmintrin.h> //SSE3(include emmintrin.h) #include <tmmintrin.h> /…...

cortex-A7核LED灯实验--STM32MP157

实验目的&#xff1a;实现LED1 / LED2 / LED3三盏灯工作 一&#xff0c;分析电路图 1&#xff0c;思路 分析电路图可知&#xff1a; 网络编号 引脚编号 LED1 PE10 LED2 > PF10 LED3 > PE8 2&#xff0c;工作原理&#xff1a; 写1&#xff1a;LED灯亮&#xf…...

WPF实战项目十三(API篇):备忘录功能api接口、优化待办事项api接口

1、新建MenoDto.cs /// <summary>/// 备忘录传输实体/// </summary>public class MenoDto : BaseDto{private string title;/// <summary>/// 标题/// </summary>public string Title{get { return title; }set { title value; }}private string con…...

clickhouse(十四、分布式DDL阻塞及同步阻塞问题)

文章目录 一、分布式ddl 阻塞、超时现象验证方法解决方案 二、副本同步阻塞现象验证解决方案 一、分布式ddl 阻塞、超时 现象 在clickhouse 集群的操作中&#xff0c;如果同时执行一些重量级变更语句&#xff0c;往往会引起阻塞。 一般是由于节点堆积过多耗时的ddl。然后抛出…...

怎么入门网络安全(黑客)?

目录&#xff1a; 一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员&#xff08;以编程为基础的学习&#xff09;再开始学习2.不要把深度学习作为入门第一课3.以黑客技能、兴趣为方向的自学误区&#xff1a;4.不要收集过多的资料二、学习网络安全的一些前期准备三…...

c++ boost::json

Boost社区12月11日发布了1.75版本&#xff0c;在之前&#xff0c;​​Boost使用Boost.PropertyTree解析​​JSON​​​&#xff0c;​​XML​​​&#xff0c;​​INI​​​和​​INFO​​​格式的文件。但是由于成文较早及需要兼容其他的数据格式&#xff0c;相比较于其他的​…...

《Flink学习笔记》——第九章 多流转换

无论是基本的简单转换和聚合&#xff0c;还是基于窗口的计算&#xff0c;我们都是针对一条流上的数据进行处理的。而在实际应用中&#xff0c;可能需要将不同来源的数据连接合并在一起处理&#xff0c;也有可能需要将一条流拆分开&#xff0c;所以经常会有对多条流进行处理的场…...

openmmlab出现KeyError: ‘xxx is not in the model registry....‘

问题描述 在复现基于mmpose框架的算法时&#xff0c;运行程序出现KeyError: xxx is not in the model registry....的问题&#xff0c;报错原因是自定义的backbone等结构或者某些当前代码使用的方法没有注册到现有的包中, 导致在import的时候无法导入该方法。 解决方案 找到…...

错误代码0x80131500要怎么解决?快速修复方法

错误代码0x80131500通常与.NET Framework 相关的问题有关。它可能表示.NET Framework的安装损坏、版本冲突或系统文件缺失等。下面我们一起来探讨一下解决错误代码0x80131500有哪些。 以下是一些解决方法 安装最新的.NET Framework版本&#xff1a;访问Microsoft官方网站&…...

PMO(Project Management Office)

PMO 是项目管理办公室&#xff08;Project Management Office&#xff09;的缩写。它是组织内的一个部门或团队&#xff0c;负责支持和促进项目管理活动&#xff0c;以确保项目按时、按预算、按要求完成。 PMO 的职责和角色可以因组织的性质和需求而有所不同&#xff0c;但通常…...

STM32 CUBEMX CAN通信数据发送失败原因分析

CAN通信是一种数据通信协议&#xff0c;用于在不同设备之间进行通信。它是一种高效的、实时的、可靠的、多主机的、串行通信系统&#xff0c;通常用于汽车电子、工业自动化等领域。CAN通信协议是由德国BOSCH公司于1986年引入&#xff0c;并在欧洲和日本广泛使用。CAN通信具有独…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序

一、开发准备 ​​环境搭建​​&#xff1a; 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 ​​项目创建​​&#xff1a; File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行&#xff1a; rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

生信服务器 | 做生信为什么推荐使用Linux服务器?

原文链接&#xff1a;生信服务器 | 做生信为什么推荐使用Linux服务器&#xff1f; 一、 做生信为什么推荐使用服务器&#xff1f; 大家好&#xff0c;我是小杜。在做生信分析的同学&#xff0c;或是将接触学习生信分析的同学&#xff0c;<font style"color:rgb(53, 1…...