wake-up-neo.com

JavaScript: Datei erstellen und speichern

Ich habe Daten, die ich in eine Datei schreiben möchte, und öffne ein Dateidialogfeld, in dem der Benutzer auswählen kann, wo die Datei gespeichert werden soll. Es wäre toll, wenn es in allen Browsern funktionieren würde, aber es muss in Chrome funktionieren. Ich möchte das alles clientseitig machen.

Grundsätzlich möchte ich wissen, was in diese Funktion zu setzen ist:

saveFile: function(data)
{
}

Wenn die Funktion Daten aufnimmt, muss der Benutzer einen Speicherort für die Datei auswählen und eine Datei mit diesen Daten an diesem Speicherort erstellen.

HTML ist auch in Ordnung, wenn das hilft.

235
user1756980

Eine sehr geringfügige Verbesserung des Codes durch Awesomeness01 (kein Anker-Tag erforderlich) mit einem Zusatz, wie von trueimage (Unterstützung für IE) vorgeschlagen:

// Function to download data to a file
function download(data, filename, type) {
    var file = new Blob([data], {type: type});
    if (window.navigator.msSaveOrOpenBlob) // IE10+
        window.navigator.msSaveOrOpenBlob(file, filename);
    else { // Others
        var a = document.createElement("a"),
                url = URL.createObjectURL(file);
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        setTimeout(function() {
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);  
        }, 0); 
    }
}

Es wurde getestet, ob es in Chrome, FireFox und IE10 einwandfrei funktioniert.

In Safari werden die Daten in einem neuen Tab geöffnet und diese Datei müsste manuell gespeichert werden.

203
Kanchu

Dieses Projekt auf Github sieht vielversprechend aus:

https://github.com/eligrey/FileSaver.js

FileSaver.js implementiert die W3C-Schnittstelle saveAs () FileSaver in Browsern, die dies nicht standardmäßig unterstützen.

Schauen Sie sich auch die Demo hier an:

http://eligrey.com/demos/FileSaver.js/

124
lostsource
function download(text, name, type) {
  var a = document.getElementById("a");
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}
<a href="" id="a">click here to download your file</a>
<button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>

Anschließend laden Sie die Datei herunter, indem Sie das download-Attribut in das anchor-Tag einfügen.

Der Grund, warum mir das besser gefällt als das Erstellen einer Daten-URL, ist, dass Sie keine lange URL erstellen müssen, sondern nur eine temporäre URL generieren können.

114
Awesomeness01

Die Auswahl des Speicherorts für die Datei vor dem Erstellen ist nicht möglich. Zumindest in Chrome ist es jedoch möglich, Dateien nur mit JavaScript zu generieren. Hier ist ein altes Beispiel für das Erstellen einer CSV-Datei. Der Benutzer wird aufgefordert, es herunterzuladen. Dies funktioniert leider nicht gut in anderen Browsern, insbesondere IE.

<!DOCTYPE html>
<html>
<head>
    <title>JS CSV</title>
</head>
<body>
    <button id="b">export to CSV</button>
    <script type="text/javascript">
        function exportToCsv() {
            var myCsv = "Col1,Col2,Col3\nval1,val2,val3";

            window.open('data:text/csv;charset=utf-8,' + escape(myCsv));
        }

        var button = document.getElementById('b');
        button.addEventListener('click', exportToCsv);
    </script>
</body>
</html>
37
Matt Greer
setTimeout("create('Hello world!', 'myfile.txt', 'text/plain')");
function create(text, name, type) {
  var dlbtn = document.getElementById("dlbtn");
  var file = new Blob([text], {type: type});
  dlbtn.href = URL.createObjectURL(file);
  dlbtn.download = name;
}
<a href="javascript:void(0)" id="dlbtn"><button>click here to download your file</button></a>
18
Samuel Tees

Für den neuesten Browser wie Chrome können Sie die Datei-API wie in diesem Tutorial verwenden :

window.requestFileSystem  = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.PERSISTENT, 5*1024*1024 /*5MB*/, saveFile, errorHandler);
13
pdjota

Versuchen Sie es mit dieser Option und laden Sie die Datei herunter. Alles, was Sie tun müssen, ist die On-Click-Attribute zu bearbeiten.

