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.
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.
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:
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.
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>
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>
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);
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>
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));
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.
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:
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. 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/ .
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:
Response
oder blob.stream()
zu StreamSaverHier 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