Je voudrais changer pour le nouveau HttpClient. Jusqu'à présent, je gère les téléchargements de fichiers suivants:
getXlsx (): Observable<any> {
return this.http.get('api/xlsx', {
responseType: ResponseContentType.ArrayBuffer, // set as ArrayBuffer instead of Json
})
.map(res => downloadFile(res, 'application/xlsx', 'export.xlsx'))
.catch(err => handleError(err));
}
export function downloadFile(data: any, type: string, filename: string): string {
const blob = new Blob([data._body], { type });
const url = window.URL.createObjectURL(blob);
// 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();
return url;
}
Changer le respondeType en 'arraybuffer' aura pour résultat des fichiers vides. Des idées comment le résoudre?
Alors Martin a résolu mon problème:
getXlsx (): Observable<any> {
return this.http.get('api/xlsx', {
responseType: 'blob' // <-- changed to blob
})
.map(res => downloadFile(res, 'application/xlsx', 'export.xlsx'))
.catch(err => handleError(err));
}
export function downloadFile(blob: any, type: string, filename: string): string {
const url = window.URL.createObjectURL(blob); // <-- 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();
return url;
}
Ce qui précède fonctionne et constitue une solution acceptable. Cependant, cela ressemble à une odeur de code ajoutant simplement des balises d'ancrage au DOM et simulant un clic lorsque vous pouvez le faire d'une manière beaucoup plus propre. Nous avons récemment eu un problème similaire concernant le téléchargement de documents en général à partir d’un site Web Angular 5 dans lequel nous avons utilisé FileSaver ( https://www.npmjs.com/package/file-saver ).
En ajoutant FileSaver en utilisant npm install file-saver
et en effectuant les importations pertinentes, vous pouvez utiliser le code suivant pour télécharger un fichier:
getDocument(document: Document) {
let headers = new HttpHeaders(); // additional headers in here
return this._http.get(url, {
headers: headers,
responseType: "blob" // this line being the important part from the previous answer (thanks for that BTW Martin)
}).map(
res => {
var x = res;
if (res) {
let filename = documentName;
saveAs(x, filename);
}
return true;
},
err => {
return true;
}
);
}
Ceci utilise la commande native saveAs
si elle existe et implémente une autre logique pour répliquer la fonctionnalité si ce n'est pas le cas.
Cela peut faire la même chose sous le capot (je ne sais pas vraiment car je n’ai pas eu le changement à regarder), mais cela le compartimentalise dans un paquet tiers facile à utiliser que j’espère pouvoir conserver (doigts croisés) sans avoir à mettre à jour les fonctionnalités pour prendre en charge les versions les plus récentes de différents packages/navigateurs.