Dateien mit Hilfe von JavaScript erzeugen und auf dem PC speichern
Vor kurzem haben wir uns hier im Blog mit dem Einlesen von Dateien vom PC mit Hilfe von JavaScript beschäftigt. In diesem Beitrag wollen wir uns nun mit dem Erzeugen und Speichern einer Datei auf dem PC beschäftigen. Auch hierfür benötigen wir die File API.
HTML5 Downloadlink
Mit der Einführung von HTML5 wurde für das a
-Element das download
-Attribut eingeführt. Ist dieses Attribut vorhanden, so navigiert der Browser nicht zu der im href
-Attribut angegebenen Seite, sondern startet den Download der verlinkten Seite bzw. des verlinkten Dokuments.
Im folgenden Beispiel wird die Datei /Handbuch/V_1-01.pdf
nicht im Browser geöffnet, sondern als Datei Handbuch.pdf
heruntergeladen:
<a href="/Handbuch/V_1-01.pdf" download="Handbuch.pdf">Handbuch herunterladen ...</a>
Wichtig: Im obigen Beispiel erhält man, wenn auf den Link geklickt wird i. d. R. ein Downloadfenster angezeigt oder die Datei wird direkt im Downloadverzeichnis des Browsers abgelegt. Dieses Verhalten lässt sich jedoch nicht steuern und ist abhängig vom verwendeten Browser und dessen Einstellungen.
Daten mit JavaScript vorbereiten
Nachdem wir es nun geschafft haben, einen Link zu definieren, dessen Ziel heruntergeladen wird anstatt geöffnet zu werden, müssen wir nun unsere Daten in ein bestimmtes Format bringen, so dass wir diese als Ziel in einem HTML-Link verwenden können.
Für dieses Vorhaben müssen wir ein Blob
-Objekt erzeugen. Das Blob
-Objekt ist Teil der File API, welches wir bereits im Blogbeitrag zum Thema Dateien vom PC mit Hilfe von JavaScript einlesen angesprochen haben. Um ein Blob
-Objekt zu erzeugen, müssen wir dessen Konstruktor aufrufen. Der Konstruktor benötigt als 1. Parameter ein Array mit Daten, die dem Blob
-Objekt angefügt werden sollen. Das Array muss dabei Elemente vom Typ ArrayBuffer
, ArrayBufferView
, String
oder Blob
enthalten. Der 2. Parameter ist optional und ein Objekt, mit welchem unterschiedliche Einstellungen festgelegt werden können. Eine wichtige Eigenschaft dieses Objekts ist type
, welches den MIME-Typ des Blob
-Objekts festlegt.
var oBlob = new Blob([ "abc", "def" ], { type: "text/plain" });
Übrigens: In der Praxis ist es zu empfehlen, den 2. Parameter und die Eigenschaft type
anzugeben.
Nachdem wir die Daten in die richtige Form gebracht haben, müssen wir nun noch eine URL erzeugen, die auf das Blob
-Objekt verweist bzw. dieses repräsentiert. Hierfür gibt es die Funktion createObjectURL()
des URL
-Objekts (dieses ist wiederum Teil des window
-Objekts). Mit Hilfe der Funktion createObjectURL()
können Sie also aus einem Blob
-Objekt eine Objekt-URL erzeugen:
var oUrl = window.URL.createObjectURL(oBlob);
Die damit erzeugte Objekt-URL kann nun in jedem beliebigen Kontext von einem Hyperlink verwendet werden (wie z. B. im href
-Attribut eines a
-Elements).
Wichtig: Die erzeugte Objekt-URL benötigt Speicher in Ihrem Browser. Es ist daher dringend zu empfehlen, die URL mit Hilfe der Funktion revokeObjectURL()
wieder frei zu geben, sobald diese nicht mehr benötigt wird. Der Funktion muss dabei als Parameter die von der Funktion createObjectURL()
zurückgegebene Objekt-URL übergeben werden. Der Speicher wird beim Verlassen der Seite natürlich automatisch freigegeben.
Lösung für den Internet Explorer
Der Internet Explorer von Microsoft unterstützt das HTML-Attribut download
nicht. Der Browser Microsoft Edge, welcher den Internet Explorer ablöst, unterstützt das download
-Attribut. Für den Internet Explorer 10 und neuer gibt es jedoch eine einfache Methode, um ein Blob-Objekt zu sichern: msSaveBlob()
. Die Funktion msSaveBlob()
ist Bestandteil des navigator
-Objekts, welches wiederum Bestandteil des window
-Objekts ist. Der 1. Parameter der Funktion spezifiziert das Blob
-Objekt und der 2. Parameter gibt den Dateinamen für den Download an:
window.navigator.msSaveBlob(oBlob, "Datei.txt");
Wichtig: Die Funktion msSaveBlob()
existiert nur im Internet Explorer mit der Version 10 oder höher.
Beispiel
Im folgenden Beispiel sehen Sie einen Button. Sobald Sie auf diesen klicken, wird eine Textdatei mit 10 Zufallszahlen mit jeweils einem Wert zwischen 0 und 100 generiert. Diese Zeichenkette wird dann dem Blob
-Konstruktor übergeben. Ist die Funktion msSaveBlob()
vorhanden, so wird diese verwendet, um das Blob
-Objekt als Datei zu sichern, andernfalls wird eine Objekt-URL erzeugt, die dann dem HTML-Element a
zugewiesen wird. Über die Funktion click()
wird dann der Download des Blob
-Objekts ausgelöst.
HTML-Code:
<form> <input type="button" value="Download starten" onclick="OnDownloadFile()" /> </form> <a id="downloadLink" href="" download="Zahlen.txt" style="display: none;"></a>
JavaScript-Code:
var oLastUrl = null; function OnDownloadFile() { var sText, oBlob, elLink; // Letzte Objekt-URL löschen (falls vorhanden) if (oLastUrl == null) { window.URL.revokeObjectURL(oLastUrl); oLastUrl = null; } // Textdatei mit Zufallszahlen erzeugen sText = ""; for (var i = 0; i < 10; i++) sText += Math.round(Math.random() * 100) + "\r\n"; // Blob-Objekt erzeugen oBlob = new Blob([ sText ], { type: "text/plain" }); // Prüfen, ob die Funktion zum direkten Sichern eines Blob-Objekts existiert (nur IE) if (window.navigator.msSaveBlob) { // Blob-Objekt abspeichern window.navigator.msSaveBlob(oBlob, "Zahlen.txt"); } else { // Download-Element laden elLink = document.getElementById("downloadLink"); // URL erzeugen und merken oLastUrl = window.URL.createObjectURL(oBlob); // URL dem HTML-Element zuweisen elLink.href = oLastUrl; // Klick auslösen elLink.click(); } }
Übrigens: Das a
-Element in diesem Beispiel ist ausgeblendet und wird nur für den Download des Blob
-Objekts benötigt. Es gibt im Internet einige Tutorials, bei welchen das a
-Element dynamisch erzeugt wird. Dieses muss aber dem Dokument zugewiesen werden und darf auch nicht sofort wieder entfernt werden, andernfalls funktioniert der Download in einigen Browsern (u. a. dem Mozilla Firefox) nicht. Daher ist es meistens besser, ein nicht sichtbares a
-Element auf der Seite zu platzieren und dieses zu verwenden.
Wichtig: Die Browser iOS Safari und Opera Mini ( Stand Februar 2018 ) unterstützen, wie auch der Internet Explorer, das download
-Attribut nicht. Jedoch gibt es für diese beiden Browser aktuell auch keine andere Lösung, um ein Blob
-Objekt auf dem Gerät zu speichern.