我正面临一个问题,我用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',因为文件格式或文件扩展名无效。验证文件是否已损坏,以及文件扩展名是否与文件格式匹配。好
我整天都在努力争取这个。替换角度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();
}
我设法通过使用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.');
});
}
下载使用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
};