如何在Angular 8中下载Excel文件作为API响应

alen0pnh  于 2022-11-18  发布在  Angular
关注(0)|答案(7)|浏览(279)

我有一个API,返回一个Excel文档作为响应。请求将是一个简单的json。
我已经搜索了谷歌,找到了一些代码库下载文件,我已经在我的应用程序中使用它,但我得到了一些错误,无法找到解决方案。下面是我的代码库。

组件.ts

import rxjs/Rx;

details = {id: 75,name: "some name"}

this.nameService.getData(this.details).subscribe(response => {
this.downloadFile(response);
})

downloadFile(data: Response) {
  const blob = new Blob([data], { type: '.xlsx' });
  const url= window.URL.createObjectURL(blob);
  window.open(url);
}

名称服务.ts

getData(postData) {
  return this.httpService.post('https://localhost:8080/getFile/', postData);
}

http服务.ts

constructor(private http: HttpClient)
post(apiEndpoint: string, request: any) :Observable<any> {
 return this.http.post<any>(apiEndpoint,request);
}

使用上面的代码库,我得到以下两个错误,文件没有下载。
1.获取错误:
“类型响应不可分配给类型Blobpart”(const blob = new Blob([data],{ type:“.xlsx”});)
1.如果我将数据更改为任何(downloadFile(data: any)),则会出现上述错误(1),但我得到的httperror响应为“语法错误:json中json.parse的位置0处出现意外标记P
请帮助,如果任何人找到任何解决上述问题。

iszxjhcz

iszxjhcz1#

1.您需要在请求中设置响应头{ responseType: 'blob'}
1.在创建blob文件时,您需要传入正确的MIME类型。(例如,application/octet-streamapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet)。
component.ts

downloadFile(data: Response) {
  const blob = new Blob([data], { type: 'application/octet-stream' });
  const url= window.URL.createObjectURL(blob);
  window.open(url);
}
0s0u357o

0s0u357o2#

添加页眉{ responseType: 'blob'}
就像这样:

this.http.post<any>(apiEndpoint,request,{ responseType: 'blob'} )
yc0p9oo0

yc0p9oo03#

虽然这里的大多数答案都说使用{ responseType: 'blob'}是有效的,但我建议使用responseType: 'arraybuffer'代替blobobserve: 'response'

this.httpClient.get(resource, {
  headers: this.httpHeaders, // Any custom client side headers like Authorization
  observe: 'response',
  responseType: 'arraybuffer'
});

这样做的好处有两个:

  1. Arraybuffer是通用的字节流,可以使用blobarraybuffer创建Blob对象,使用Content-Type
  2. observe: 'response'还将在解析的响应中包含您在服务器上设置的响应头。
    我使用此方法将arraybuffer的文件名和MIME类型放在Content-DispositionContent-Type响应头中,然后在客户端使用通用下载服务。
    另外,我建议使用File对象而不是Blob,这样可以灵活地为它指定一个文件名,如下所示:
public downloadFile(response: any, fileName?: string) {
    const blob = new Blob([response.body], { type: response.headers.get('content-type') });
    fileName = fileName || response.headers.get('content-disposition').split(';')[0];
    const file = new File([blob], fileName, { type: response.headers.get('content-type') });
    saveAs(file);
}

这也将解决@knbibin提出的关于使用自定义文件名的问题。

wsewodh2

wsewodh24#

在请求中设置响应头{ responseType: 'blob'}
要下载excel,请使用以下功能。
响应- api响应,文件名- excel名称

downloadExcel(response, fileName) {
    // Doing it this way allows you to name the file
    var link = document.createElement('a');
    link.href = window.URL.createObjectURL(res);
    link.download = fileName;
    link.click();
  }
yh2wf1be

yh2wf1be5#

要下载该文件,请使用以下代码

downloadFile(data: Response) {
  const blob = new Blob([data], { type: 'application/octet-stream' });
  fs.saveAs(blob, fileName + '.xlsx');
}
4si2a6ki

4si2a6ki6#

您需要将{ responseType:'application/octet-stream'}在get请求中作为不需要调用post方法

{ responseType : 'application/octet-stream'}

并在.ts文件中

DownLoadExcel(){
    this.MprService.downLoadRFQInfoExcel(this.revisionId).subscribe(data =>{this.downloadFile(data)});
}
    
downloadFile(data: Blob) { 
    const contentType = 'application/vnd.openxmlformats-ficedocument.spreadsheetml.sheet'; 
    const blob = new Blob([data], { type: contentType });
    const url = window.URL.createObjectURL(blob);
    window.open(url);
}
bybem2ql

bybem2ql7#

如果任何人只想从资产下载文件,他们可以使用以下代码:

<a href="./assets/files/file.xlsx" target="_blank"></a>

但是你需要在angular.json中提到位置

"architect": {
   "build": {
      "options": {
    "assets": [
                  "src/assets/files"
              ]
      }
   }
}

相关问题