Angular 5 download excel file with post request

15,133

Solution 1

I struggle with this one all day. Replace angular HttpClient and use XMLHttpRequest as follows:

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);

Then modified the creation of the Blob in your downloadFile function:

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

In your case the service will look something like this:

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);
  });
}

Then the component:

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

Solution 2

I managed to make it working by using httpClient ( responseType: 'arraybuffer' in the httpOptions did the trick).

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.');
      });
  }
Share:
15,133

Related videos on Youtube

user5497854
Author by

user5497854

I am experienced developer specialized upon complex web systems creation. I can be useful for you as a Technical .NET Web Developer. Projects, I took part in, were directed on solving specific business problems. All these projects are already released and bring benefit to their owners. I have been creating solutions from scratch, including architecture of application, services, APIs, database schema. I am oriented on solving problems and making my job in a best way. I like to plan and always spend enough time on application architecture before starting implementation.

Updated on June 04, 2022

Comments

  • user5497854
    user5497854 almost 2 years

    I am facing an issue where I have downloaded an Excel file with Angular 1 but if I am implementing the same code in Angular 5 it is showing the error that your file is corrupted. My response is in ArrayBuffer and I am unable to read the file.

    Below is my code:

    Service:

     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)));
     }
    

    Component:

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

    I am able to download the file, but unable to read its content. The error is:

    Microsoft Excel
    Excel cannot open the file '███████ DASHBOARD (5).xlsx' because the file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file. OK

  • Cooper Scott
    Cooper Scott over 3 years
    You sir, saved me from at least another hour fumbling around the internet for some help. Thank you.