本文主要是介绍在工作中遇到的后端接口返回一个二进制数据流,前端在界面上创建下载按钮并下载成对应格式的文件导出。
首先介绍后端接口 downloadData
,这是一个传统的RESTFul风格接口。前端接入该接口如下:
export async function downloadData(params: any) {
return request('/demo/download', {
method: 'POST',
data: params,
// 重点,这里需要使用一个 responseType 属性,下面有解释
responseType: 'arrayBuffer', // 或者设置成 'blob'
headers: {
// 公司业务中需要带的一些信息
}
})
}
切记:二进制文件流导出 一定要设置 responseType 属性!!!
如果没有设置
responseType
属性,就会产生文件下载后,打开失败或不能正确打开的问题。关于该属性有兴趣的可在文章最后部分进行了解。
接下来是调用 downloadData
接口。
downloadData({
start: startTime,
end: endTime,
exportType: 0, // 0-excel, 1-csv, 2-json
}).then((res) => {
download(res, startTime, endTime, exportType);
})
接口会返回一个二进制数据流,即上文接口中返回的 res
,如下图所示。
其中, startTime
和 endTime
是用来构建文件名字,exportType
是用来确定导出文件格式后缀的。
根据对应的按钮获取对应文件,并由浏览器进行下载。
const download = (res: any, startDate: any, endDate: any, exportType: any) => {
const blob = new Blob([res])
let filename = "";
let startPrefix = new Date(startDate);
let endPrefix = new Date(endDate);
// 起名,根据日期进行命名,这一步可以省略,换成随便的一个字符串命名。
let date = startPrefix.getFullYear().toString() +
(startPrefix.getMonth() + 1 < 10 ? '0' +
(startPrefix.getMonth() + 1) : startPrefix.getMonth() + 1) +
startPrefix.getDate().toString() + '-' +
endPrefix.getFullYear().toString() +
(endPrefix.getMonth() + 1 < 10 ?
'0' + (endPrefix.getMonth() + 1) :
endPrefix.getMonth() + 1) + endPrefix.getDate().toString();
// 判断后缀,根据你想要下载的文件类型,添加对应后缀。
if (exportType=== 0) filename = date + '.json';
else if (exportType === 1) filename = date + '.xlsx';
else filename = date + '.csv';
if (typeof window.navigator.msSaveBlob !== 'undefined') {
window.navigator.msSaveBlob(blob, filename);
} else {
// 导出
const url: any = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.style.display = 'none';
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url.href);
document.body.removeChild(link);
}
}
导出的方式是通过创建一个 url
后,浏览器自动点击并自行下载。
XMLHttpRequest.responseType
属性是一个枚举类型的属性,返回响应数据的类型。它允许我们手动的设置返回数据的类型。通过设置这个属性,你可以告诉浏览器你期望从服务器接收的数据类型是什么,这样浏览器就可以相应地处理这些数据。这对于提高性能、减少数据处理时间以及确保数据以正确的方式被解析或处理至关重要。
XMLHttpRequest.responseType
可以设置为以下几种类型之一:
-
“”(空字符串,默认值):这表示服务器响应的数据类型不会被预处理,而是作为字符串(
DOMString
)返回。 -
“arraybuffer”:响应数据将被处理为
ArrayBuffer
对象,这是一种通用的、固定长度的二进制数据缓冲区。这对于处理二进制数据(如文件、图像等)非常有用。 -
“blob”:响应数据将被处理为
Blob
对象,这是一种表示不可变、原始数据的类文件对象。这对于处理大文件或二进制数据特别有用。 -
“document”:响应数据将被处理为 HTML 或 XML 文档,并可以通过
responseXML
属性访问。这适用于需要从服务器加载并解析 HTML 或 XML 文档的场景。 -
“json”:响应数据将被自动解析为 JavaScript 对象(JSON 格式)。需要注意的是,并非所有浏览器都支持这个值,但在支持的浏览器中,这可以简化 JSON 数据的处理。
-
“text”:响应数据将被处理为文本字符串。这是最常见的设置之一,适用于大多数基于文本的响应。
通过设置 XMLHttpRequest.responseType
,你可以更灵活地处理来自服务器的数据,从而编写更高效、更易于维护的 JavaScript 代码。例如,如果你知道服务器将返回 JSON 格式的数据,你可以将 responseType
设置为 "json"
(如果浏览器支持),这样浏览器就会自动将响应数据解析为 JavaScript 对象,而无需你手动调用 JSON.parse()
方法。