Angular 5下载带有帖子请求的excel文件

问题描述 投票:7回答:3

我正面临一个问题,我用Angular 1下载了一个Excel文件,但是如果我在Angular 5中实现了相同的代码,则会显示您的文件已损坏的错误。我的回复是在ArrayBuffer中,我无法读取该文件。

以下是我的代码:

服务:

 DownloadData(model:requiredParams):Observable<any>{
  const headers = new Headers();
  const requestOptions = new RequestOptions({ headers: headers });
  requestOptions.headers.append('Content-Type', 'application/json');

   const body = JSON.stringify(model);
  return this.http.post(url, body, requestOptions)
  .map((res:any) => res)
 .catch((e: any) => Observable.throw(this.errorHandler(e)));
 }

零件:

exportToExcel() {
    this.loadingOverlayFlag = true;
   this.podashboardService.DownloadData(this.data).subscribe(result=>{
    console.log(result);
    this.downloadFile(result._body,'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'export.xlsx');
  })
  }

 downloadFile(blob: any, type: string, filename: string) {

 var binaryData = [];
   binaryData.push(blob);

     const url = window.URL.createObjectURL(new Blob(binaryData, {type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"})); // <-- work with blob directly

     // create hidden dom element (so it works in all browsers)
     const a = document.createElement('a');
     a.setAttribute('style', 'display:none;');
     document.body.appendChild(a);

     // create file, attach to hidden element and open hidden element
     a.href = url;
     a.download = filename;
     a.click();

   }

我可以下载该文件,但无法阅读其内容。错误是:

Microsoft Excel Excel无法打开文件'███████DASHBOARD(5).xlsx',因为文件格式或文件扩展名无效。验证文件是否已损坏,以及文件扩展名是否与文件格式匹配。好

angular angular-services
3个回答
7
投票

我整天都在努力争取这个。替换角度HttpClient并使用XMLHttpRequest,如下所示:

var oReq = new XMLHttpRequest();
  oReq.open("POST", url, true);
  oReq.setRequestHeader("content-type", "application/json");
  oReq.responseType = "arraybuffer";

  oReq.onload = function (oEvent) {
    var arrayBuffer = oReq.response;
    if (arrayBuffer) {
      var byteArray = new Uint8Array(arrayBuffer);
      console.log(byteArray, byteArray.length);
      this.downloadFile(byteArray, 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'export.xlsx');
    }
  };

  oReq.send(body);

然后在downloadFile函数中修改了Blob的创建:

const url = window.URL.createObjectURL(new Blob([binaryData]));

在您的情况下,服务将看起来像这样:

DownloadData(model:requiredParams):Observable<any>{
  return new Observable(obs => {
    var oReq = new XMLHttpRequest();
    oReq.open("POST", url, true);
    oReq.setRequestHeader("content-type", "application/json");
    oReq.responseType = "arraybuffer";

    oReq.onload = function (oEvent) {
      var arrayBuffer = oReq.response;
      var byteArray = new Uint8Array(arrayBuffer);
      obs.next(byteArray);
    };

    const body = JSON.stringify(model);
    oReq.send(body);
  });
}

那么组件:

exportToExcel() {
  this.loadingOverlayFlag = true;
  this.podashboardService.DownloadData(this.data).subscribe(result=>{
    // console.log(result);
    this.downloadFile(result,'application/vnd.openxmlformats-
    officedocument.spreadsheetml.sheet', 'export.xlsx');
  })
}

downloadFile(blob: any, type: string, filename: string) {

  var binaryData = [];
  binaryData.push(blob);

  const url = window.URL.createObjectURL(new Blob(binaryData, { type: filetype })); // <-- work with blob directly

   // create hidden dom element (so it works in all browsers)
   const a = document.createElement('a');
   a.setAttribute('style', 'display:none;');
   document.body.appendChild(a);

   // create file, attach to hidden element and open hidden element
   a.href = url;
   a.download = filename;
   a.click();
}

4
投票

我设法通过使用httpClient使其工作(httpOptions中的responseType: 'arraybuffer'做了伎俩)。

createReportBackend() {

    const httpOption: Object = {
      observe: 'response',
      headers: new HttpHeaders({
        'Content-Type': 'application/json'
      }),
      responseType: 'arraybuffer'
    };

    this.httpClient.post('http://localhost:8080/api/report', this.data, httpOption)
      .pipe(map((res: HttpResponse) => {
        return {
          filename: 'Drinks.xlsx',
          data: new Blob(
            [res['body']],
            { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}
          ),
        };
      }))
      .subscribe(res => {
        if (window.navigator.msSaveOrOpenBlob) {
          window.navigator.msSaveBlob(res.data, res.filename);
        } else {
          const link = window.URL.createObjectURL(res.data);
          const a = document.createElement('a');
          document.body.appendChild(a);
          a.setAttribute('style', 'display: none');
          a.href = link;
          a.download = res.filename;
          a.click();
          window.URL.revokeObjectURL(link);
          a.remove();
        }
      }, error => {
        throw error;
      }, () => {
        console.log('Completed file download.');
      });
  }

0
投票

下载使用filesaver找到的excel文件的最简单方法是:

//Declaration
headers: HttpHeaders;
options: any;

 //Constructor or u can have for specific method
 this.headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    this.options = {
        observe: 'response',
        headers: this.headers,
        responseType: 'arraybuffer'
    };

 //Service request:
  this.httpClient.post('http://localhost:8080/api/report', this.data, this.option)
  .pipe(
  catchError(err => this.handleError(err))
    ).subscribe(response => {
        Helper.exportExelFile(response, 'FileName');
    });

//component or in helper function in one class

import * as FileSaver from 'file-saver';
 function exportExelFile(data, filename) {
const blobValue = new Blob([data['body']], {
    type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
 FileSaver.saveAs(blobValue, filename + '.' + FileType.EXCEL);
}

export const Helper = {
  exportExelFile
   };
© www.soinside.com 2019 - 2024. All rights reserved.