以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. 关于decimal非常浅显的学习与整理

    关于decimal非常浅显的学习与整理 背景知识 整数,小数,浮点,定点 整数(Integer)是没有小数部分的数值,可以是正数.负数或零.在计算机中,整数通常以二进制形式存储. 小数(Decimal ...

  2. [转帖]tiup cluster reload

    https://docs.pingcap.com/zh/tidb/stable/tiup-component-cluster-reload 4 Contributors 在修改集群配置之后,需要通过  ...

  3. [转帖]【InfluxDB V2.0】介绍与使用,flux查询、数据可视化

    目录 一.关键概念 二.系统结构 三.配置文件 四.Flux查询语句 五.可视化数据 附录 一.关键概念 相比V1 移除了database 和 RP,增加了bucket. V2具有以下几个概念: ti ...

  4. FIO的再学习-不同Raid,不同磁盘性能验证

    FIO的再学习-不同Raid性能验证 背景 发现自己对iodepth的和num_jobs的理解存在偏差 找了一些资料才发现自己很多地方做的不对. 这里找到一个新资料可以进行模拟数据库的测试 测试配置文 ...

  5. [转帖]【JVM】常用虚拟机参数及实例

    常用参数表 参数 描述 -XX:+PrintGC 启动java虚拟机后,只要遇到gc,就打印日志 -XX:+PrintGCDetails gc发生时,打印更详细的日志 -XX:+PrintHeapAt ...

  6. [转帖]JVM-工具-jcmd

    http://events.jianshu.io/p/011f0e3a39ff 一.jcmd 用法 1.1 基本知识 jcmd 是在 JDK1.7 以后,新增了一个命令行工具. jcmd 是一个多功能 ...

  7. MYSQL 简单验证

    建立测试表 create table test001 (a varchar(2000),b varchar(2000),c varchar(2000),d varchar(2000),e varcha ...

  8. echarts更改x和y轴的颜色

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  9. TypeScript类的修饰符 public private protected的详细讲解

    简单介绍一下public private protected public:当一个类的成员变量没有修饰的时候,默认的就是 public 进行修饰.外部是可以进行访问的. private属性只能够在父类 ...

  10. C# 使用字典将枚举转换为String

    枚举 public enum ColorType { Red = 10, Blue = 20, Green = 30, Yellow = 40, } String var A1 = "AAA ...