Ich habe eine WebApi / MVC-App, für die ich einen angle2-Client entwickle (als Ersatz für MVC). Ich habe einige Probleme zu verstehen, wie Angular eine Datei speichert.
Die Anfrage ist in Ordnung (funktioniert gut mit MVC und wir können die empfangenen Daten protokollieren), aber ich kann nicht herausfinden, wie die heruntergeladenen Daten gespeichert werden sollen (ich folge größtenteils der gleichen Logik wie in diesem Beitrag ). Ich bin sicher, dass es dumm einfach ist, aber bis jetzt verstehe ich es einfach nicht.
Der Code der Komponentenfunktion ist unten. Ich habe verschiedene Alternativen ausprobiert, der Blob-Weg sollte der Weg sein, soweit ich verstanden habe, aber es gibt keine Funktion createObjectURL
in URL
. Ich kann nicht einmal die Definition von URL
in window finden, aber anscheinend existiert sie. Wenn ich das Modul benutzeFileSaver.js
erhalte ich den gleichen Fehler. Ich denke, dies hat sich kürzlich geändert oder ist noch nicht implementiert. Wie kann ich das Speichern der Datei in A2 auslösen?
downloadfile(type: string){
let thefile = {};
this.pservice.downloadfile(this.rundata.name, type)
.subscribe(data => thefile = new Blob([data], { type: "application/octet-stream" }), //console.log(data),
error => console.log("Error downloading the file."),
() => console.log('Completed file download.'));
let url = window.URL.createObjectURL(thefile);
window.open(url);
}
Der Vollständigkeit halber ist der Dienst, der die Daten abruft, unten aufgeführt. Das einzige, was er tut, ist, die Anforderung auszugeben und die Daten ohne Zuordnung weiterzuleiten, wenn dies erfolgreich ist:
downloadfile(runname: string, type: string){
return this.authHttp.get( this.files_api + this.title +"/"+ runname + "/?file="+ type)
.catch(this.logAndPassOn);
}
Antworten:
Das Problem ist, dass das Observable in einem anderen Kontext ausgeführt wird. Wenn Sie also versuchen, die URL var zu erstellen, haben Sie ein leeres Objekt und nicht den gewünschten Blob.
Eine der vielen Möglichkeiten, dies zu lösen, ist folgende:
Wenn die Anfrage fertig ist, ruft sie die Funktion "downloadFile" auf, die wie folgt definiert ist:
Der Blob wurde perfekt erstellt und daher die URL var. Wenn das neue Fenster nicht geöffnet wird, überprüfen Sie bitte, ob Sie 'rxjs / Rx' bereits importiert haben.
Ich hoffe das kann dir helfen.
quelle
this._reportService.getReport()
und was gibt es zurück?getReport()
Rückkehr athis.http.get(PriceConf.download.url)
Versuchen Sie dies !
1 - Installieren Sie Abhängigkeiten für das Popup "Datei speichern / öffnen"
2- Erstellen Sie mit dieser Funktion einen Dienst, um die Daten zu empfangen
3- Analysieren Sie in der Komponente den Blob mit 'file-saver'.
Das funktioniert bei mir!
quelle
Wenn Sie der Anforderung keine Header hinzufügen müssen , können Sie zum Herunterladen einer Datei in Angular2 Folgendes einfach tun :
in Ihrer Komponente.
quelle
authHttp
!Dies ist für Leute, die suchen, wie es mit HttpClient und File-Saver geht:
API-Serviceklasse:
Komponente:
quelle
Wie wäre es damit?
Ich könnte damit anfangen.
Kein zusätzliches Paket erforderlich.
quelle
Wie von Alejandro Corredor erwähnt, handelt es sich um einen einfachen Bereichsfehler. Das
subscribe
wird asynchron ausgeführt und dasopen
muss in diesen Kontext gestellt werden, damit die Daten beim Auslösen des Downloads vollständig geladen werden.Es gibt jedoch zwei Möglichkeiten. Wie in den Dokumenten empfohlen, kümmert sich der Dienst um das Abrufen und Zuordnen der Daten:
Dann abonnieren wir für die Komponente einfach die zugeordneten Daten und bearbeiten sie. Es gibt zwei Möglichkeiten. Die erste , wie im ursprünglichen Beitrag vorgeschlagen, muss jedoch geringfügig korrigiert werden, wie von Alejandro festgestellt:
Der zweite Weg wäre die Verwendung von FileReader. Die Logik ist dieselbe, aber wir können explizit darauf warten, dass FileReader die Daten lädt, die Verschachtelung vermeidet und das asynchrone Problem löst.
Hinweis: Ich versuche, eine Excel-Datei herunterzuladen, und obwohl der Download ausgelöst wird (dies beantwortet die Frage), ist die Datei beschädigt. Siehe die Antwort auf diesen Beitrag, um die beschädigte Datei zu vermeiden.
quelle
res
in den Blob laden und tatsächlich wollenres._body
. Ist_body
jedoch eine private Variable und nicht zugänglich. Ab heute.blob()
und.arrayBuffer()
auf einem http - Antwort - Objekt nicht in Angular 2. umgesetzt wordentext()
undjson()
sind die einzigen zwei Möglichkeiten , aber beide werden Ihren Körper verstümmeln. Haben Sie eine Lösung gefunden?<a href=""></a>
eine Datei herunterzuladen.Download * .zip-Lösung für Angular 2.4.x: Sie müssen ResponseContentType aus '@ angle / http' importieren und responseType in ResponseContentType.ArrayBuffer ändern (standardmäßig ResponseContentType.Json).
quelle
Für neuere Winkelversionen:
quelle
Das Herunterladen von Dateien über Ajax ist immer ein schmerzhafter Prozess. Meiner Ansicht nach ist es am besten, Server und Browser diese Arbeit der Aushandlung von Inhaltstypen ausführen zu lassen.
Ich denke, es ist das Beste zu haben
es zu tun. Dies erfordert nicht einmal das Öffnen neuer Fenster und ähnliches.
Der MVC-Controller wie in Ihrem Beispiel kann wie folgt aussehen:
quelle
Für diejenigen, die Redux Pattern verwenden
Ich habe im Dateisparer @Hector Cuevas hinzugefügt, der in seiner Antwort genannt wird. Mit Angular2 v. 2.3.1 musste ich den @ types / file-saver nicht hinzufügen.
Im folgenden Beispiel wird ein Journal als PDF heruntergeladen.
Die Journalaktionen
Die Journaleffekte
Der Journalservice
Der HTTP-Dienst
Der Journalreduzierer Obwohl dies nur die korrekten Zustände festlegt, die in unserer Anwendung verwendet werden, wollte ich ihn dennoch hinzufügen, um das vollständige Muster anzuzeigen.
Ich hoffe das ist hilfreich.
quelle
Ich teile die Lösung, die mir geholfen hat (jede Verbesserung wird sehr geschätzt)
In Ihrem Dienst 'pservice':
Bestandteil :
Auf der Komponente rufen Sie den Dienst auf, ohne eine Antwort zu abonnieren. Das Abonnement für eine vollständige Liste der openOffice-MIME-Typen finden Sie unter: http://www.openoffice.org/framework/documentation/mimetypes/mimetypes.html
quelle
Ich verwende Angular 4 mit dem 4.3 httpClient-Objekt. Ich habe eine Antwort geändert, die ich in Js 'technischem Blog gefunden habe. Sie erstellt ein Linkobjekt, verwendet es zum Herunterladen und zerstört es dann.
Klient:
Der Wert von this.downloadUrl wurde zuvor so festgelegt, dass er auf die API zeigt. Ich verwende dies zum Herunterladen von Anhängen, daher kenne ich die ID, den Inhaltstyp und den Dateinamen: Ich verwende eine MVC-API, um die Datei zurückzugeben:
Die Anhangsklasse sieht folgendermaßen aus:
Das Filerep-Repository gibt die Datei aus der Datenbank zurück.
Hoffe das hilft jemandem :)
quelle
Es ist besser, wenn Sie versuchen, die neue Methode in Ihnen aufzurufen
subscribe
Innerhalb der
downloadFile(data)
Funktion müssen wir machenblock, link, href and file name
quelle
Um PDF- Dateien herunterzuladen und anzuzeigen, sieht ein sehr ähnlicher Code wie folgt aus:
quelle
Hier ist etwas, was ich in meinem Fall getan habe -
Die Lösung wird mit Bezug auf den - hier
quelle
Aktualisieren Sie die Antwort von Hector mit File-Saver und HttpClient für Schritt 2:
quelle
Ich habe eine Lösung zum Herunterladen von Angular 2, ohne beschädigt zu werden, mit Spring MVC und Angular 2
1. Mein Rückgabetyp ist: - ResponseEntity vom Java-Ende. Hier sende ich Byte [] Array hat Rückgabetyp von der Steuerung.
2. Um den Dateisparer in Ihren Arbeitsbereich aufzunehmen - auf der Indexseite wie folgt:
3. Bei Komponente ts schreiben Sie diesen Code:
Dadurch erhalten Sie das XLS-Dateiformat. Wenn Sie andere Formate wünschen, ändern Sie den Medientyp und den Dateinamen mit der richtigen Erweiterung.
quelle
Ich war heute mit dem gleichen Fall konfrontiert. Ich musste eine PDF-Datei als Anhang herunterladen (die Datei sollte nicht im Browser gerendert, sondern stattdessen heruntergeladen werden). Um dies zu erreichen, musste ich die Datei in einem Winkel abrufen
Blob
und gleichzeitig eine hinzufügenContent-Disposition
Header in die Antwort einfügen.Dies war das einfachste, was ich bekommen konnte (Winkel 7):
Innerhalb des Dienstes:
Wenn ich dann die Datei in einer Komponente herunterladen muss, kann ich einfach:
AKTUALISIEREN:
Unnötige Header-Einstellungen aus dem Dienst entfernt
quelle
Ich fand die Antworten bisher ohne Einsicht und Warnungen. Sie könnten und sollten auf Inkompatibilitäten mit IE10 + achten (wenn Sie sich interessieren).
Dies ist das vollständige Beispiel mit dem Anwendungsteil und dem Serviceteil danach. Beachten Sie, dass wir die Beobachtung: "Antwort" setzen , um den Header für den Dateinamen abzufangen. Beachten Sie auch, dass der Content-Disposition-Header vom Server festgelegt und verfügbar gemacht werden muss, da er sonst vom aktuellen Angular HttpClient nicht weitergegeben wird. Ich habe unten einen Dotnet-Kerncode hinzugefügt .
Dotnet-Kern mit Content-Disposition & MediaType
quelle
quelle
Setzen die einfach
url
so ,href
wie unten.quelle
<a href="my_url" download="myfilename">Download file</a>
my_url sollte denselben Ursprung haben, andernfalls wird es an diesen Speicherort umgeleitet
quelle
Sie können eine Datei auch direkt aus Ihrer Vorlage herunterladen, in der Sie das Download-Attribut verwenden, und
[attr.href]
einen Eigenschaftswert aus der Komponente bereitstellen. Diese einfache Lösung sollte in den meisten Browsern funktionieren.Referenz: https://www.w3schools.com/tags/att_a_download.asp
quelle
Der folgende Code hat bei mir funktioniert
quelle
Wenn Sie die Parameter nur an eine URL senden, können Sie dies folgendermaßen tun:
in dem Dienst, der die Parameter empfängt
quelle
Dies Antwort legt nahe, dass Sie Dateien nicht direkt mit AJAX herunterladen können, hauptsächlich aus Sicherheitsgründen. Also werde ich beschreiben, was ich in dieser Situation mache,
01. Fügen Sie ein
href
Attribut in Ihr Ankertag in dercomponent.html
Datei ein,z. B.: -
02. Führen Sie alle folgenden Schritte aus
component.ts
, um die Sicherheitsstufe zu umgehen und das Dialogfeld Als Popup speichern aufzurufen,z. B.: -
quelle
Nun, ich habe einen Code geschrieben, der von vielen der oben genannten Antworten inspiriert ist und in den meisten Szenarien, in denen der Server eine Datei mit einem Header für die Inhaltsdisposition sendet, ohne Installationen von Drittanbietern, außer rxjs und angle, problemlos funktionieren sollte.
Zunächst, wie Sie den Code aus Ihrer Komponentendatei aufrufen
Wie Sie sehen können, handelt es sich im Grunde genommen um den durchschnittlichen Backend-Aufruf von Angular mit zwei Änderungen
Sobald die Datei vom Server abgerufen wurde, delegiere ich im Prinzip die gesamte Aufgabe des Speicherns der Datei an die Hilfsfunktion, die ich in einer separaten Datei aufbewahre, und importiere sie in die gewünschte Komponente
Es gibt keine kryptischen GUID-Dateinamen mehr! Wir können jeden Namen verwenden, den der Server bereitstellt, ohne ihn explizit im Client angeben zu müssen, oder den vom Server bereitgestellten Dateinamen überschreiben (wie in diesem Beispiel). Außerdem kann man den Algorithmus zum Extrahieren des Dateinamens aus der Inhaltsdisposition bei Bedarf leicht ändern, um sie an ihre Bedürfnisse anzupassen, und alles andere bleibt unberührt - im Falle eines Fehlers während einer solchen Extraktion wird nur "null" übergeben. als Dateiname.
Wie bereits in einer anderen Antwort erwähnt, muss der IE wie immer speziell behandelt werden. Aber da Chrom Edge in ein paar Monaten kommt, würde ich mir darüber keine Sorgen machen, wenn ich (hoffentlich) neue Apps erstelle. Es gibt auch die Frage, die URL zu widerrufen, aber da bin ich mir nicht so sicher. Wenn also jemand in den Kommentaren dabei helfen könnte, wäre das großartig.
quelle
Wenn eine Registerkarte geöffnet und geschlossen wird, ohne etwas herunterzuladen, habe ich versucht, mit einem Scheinanker-Link zu folgen, und es hat funktioniert.
quelle