现在越来越多的业务需要进行数据分析,数据查看等,然后关联的就要用到数据下载
数据下载可以分为几种:
1、返回数据URL,前端直接跳转到URL进行下载;
2、返回数据列表,可以通过xlsx、xlsx-style等相关的插件,通过定制化表头,把列表数据依次遍历循环,然后生产文件;
3、返回数据流,前端经过数据解析和转换从而下载数据。
返回数据URL
这一种是最简单的,只要后端把数据处理好,然后生成现成的文件放在服务器上,我们只要通过a标签跳转过去就行了,或者点击按钮,window.open()打开相应的链接一样达到下载数据的目的。这种弊端就是,每次生成的文件如何不及时删除会占用服务器的内存,当然工作量这一块也要和后端沟通好,因为这种方式,大部分工作量都在后端这边。
返回数据列表
后端返回数据列表,我们可以插件xlsx-style通过遍历循环把数据平铺下来,下载的表格,我们可以高度自定义,可以自己设定表头,表格的区域样式配置,处理sheet内容等等,然后调取插件封装好的方法下载下来。这种方法有个让我吐槽点,就是每次如果下载的数据要增加一列数据或者表头有修改,前后端就要进行动代码,感觉有点麻烦。具体的可以看一下官方文档
返回数据流(强烈推荐)
第三种方法其实是我最推荐的,后端返回数据流,然后前端操作数据流从而下载数据。其实,第二种方法使用插件也是先把数据处理好,然后转为Blob数据流进行下载的。现在详细的介绍一下通过数据流下载的几种方式:
- 使用window.open()方法
- 使用Fetch API或XHR请求
- 使用HTML5的download属性
- 使用FileSaver.js库
- 使用iframe
- 使用FormData和XMLHttpRequest
- 使用axios库
1、使用window.open()方法
在前端使用window.open()方法打开一个新的窗口或标签页,并将后端返回的文件流作为URL传递给该方法。浏览器会自动下载该文件(这里需要后端提前把文件处理好,不然下载的文件会有问题)。
javascript">window.open('http://baidu.***/download', '_blank');
2、使用Fetch API或XHR请求
使用Fetch API或XHR(XMLHttpRequest)发送请求,获取后端返回的文件流,并使用Blob对象创建一个URL。然后将该URL传递给a标签的href属性,并使用JavaScript模拟点击该标签,触发文件下载。
fetch('http://baidu.***/download')
.then(response => response.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'filename.ext';
link.click();
});
这些方法可以根据具体的需求和项目环境选择使用。需要注意的是,后端返回的文件流需要正确设置Content-Disposition响应头,以指定文件的名称和下载方式。
除了上述提到的方法,还有以下五种方法可以实现前端导出和下载后端返回的文件流:
3、使用HTML5的download属性
创建一个a标签,设置href属性为后端返回的文件流的URL,同时设置download属性为文件的名称。将该标签插入到DOM中,并使用JavaScript模拟点击该标签,触发文件下载。
const link = document.createElement('a');
link.href = 'http://baidu.***/download';
link.download = 'filename.ext';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
4、使用FileSaver.js库
引入FileSaver.js库,使用saveAs()方法将后端返回的文件流保存为本地文件。需要将后端返回的文件流转换为Blob对象。
import { saveAs } from 'file-saver';
fetch('http://baidu.***/download')
.then(response => response.blob())
.then(blob => {
saveAs(blob, 'filename.ext');
});
5、使用iframe
创建一个隐藏的iframe,将其src属性设置为后端返回的文件流的URL。浏览器会自动下载该文件。
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = 'http://baidu.***/download';
document.body.appendChild(iframe);
6、使用FormData和XMLHttpRequest
创建一个FormData对象,将后端返回的文件流作为Blob对象添加到FormData中。然后使用XMLHttpRequest发送请求,将FormData作为请求体发送到后端进行下载。
const formData = new FormData();
formData.append('file', blob, 'filename.ext');
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://baidu.***/download');
xhr.send(formData);
7、使用axios库
使用axios库发送请求,获取后端返回的文件流,并将其保存为本地文件。需要将后端返回的文件流转换为Blob对象。
import axios from 'axios';
axios.get('http://baidu.***/download', { responseType: 'blob' })
.then(response => {
const blob = new Blob([response.data]);
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'filename.ext';
link.click();
});
以上的这些方法提供了多种选择来实现前端导出和下载后端返回的数据。然后根据具体的需求和项目环境,选择适合的方法进行实现。
参考文档