function download(text, name, type) {
  var a = document.getElementById("a");
  a.style.display = "block";
  var file = new Blob([text], {type: type});
  a.href = URL.createObjectURL(file);
  a.download = name;
}
#a { display: none; }
<a href="" id="a" download>click here to download your file</a>
<button onclick="download('file text', 'myfilename.txt', 'text/plain')">Create file</button>
12
boomcreeper11

Versuchte dies in der Konsole, und es funktioniert.

var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];
var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // the blob
window.open(URL.createObjectURL(oMyBlob));
8
Netsi1964

Sie können dies nicht rein in Javascript tun. In Browsern ausgeführtes Javascript verfügt aus Sicherheitsgründen noch nicht über ausreichende Berechtigungen (es wurden Vorschläge eingereicht).

Stattdessen würde ich empfehlen, Downloadify zu verwenden:

Eine winzige Javascript + Flash-Bibliothek, die das Erstellen und Herunterladen von Textdateien ohne Serverinteraktion ermöglicht.

Sie sehen eine einfache Demo hier , in der Sie den Inhalt bereitstellen und die Funktionen zum Speichern/Abbrechen/Behandeln von Fehlern testen können.

5
Aamir

Für Chrome und Firefox habe ich eine reine JavaScript-Methode verwendet.

(Meine Anwendung kann ein Paket wie Blob.js nicht verwenden, da es von einer speziellen Engine bereitgestellt wird: einem DSP mit einem überfüllten WWWeb-Server und wenig Platz für alles.)

function FileSave(sourceText, fileIdentity) {
    var workElement = document.createElement("a");
    if ('download' in workElement) {
        workElement.href = "data:" + 'text/plain' + "charset=utf-8," + escape(sourceText);
        workElement.setAttribute("download", fileIdentity);
        document.body.appendChild(workElement);
        var eventMouse = document.createEvent("MouseEvents");
        eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
        workElement.dispatchEvent(eventMouse);
        document.body.removeChild(workElement);
    } else throw 'File saving not supported for this browser';
}

Anmerkungen, Vorbehalte und Wieselworte:

  • Ich hatte Erfolg mit diesem Code sowohl in Chrome - als auch in Firefox-Clients, die unter Linux (Maipo) und Windows (7 und 10) ausgeführt werden.
  • Wenn jedoch sourceText größer als ein MB ist, bleibt Chrome manchmal (nur manchmal) in seinem eigenen Download stecken, ohne dass eine Fehlermeldung angezeigt wird. Firefox hat dieses Verhalten bisher nicht gezeigt. Die Ursache könnte eine Blob-Einschränkung in Chrome sein. Ehrlich gesagt, ich weiß es einfach nicht. Wenn jemand eine Idee hat, wie er etwas korrigieren (oder zumindest erkennen) kann, posten Sie diese bitte. Wenn die Download-Anomalie auftritt und der Browser Chrome geschlossen wird, wird eine Diagnose generiert, z. B. Chrome browser diagnostic
  • Dieser Code ist nicht mit Edge oder Internet Explorer kompatibel. Ich habe Opera oder Safari nicht ausprobiert.
2
We B Martians

Javascript hat eine FileSystem API. Wenn Sie damit umgehen können, dass die Funktion nur in Chrome funktioniert, ist dies ein guter Ausgangspunkt: http://www.html5rocks.com/en/tutorials/file/filesystem/ .

1
Alok

StreamSaver ist eine Alternative zum Speichern sehr großer Dateien, ohne alle Daten im Speicher behalten zu müssen.
Tatsächlich emuliert es alles, was der Server beim Speichern einer Datei benötigt, aber alle Clients mit dem Servicemitarbeiter.

Sie können entweder den Writer abrufen und manuell Uint8Array's darauf schreiben oder einen binären readableStream an den beschreibbaren Stream leiten

Es gibt einige Beispiel Beispiele:

  • So speichern Sie mehrere Dateien als Zip
  • leiten eines readableStreams von zB Response oder blob.stream() zu StreamSaver
  • manuelles Schreiben in den beschreibbaren Stream, während Sie etwas eingeben
  • oder ein Video/Audio umkodieren

Hier ist ein Beispiel in seiner einfachsten Form:

const fileStream = streamSaver.createWriteStream('filename.txt')

new Response('StreamSaver is awesome').body
  .pipeTo(fileStream)
  .then(success, error)

Wenn Sie einen Blob speichern möchten, konvertieren Sie diesen einfach in einen readableStream

new Response(blob).body.pipeTo(...) // response hack
blob.stream().pipeTo(...) // feature reference
0
Endless