excel导出百万数据与进度条展示

news2024/11/23 17:18:55

前言

需求:用户在UI界面上选择想要导出的列,然后点击导出按钮,就能导出用户想要的数据。

效果展示

在这里插入图片描述

可能会产生的问题
1.如果同步到数据,接口很容易造成超时。
2.如果把数据一次性装载到内存里,很容易造成OOM与GC。
3.如果数据量太大sql语句查询也会很慢。

以下是批量导出解决的方案,如有更好的办法请支持。

1.在pom文件中导入poi的包

		<poi.version>4.1.2</poi.version>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>${poi.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml-schemas</artifactId>
			<version>${poi.version}</version>
		</dependency>

2.查询导出数据条数

select count(id) from you_table_name;

3.通过总条数计算需要进行几次分页查询
每次查询20w条数据,每次向excel输出1w条,减轻对内存的压力,已经减少用户等待时长。

 int pageSize = 200000;  // 每页显示的记录数
 if (totalCount > 200000) {
  int totalPages = (int) Math.ceil((double) totalCount / pageSize);
  for (int page = 1; page <= totalPages; page++) {
   int offset = (page - 1) * pageSize;
   //组装SQL语句
   Map<String, Object> sqlParamsMap = getDownloadOrgDataLimit(filters, filedList, offset, pageSize);
   String sql = (String) sqlParamsMap.get("sql");
   //查询数据
   List<Map<String, String>> dataset = listOfSQL(sql.toString());
   int totalSize = dataset.size();
   //定义每次只输出1万条
   int batchSize = 10000;
   for (int i = 0; i < totalSize; i += batchSize) {
       int endIndex = Math.min(i + batchSize, totalSize);
       //批次
       List batch = Arrays.asList(dataset.toArray()).subList(i, endIndex);
       Iterator<Map> it = batch.iterator();
        while (it.hasNext()) {
        	Row row = sheet.createRow(index);
        	//循环输出数据...
		}
    }
  }
 }

4.为了让UI界面更直观的观察到导出进度可以加一个进度条

 //导出的进度条信息
   double dPercent=(double)index/totalCount;   //将计算出来的数转换成double
   int  percent=(int)(dPercent*100);               //再乘上100取整
   request.getSession().setAttribute("curCount", index);
   request.getSession().setAttribute("percent", percent);    //比如这里是50
   request.getSession().setAttribute("percentText",percent+"%");//这里是50%
   //...也可以增加当前导出条数,剩余条数

5.前端需要频繁获取进度条进度

			//下载数据
 			downloadOrgData(){
 					//将刷新进度条状态打开
                    this.downloadFlag=true;
                    //执行进度条刷新方法
                    this.flushProgress();
                    axios.get("/org/orgDataDownload/",{
                        params:{
                            filedList: this.filedList.toString()
                        },
                        timeout:600000,
                        responseType:'blob'
                    }).then(res=>{
                        var blob = new Blob([res.data])
                        let fileName =  decodeURI(res.headers['content-disposition'].split("filename= ")[1])
                        var downloadElement = document.createElement('a');
                        var href = window.URL.createObjectURL(blob); //创建下载的链接
                        downloadElement.href = href;
                        downloadElement.download = fileName; //下载后文件名
                        document.body.appendChild(downloadElement);
                        downloadElement.click(); //点击下载                  
                        document.body.removeChild(downloadElement); //下载完成移除元素  
                        window.URL.revokeObjectURL(href); //释放掉blob对象
                        this.downloadFlag=false;    //关闭状态
                    })
                },
 			flushProgress(){
                    $.ajaxSettings.async = false;
                    //刷新进度条
                  if (this.downloadFlag){
                      window.setTimeout(function(){
                          var timer=window.setInterval(function(){
                              axios.get("/org/flushProgress").then(res=>{
                                  let progress =  res.data.data.map.percent;

                                  const progressBar = document.querySelector('.progress');
                                  const progressText = document.querySelector('.progress-text');
                                  if (progress===null){
                                      progressText.innerText = `数据准备中`;
                                  }else if (progress===100){
                                      progressText.innerText = `文档下载中`;
                                  } else {
                                      progressBar.style.width = `${progress}%`;
                                      progressText.innerText = `${progress}%`;
                                  }
                                  if(res.data.data.map.percent=="100"){
                                      window.clearInterval(timer);
                                  }
                              })
                          },800);
                      },800);
                  }
                    $.ajaxSettings.async = true;
                },

其他方案:如果请求超时时间太长,配置也不能修改的情况下,可以使用异步导出。
1.导出成功后将excel上传到OSS,用户直接下载OSS中文件。
2.导出成功后将消息发送到mq中,mq消费消息时通知用户下载excel.

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

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

相关文章

【计算机网络自顶向下】简答题习题总结(二)

目录 第二章 应用层 HTTP FTP文件传输协议 电子邮件 域名系统DNS 内容分发网络CDN 常考问题 题目 第二章 应用层 HTTP 网页&#xff08;Web页&#xff0c;或称文档&#xff09;由许多对象组成&#xff0c;每个对象被一个URL(Uniform Resource Locator统一资源定位符)寻…

帅呆!接口开发不用写Controller、Service、Dao、Mapper、XML、VO,全自动生成

今天给小伙伴们介绍一个Java接口快速开发框架-magic-api 简介 magic-api 是一个基于 Java 的接口快速开发框架&#xff0c;编写接口将通过 magic-api 提供的 UI 界面完成&#xff0c;自动映射为 HTTP 接口&#xff0c;无需定义 Controller、Service、Dao、Mapper、XML、VO 等…

MySQL连环炮,你抗的住嘛?

最近后台好多小伙伴发私信咨询阿Q&#xff0c;问马上就是金九银十的面试黄金期了&#xff0c;该如何在三个月内突击一下&#xff0c;以便更好地通过面试呢&#xff1f; 有想赚点外块|技术交流的朋友&#xff0c;欢迎来撩 阿Q的想法就是需要对自己掌握的知识进行归纳整理&#x…

云原生应用交付平台Orbit设计理念与价值主张

本文作者&#xff1a;何文强——腾讯云 CODING 高级架构师。 负责 CODING DevOps产品解决方案架构设计和技术产品布道以及 CODING 云原生技术研究与落地实践。在多个技术大会担任演讲嘉宾&#xff0c;腾讯云 CODING DevOps 课程认证出品人&#xff0c;腾讯云云原生训练营核心初…

论文解读:DETRs Beat YOLOs on Real-time Object Detection

发表时间&#xff1a;2023 论文地址&#xff1a;https://arxiv.org/abs/2304.08069 项目地址&#xff1a;https://github.com/PaddlePaddle/PaddleDetection/tree/develop/configs/rtdetr 【官方】 或 https://github.com/ultralytics/ultralytics/tree/main/ultralytics/vit/r…

大数据云计算运维之HA高可用服务搭建

HA高可用服务搭建 1、HA Cluster高可用集群 HA是High Available缩写。 HA Cluster是指高可用性集群&#xff0c;是保证业务连续性的有效解决方案&#xff0c;一般 有两个或两个以上的节点&#xff0c;且分为活动节点及备用节点。 FailOver&#xff1a;故障自动切换&#xff…

前端后端交互-ElementUI(日期选择器)

日期选择器 页面效果 页面效果 组件源码 <!-- daterange: 范围选择类型format: 绑定后表单中显示的格式value-format: 传递时显示的格式--> <template><el-date-picker v-model"rangeTime" type"daterange" range-separator"至" …

RabbitMQ使用延迟插件,代码量直接减少一半!

今天介绍一下使用RabbitMQ的延迟插件方便实现延迟消息的方案。 RabbitMQ 是一个由 Erlang 语言开发的 AMQP(高级消息队列协议) 的开源实现。 RabbitMQ 是轻量级且易于部署的&#xff0c;能支持多种消息协议。 RabbitMQ 可以部署在分布式和联合配置中&#xff0c;以满足高规模…

【立体视觉(四)】之极线校正与双目视觉

【立体视觉&#xff08;四&#xff09;】之极线校正与双目视觉 一、极线校正一&#xff09;Fusiello校正法1. 转换矩阵计算1&#xff09;计算旋转矩阵 R n R_n Rn​2&#xff09;计算内参矩阵 K n K_n Kn​3&#xff09;计算转换矩阵 T T T 2. 核线影像生成 二、双目视觉 此…

css基础知识五:CSS中,有哪些方式可以隐藏页面元素?区别?

一、前言 在平常的样式排版中&#xff0c;我们经常遇到将某个模块隐藏的场景 通过css隐藏元素的方法有很多种&#xff0c;它们看起来实现的效果是一致的 但实际上每一种方法都有一丝轻微的不同&#xff0c;这些不同决定了在一些特定场合下使用哪一种方法 二、实现方式 通过…

【IC设计】ICC1 workshop lab guide 学习笔记——Lab 2 Design Planning Task1-4

文章目录 Lab 2 Design Planning2.1 Load the Design2.2 Initialize the Floorplan2.3 Preplace the Macros Connected to I/O Pads2.4 Perform Virtual Flat Placement Lab 2 Design Planning 2.1 Load the Design 进入lab2_dp目录并打开icc_shell&#xff0c;打开orca_lib.…

雪花去噪算法学习记录(一)之基础知识

在进行实验过程中&#xff0c;需要完成对雪天图像的处理&#xff0c;其中一个主要操作为去雪。相较于去雾&#xff0c;去雨模型&#xff0c;去雪模型相对较少&#xff0c;因此在研究时所能够借鉴的资料有限&#xff0c;这对我们的研究造成了一定困扰。 模型算法 DesnowNet网络…

[VPN]华为SecoClient客户端Linux使用

准备 安装环境&#xff1a;CentOS 下载安装包&#xff1a; # wget http://www.corem.com.cn/sites/default/files/tools/secoclient/secoclient-linux-64-7.0.2.26.run 安装 在root用户下&#xff0c;执行&#xff1a; # chmod x secoclient-linux-64-7.0.2.26.run # ./secoc…

瞎搞!你真的懂什么是ERP、中台、低代码吗?

企业数字化领域从来都不缺新概念 从制造资源计划到中台&#xff0c;企业MRP报表数字还没对齐&#xff0c;就要忙着“去烟囱”化&#xff1b; 从中台到低代码&#xff0c;企业“数据孤岛”还没打通&#xff0c;又要忙着“赋能数字化能力”给业务人员了。 这一来二去&#xff0c;…

已有仓库,上传代码,如果你是先写代码,想上传git上你可以这样操作

已有仓库,上传代码&#xff0c;如果你是先写代码&#xff0c;想上传git上你可以这样操作 第一步&#xff1a;初始化 git git init 第二步&#xff1a;添加文件 git add * 第三步&#xff1a;提交文件 git commit -m "完整项目可直接下载使用" 第四步&#xff1a;配置…

【MySql】MySql索引的操作

文章目录 索引结构问题聚簇索引与非聚簇索引索引操作创建主键索引唯一索引创建普通索引创建全文索引创建删除索引查询索引索引创建原则 索引结构问题 InnoDB 在建立索引结构来管理数据的时候&#xff0c;其他数据结构为何不行 链表:线性遍历,在效率上是不合适的 二叉搜索树&am…

如何用Jmeter提取和引用Token

1.执行获取token接口 在结果树这里&#xff0c;使用$符号提取token值。 $根节点&#xff0c;$.data.token表示提取根节点下的data节点下的token节点的值。 2.使用json提取器&#xff0c;提取token 变量路径就是把在结果树提取的路径写上。 3.使用BeanShell取样器或者BeanShell后…

在 Navicat Premium 中管理 MySQL 用户 | 第 2 部分:创建新用户

第 2 部分&#xff1a;创建新用户 第 2 部分&#xff1a;创建新用户 第 1 部分 中&#xff0c;我们学习了如何使用 Navicat Premium 用户管理工具保护 MySQL 的 root 帐号。本篇文章将集中介绍如何设置新用户的帐号详细信息、帐号限制和 SSL 设置。如果你想边学边用&#xff1…

做好用户体验设计 关键看5个方面

用户来了就走&#xff0c;用户吐槽不好用&#xff0c;用户留不住&#xff0c;好的功能没人用&#xff0c;这到底是怎么回事&#xff1f;问题关键在于好的用户体验设计&#xff0c;而做好用户体验设计&#xff0c;关键看5个方面&#xff1a; 1、是否有用 我们需要考量产品。对用…

如何用数字人技术让课堂活起来?番职院和3DCAT实时云渲染给出答案

2023年4月20日&#xff0c;广州市第二届智慧教育成果巡展活动在番禺职业技术学院&#xff08;下文简称番职院&#xff09;举行&#xff0c;本次活动的主题是智能AI助教—让课堂活起来。 活动现场&#xff0c;瑞云科技受邀展示了其自主研发的瑞云数字人课堂互动教学解决方案。数…