How to properly download excel file with Angular2

Abhishek Subradeep picture Abhishek Subradeep · Apr 7, 2017 · Viewed 21.2k times · Source

This is the code of my service which makes post request with response an xls file :

exportInternalOrder(body) {
        let user_token: string = this.sessionService.getToken();
        let headers = new Headers();
        headers.append('responseType', 'arraybuffer');
        headers.append('Authorization', 'Bearer ' + user_token);
        return this.http.post(this.config.exportInternalOrder, body,{
            headers: headers
        }).map(res => new Blob([res._body],{ type: 'application/vnd.ms-excel' }));
    }

Which is supposed to handle response of excel file. This is the code invoking it:

let objToSend = this.makeObjToSend(false);
this.reportingService.exportExcel(objToSend)
    .subscribe(
        data => {
            this.exportData(data);
        },
        error => {
            this.errorFilterMsg.push({ severity: 'error', detail: 'Report exporting has failed!' });
        }
);

And this is the saving of the file (for some reason window.open does nothing):

exportData(data){       
        let blob = data;
        let a = document.createElement("a");
        a.href = URL.createObjectURL(blob);
        a.download = 'fileName.xls';
        document.body.appendChild(a);
        a.click();        
    }

But the file still saves as corrupted one. While using postman and curl it comes ok. Any help would be appreciated.

Answer

Stefan Svrkota picture Stefan Svrkota · Apr 7, 2017

responseType shouldn't be set in headers, it's part of RequestOptionsArgs object which is passed as second argument in post function and RequestOptionsArgs contains headers, responseType and others, you can read more about it here. So, your code should look like this:

import { ResponseContentType } from '@angular/http';

exportInternalOrder(body) {
    let user_token: string = this.sessionService.getToken();
    let headers = new Headers();
    headers.append('Authorization', 'Bearer ' + user_token);
    return this.http.post(this.config.exportInternalOrder, body,{
        headers: headers,
        responseType: ResponseContentType.Blob
    }).map(res => new Blob([res._body],{ type: 'application/vnd.ms-excel' }));
}