webentwicklung-frage-antwort-db.com.de

Angular 4.3: Array-Puffer mit neuem HttpClient abrufen

Ich möchte zum neuen HttpClient wechseln. Bis jetzt verwende ich das Herunterladen von Dateien wie folgt:

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

Wenn Sie den respondeType in 'arraybuffer' ändern, werden leere Dateien angezeigt. Irgendwelche Ideen, wie man es löst?

3
Luke

Also hat Martin mein Problem gelöst:

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

Das oben genannte funktioniert und ist eine akzeptable Lösung, scheint jedoch wie ein Code-Geruch zu sein, der Ankern-Tags zum DOM hinzufügt und einen Klick fälscht, wenn Sie es viel sauberer machen können. Wir hatten kürzlich ein ähnliches Problem beim Herunterladen von Dokumenten im Allgemeinen von einer Angular 5-Website, auf der FileSaver verwendet wurde ( https://www.npmjs.com/package/file-saver ).

Wenn Sie FileSaver mit npm install file-saver hinzufügen und die entsprechenden Importe durchführen, können Sie den folgenden Code zum Herunterladen einer Datei verwenden: 

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

Hierbei wird der native Befehl saveAs verwendet, falls vorhanden, und eine andere Logik implementiert, um die Funktionalität zu replizieren, falls dies nicht der Fall ist. 

Dies kann eine ähnliche Sache unter der Haube tun (ich weiß nicht wirklich, da ich die Änderung nicht vorgenommen hatte), aber es unterteilt es in einem einfach zu verwendenden Paket von Drittanbietern, von dem ich hoffe, dass es beibehalten werden würde (Daumen drücken). ohne dass ich die Funktionalität aktualisieren muss, um für neuere Versionen verschiedener Pakete/Browser zu sorgen. 

1
chunkydigits