繁体   English   中英

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

[英]How to download an excel file in Angular 8 as an API response

我有一个 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. 得到错误:

在创建 Blob(const blob = new Blob([data], { type: '.xlsx' }); 时“类型响应不可分配给类型 Blobpart”

  1. 如果我将数据更改为任何(downloadFile(data: any))以上错误 (1) 将 go 但我收到一个httperror响应 '语法错误:json 中的意外令牌 P position 0 json.parse

如果有人找到上述问题的任何解决方案,请提供帮助。

添加 header { responseType: 'blob'}

像这样:

this.http.post<any>(apiEndpoint,request,{ responseType: 'blob'} )
  1. 您需要在请求中设置 response-header { responseType: 'blob'}

  2. 您需要在创建 blob 文件时传入正确的 MIME-Type。 (fe application/octet-streamapplication/vnd.openxmlformats-officedocument.spreadsheetml.sheet )。

组件.ts

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

虽然使用{ 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 是一个通用的 stream 字节和 Blob object 可以使用blobarraybuffer ,使用Content-Type
  2. observe: 'response'还将包括您在解析的响应中在服务器上设置的响应标头。

我使用此方法将arraybuffer的文件名和 MIME 类型放入Content-DispositionContent-Type响应标头中,然后在客户端使用通用下载服务。

另外,我建议使用File object 而不仅仅是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 提出的关于使用自定义文件名的问题。

在请求中设置 response-header { responseType: 'blob'}

要下载 excel,请使用下面的 function。

响应 - 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();
  }

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

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

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

{ responseType : 'application/octet-stream'}

和 in.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);
}

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM