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