一、使用post传参的方法下载excel文件
Angular使用HTTP POST下载流文件
在使用Angular开发项目时,通常会有下载文件的功能项。一般是后台返回下载地址,通过标题或者使用window打开下载地址新窗口,浏览器则会识别出流文件进行文件下载。
但是,有时候进行http异步请求,后台返回的并不是下载地址,而是直接返回一个文件流,这时如何使用http请求回来的文件流转换成文件下载?
其实并非Angular框架存地这样的情况,其他如Vue,React甚至Jquery都通过http xhr进行请求而获取的流文件,浏览器也并不会自动识别并自动下载。
二、方案思路
- http请求使用blob的返回类型,
- 获取文件流后,对数据进行Blob,
- 再提交给浏览器进行识别下载。
备注:此时前端只是把从后台获取的流封装一个架子从excel下载下来,并不是解析流, 前端不做解析
三、代码示例
/**
* 导出excel
*/
exportExcel() {
// 此处为了获取全部数据 将分页设置为 0
this.CommonAllSearchInfo.pageNo = 0;
this.CommonAllSearchInfo.pageSize = 0;
const params = {
...this.CommonAllSearchInfo, //解构对象
projectIds: this.CommonAllSearchInfo.projectIds.includes('-1') || this.CommonAllSearchInfo.projectIds.length == 0 ? this.allProjectIdArr : this.CommonAllSearchInfo.projectIds
}
const headerParam = {
responseType: "blob"
}
this.http.postOrgAfterVisitExport(params, headerParam).subscribe(resp => {
this.message.success('导出列表成功');
// resp: 文件流
this.downloadFile(resp,`集团客户池列表`);
this.CommonAllSearchInfo.pageNo = 1;
this.CommonAllSearchInfo.pageSize = 10;
})
}
/**
* 创建blob对象,并利用浏览器打开url进行下载
* @param data 文件流数据
*/
downloadFile(data,downName) {
// 下载类型 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 a = document.createElement('a');
// const fileName = this.datePipe.transform(new Date(), 'yyyyMMdd');
a.href = url;
// a.download = fileName;
a.download = downName+'.xlsx';
a.click();
window.URL.revokeObjectURL(url);
}
备注:
- params 为向后台传递的参数
- 设置了请求头参数 responseType: “blob”
下面是后台返回的流
下面是传递的请求头参数 blob 流
- 最主要的封装还在在于第二段代码 downloadFile(data,downName) 函数
四、请求后台的接口定义
postOrgAfterVisitExport(param?: any,headerParam?:any): Observable<any> {
const queryParams = undefined; // url query的参数
return this.http.post(`${SERVER_URL}/customer/orgStandingBooksExcel`, param, queryParams, headerParam)
.pipe(map((res: any) => {
return res;
}));
五、通用浏览器下载文件
/**
* Transfer the file stream to zip file
* @param {*} data
*/
const downloadFile = (data) => {
const blob = new Blob([data], { type: 'application/zip' });
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `${detailInfo.deviceId}`;
link.click();
URL.revokeObjectURL(url);
};
/**
* Call the download certificate API when click the menu item in context menu
*/
const getDownloadCertificate = () => {
DMSDownloadCertificate(detailInfo.deviceId).then((res) => {
downloadFile(res.data);
});
};
备注: 后台请求接口 (通过封装axios请求,此方法没有设置请求头)
/**
* Download the certificate
* @param {*} data
* @returns
*/
export function DMSDownloadCertificate(data) {
return request({
url: `${baseUrlDMS}/api/enroll/cert/${data}`,
method: 'get',
responseType: 'blob',
});
}