解决思路:
- http请求使用blob的返回类型,
- 获取文件流后,对数据进行
Blob
, - 再提交给浏览器进行识别下载。
/**
* 导出excel
*/
exportExcel() {
this.http.get(this.exportUrl, {
responseType: "blob",
headers: new HttpHeaders().append("Content-Type", "application/json")
}).subscribe(resp => {
// resp: 文件流
this.downloadFile(resp);
})
}
/**
* 创建blob对象,并利用浏览器打开url进行下载
* @param data 文件流数据
*/
downloadFile(data: BlobPart) {
// 下载类型 xls
const contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
// 下载类型:csv
const contentType2 = 'text/csv';
const blob = new Blob([data], { type: contentType });
const url = window.URL.createObjectURL(blob);
// 打开新窗口方式进行下载
// window.open(url);
// 以动态创建a标签进行下载
const link = document.createElement('a');
const fileName = '';
link.href = url;
link.download = fileName + '.xlsx';
link.click();
window.URL.revokeObjectURL(url);
}
MDN官方解释:
Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取,也可以转换成 ReadableStream 来用于数据操作。
Blob 表示的不一定是 JavaScript 原生格式的数据。https://developer.mozilla.org/zh-CN/docs/Web/API/Blob
后端传过来的文件流存储在内存中,然后生成的URL就是文件流在内存中的地址,当然这个地址是临时的,浏览器在 document 卸载的时候,会自动释放它们。
MDN官方建议,当不再需要这些URL对象的时候,应该调用URL.revokeObjectURL()主动释放。