话不多说,先上代码
// 导出
exportData() {
// const curDate: any = new Date();
this.visualSplineService.exportLoanDetailLst(this.businessList, 'exportDistributorBusiness')
.pipe(finalize(() => this.loading = false))
.subscribe((response: any) => {
if (response.ok) {
const reader = new FileReader();
reader.onload = (readRes: any) => {
if (readRes.target.result.includes('success')) {
if (!JSON.parse(readRes.target.result).success) {
this.log.error('导出失败' + JSON.parse(readRes.target.result).message || '');
}
} else {
const link = document.createElement('a');
const blob = new Blob([response.body], { type: 'application/xlsx' }),
doloadUrl = window.URL.createObjectURL(blob);
link.setAttribute('href', doloadUrl);
const fileName = '经销商业务量汇总.xlsx';
link.setAttribute('download', fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
this.log.success('正在为您导出,请稍后......');
}
};
reader.readAsText(response.body);
}
}, error => {
this.log.error('导出失败:', error.error);
});
}
接口:
// 放款客户明细/经销商明细导出
exportLoanDetailLst(params: any, name: string): Observable<any> {
const url = `loan/${name}`;
const options: Object = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
responseType: 'blob', observe: 'response'
};
return this.http.post(url, params, options).pipe(map(super.handleSuccess), catchError(super.handleError));
}
千里之行,始于足下,接下来进行一步一步的解析:
先来看一个简单的实例:只管***下载***,不处理其他
this.archiveBorrowService.downLoadTemplate(this.temName)
.pipe(finalize(() => this.isLoading = false))
.subscribe((response: any) => {
const link = document.createElement('a');
const blob = new Blob([response.body], { type: 'application/xlsx' }),
doloadUrl = window.URL.createObjectURL(blob);
link.setAttribute('href', doloadUrl);
link.setAttribute('download', this.fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}, error => this.log.error('下载失败。', error));
}
步骤:
首先,当接口返回response后 ,创建了一个a标签,
然后利用BLOB处理二进制流,这里限制接收的数据类型xlsx 详见下方
给创建的a标签添加属性href为创建的链接
给a标签添加属性download,并给下载download属性一个下载文件名 详见下方
隐藏掉创建好的a标签
模拟点击a标签
删除a标签
总结一下:这里其实就是一个 假装的a标签点击下载的过程,创建一个a标签来作为这个下载东西的载体,通过Blob来接收二进制流的数据
1、Blob() 构造函数返回一个新的 Blob 对象。 blob的内容由参数数组中给出的值的串联组成。
1)array 是一个由ArrayBuffer, ArrayBufferView, Blob, DOMString 等对象构成的 Array ,或者其他类似对象的混合体,它将会被放进 Blob。DOMStrings会被编码为UTF-8。
2)、options 是一个可选的BlobPropertyBag字典,它可能会指定如下两个属性:
type,默认值为 “”,它代表了将会被放入到blob中的数组内容的MIME类型。
endings,默认值为"transparent",用于指定包含行结束符\n的字符串如何被写入。 它是以下两个值中的一个: “native”,代表行结束符会被更改为适合宿主操作系统文件系统的换行符,或者 “transparent”,代表会保持blob中保存的结束符不变
2、URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象
再来看另一部分:
.subscribe((response: any) => {
console.log(response);
if (response.ok) {
const reader = new FileReader();
reader.onload = (readRes: any) => {
if (readRes.target.result.includes('success')) {
console.log(readRes);
if (!JSON.parse(readRes.target.result).success) {
this.log.error('导出失败' + JSON.parse(readRes.target.result).message || '');
}
先看response里面返回ok来判断接口是否通了
再创建一个FileReader来放一下下载下来的这个文件,
FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据
读取完成文件后,我们来看一下readRes,这里每个后台都不大一样,具体情况具体修改
readAsText 方法可以将 Blob 或者 File 对象转根据特殊的编码格式转化为内容(字符串形式)
还要待考究
接口:
接口这里因为是post 所以将规定的放入body中,定义请求头的类型和返回值类型blob
const options: Object = {
headers: new HttpHeaders({ 'Content-Type': 'application/json' }),
responseType: 'blob', observe: 'response'
};