以Web方式下载数据有多种场景:

1.服务端本身已经存在文件,此时只需要一个文件访问地址即可下载,比如:将文件URL设置为<a>标签的href属性即可,点击<a>标签就能立即触发浏览器下载文件,此时无需单独设置下载提示信息。

2.下载的文件在服务端并不存在,而是需要查询数据库等才能获取,这种方式无法直接在客户端设置一个文件访问URL,通常是以流式方式下载数据,这就是本篇博文要阐述的情景。

在大多数需要以流方式下载/导出文件的场景,从客户端发出请求,到浏览器端开始下载文件这一段间隔里,是不会有任何提示的,查看网络请求也是处于“Pending”状态的。

甚至有时候因为服务端查询数据耗时慢等问题会让用户误以为没有触发下载,于是又重复点击按钮,在导出大量数据的场景,这可能会加剧服务端的处理负担。

实际上,这却又是一个常见且普遍的问题。

之所以会出现这样的情况,就是因为当我们在浏览器端点击“下载/导出”按钮的时候没有给予用户一个明确的提示信息,或者说没有通过一种有效的手段来防止用户出现重复点击的情况。

那么对于这种以流式方式下载文件的情况,又该如何来实现当用户点击按钮后到浏览器出现下载提示这段时间给予用户一个明确的提示呢?

有一篇博文web程序下载文件添加等待加载效果阐述了使用iframe框架来实现这一功能,但经过实验并未成功。

直到看到另一篇博文前后端分离,前端获取文件流下载文件介绍的方式,经过实验发现,这种方式确实有效。

于是把该博文介绍的方式以一个完整的示例(使用EasyExcel导出表格)整理出来,提供给大家参考(基于Chrome浏览,版本:103.0.5060.134)。

展示效果如下:

服务端核心代码:

// 以流的方式下载文件
@RequestMapping("/download")
public String download(HttpServletRequest request, HttpServletResponse response,
@RequestParam("name") String name,
@RequestParam("age") int age) throws IOException {
System.out.println(String.format("name:%s, age:%s", name, age));
String fileName = URLEncoder.encode(String.format("%s_%s.xlsx", "导出数据", System.currentTimeMillis()), "UTF-8");
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + fileName);
response.addHeader("filename", fileName); // 注意:这里一定要在响应消息头中设置下载文件名
response.setContentType("application/octet-stream; charset=UTF-8");
try {
// 模拟查询数据耗时
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
}
EasyExcel.write(response.getOutputStream(), SubjectExport.class).sheet("sheet").doWrite(dataList);
return null;
}

前端代码:

<html>
<body>
<div>
<form id="paramForm">
<input type="hidden" name="name" value="zhangsan" />
<input type="hidden" name="age" value="12" />
</form>
</div>
<div>
<button id="btnDownloadXhr">导出</button>
</div>
</body>
<script type="text/javascript" src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://cdn.bootcss.com/jquery.blockUI/2.66.0-2013.10.09/jquery.blockUI.min.js"></script>
<script type="text/javascript">
$(function(){
$("#btnDownloadXhr").click(function () {
downloadXhr();
})
}) function downloadXhr() {
var url = "/download";
var param = $("#paramForm").serialize();
var xhr = new XMLHttpRequest();
xhr.open("POST", url);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
xhr.responseType = "blob";
xhr.onload = function () {
console.log("加载完毕");
$.unblockUI();
if (xhr.status === 200) {
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob);
var filename = decodeURI(this.getResponseHeader('filename'));
reader.onload = function (e) {
var a = document.createElement('a');
a.download = filename;
a.href = e.target.result;
//兼容firefox
$('body').append(a);
a.click();
$(a).remove();
}
}
};
xhr.send(param);
console.log("正在加载数据...")
$.blockUI({
message: "正在加载数据..."
});
}
</script>
</html>

完整示例代码地址:test-web-downloadtip,可以直接下载下来在本地运行。

【参考】

https://blog.csdn.net/qq_40527797/article/details/122813537 springBoot+JSP搭建项目

https://easyexcel.opensource.alibaba.com/ Easy Excel

https://blog.csdn.net/fgx_123456/article/details/79603455 web程序下载文件添加等待加载效果

https://blog.csdn.net/w139074301/article/details/121786052 前后端分离,前端获取文件流下载文件

