簡體   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