Web流式下载数据时展示提示信息的更多相关文章

  1. 流式大数据计算实践(1)----Hadoop单机模式

    一.前言 1.从今天开始进行流式大数据计算的实践之路,需要完成一个车辆实时热力图 2.技术选型:HBase作为数据仓库,Storm作为流式计算框架,ECharts作为热力图的展示 3.计划使用两台虚拟 ...

  2. 流式大数据计算实践(6)----Storm简介&使用&安装

    一.前言 1.这一文开始进入Storm流式计算框架的学习 二.Storm简介 1.Storm与Hadoop的区别就是,Hadoop是一个离线执行的作业,执行完毕就结束了,而Storm是可以源源不断的接 ...

  3. 精讲RestTemplate第6篇-文件上传下载与大文件流式下载

    本文是精讲RestTemplate第6篇,前篇的blog访问地址如下: 精讲RestTemplate第1篇-在Spring或非Spring环境下如何使用 精讲RestTemplate第2篇-多种底层H ...

  4. 流式大数据计算实践(5)----HBase使用&SpringBoot集成

    一.前言 1.上文中我们搭建好了一套HBase集群环境,这一文我们学习一下HBase的基本操作和客户端API的使用 二.shell操作 先通过命令进入HBase的命令行操作 /work/soft/hb ...

  5. 流式大数据计算实践(2)----Hadoop集群和Zookeeper

    一.前言 1.上一文搭建好了Hadoop单机模式,这一文继续搭建Hadoop集群 二.搭建Hadoop集群 1.根据上文的流程得到两台单机模式的机器,并保证两台单机模式正常启动,记得第二台机器core ...

  6. 流式大数据计算实践(7)----Hive安装

    一.前言 1.这一文学习使用Hive 二.Hive介绍与安装 Hive介绍:Hive是基于Hadoop的一个数据仓库工具,可以通过HQL语句(类似SQL)来操作HDFS上面的数据,其原理就是将用户写的 ...

  7. 流式大数据计算实践(4)----HBase安装

    一.前言 1.前面我们搭建好了高可用的Hadoop集群,本文正式开始搭建HBase 2.HBase简介 (1)Master节点负责管理数据,类似Hadoop里面的namenode,但是他只负责建表改表 ...

  8. 流式大数据计算实践(3)----高可用的Hadoop集群

    一.前言 1.上文中我们已经搭建好了Hadoop和Zookeeper的集群,这一文来将Hadoop集群变得高可用 2.由于Hadoop集群是主从节点的模式,如果集群中的namenode主节点挂掉,那么 ...

  9. Java 使用流读文本数据时乱码 解决方法

    一.问题描述 当我使用FileReader读取文本文件里的汉字时,读出来的是乱码.但为什么字符是正常的呢??? 二.原因探究 其根本原因在于编码标准不同.汉字采用gbk,而idea使用UTF-8.gb ...

  10. ASP.NET Core SignalR中的流式传输

    什么是流式传输? 流式传输是这一种以稳定持续流的形式传输数据的技术. 流式传输的使用场景 有些场景中,服务器返回的数据量较大,等待时间较长,客户端不得不等待服务器返回所有数据后,再进行相应的操作.这时 ...

随机推荐

  1. [转帖]TiFlash 面向编译器的自动向量化加速

    作者:朱一帆 目录​ SIMD 介绍 SIMD 函数派发方案 面向编译器的优化 SIMD 介绍​ SIMD 是重要的重要的程序加速手段.CMU DB 组在 Advanced Database Syst ...

  2. minio性能测试

    minio性能测试 minio的使用 前期使用了s3fs 但是想验证一下性能相关, 所以使用今天简单验证了一下, 其实也可以使用一下fio 但是s3fs 是对象存储 没有修改 只有上传, 所以感觉还是 ...

  3. [转帖]Jmeter之JDBC Request使用方法(oracle)

    https://zhuanlan.zhihu.com/p/121747788 JDBC Request: 这个sampler可以向数据库发送一个jdbc请求(sql语句),它经常需要和JDBC Con ...

  4. [转帖]021系统状态检测命令sosreport

    https://www.cnblogs.com/anyoneofus/p/16467677.html   sosreport命令用于收集系统配置及架构信息并输出诊断文档.

  5. [转帖] GC耗时高,原因竟是服务流量小?

      原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,转载请保留出处. 简介# 最近,我们系统配置了GC耗时的监控,但配置上之后,系统会偶尔出现GC耗时大于1s的报警,排查花了一些力气,故 ...

  6. Docker镜像的基本操作总结

    摘要 容器化是上个十年比较火的技术. 现在看起来在进行总计有点晚了. 不过linux是三十年前的,我依旧没有总结好 道理是一样的. 技术不在于新旧, 重要的是学习到原理. Docker的重要概念 Re ...

  7. Docker 运行 MongoDB的简单办法

    Docker 运行 MongoDB的简单办法 第一步拉取镜像 docker pull mongo 第二步创建自己的目录 地址 10.24.22.240 创建目录 mkdir /mongodb 第三步 ...

  8. 文盘Rust -- 安全连接 TiDB/Mysql

    作者:京东科技 贾世闻 最近在折腾rust与数据库集成,为了偷懒,选了Tidb Cloud Serverless Tier 作为数据源.Tidb 无疑是近五年来最优秀的国产开源分布式数据库,Tidb ...

  9. Go 跟踪函数调用链,理解代码更直观

    Go 跟踪函数调用链,理解代码更直观 目录 Go 跟踪函数调用链,理解代码更直观 一.引入 二.自动获取所跟踪函数的函数名 三.增加 Goroutine 标识 四.让输出的跟踪信息更具层次感 五.利用 ...

  10. Go 匿名函数与闭包

    Go 匿名函数与闭包 匿名函数和闭包是一些编程语言中的重要概念,它们在Go语言中也有重要的应用.让我们来详细介绍这两个概念,并提供示例代码来帮助理解. 目录 Go 匿名函数与闭包 一.匿名函数(Ano ...