371 Stimmen

HTML5/JavaScript verwenden, um eine Datei zu erzeugen und zu speichern

Ich habe in letzter Zeit mit WebGL herumgespielt und einen Collada-Reader zum Laufen gebracht. Das Problem ist, dass es ziemlich langsam ist (Collada ist ein sehr ausführliches Format), also werde ich anfangen, Dateien in ein einfacheres Format zu konvertieren (wahrscheinlich JSON). Ich habe bereits den Code, um die Datei in JavaScript zu parsen, also kann ich ihn auch als meinen Exporter verwenden! Das Problem ist das Speichern.

Jetzt weiß ich, dass ich die Datei analysieren, das Ergebnis an den Server senden und den Browser veranlassen kann, die Datei vom Server als Download zurückzufordern. Aber in Wirklichkeit hat der Server nichts mit diesem speziellen Prozess zu tun, warum sollte er also involviert werden? Ich habe den Inhalt der gewünschten Datei bereits im Speicher. Gibt es eine Möglichkeit, dem Benutzer einen Download mit reinem JavaScript zu präsentieren? (Ich bezweifle es, aber ich könnte genauso gut fragen...)

Und um das klarzustellen: Ich versuche nicht, ohne Wissen des Benutzers auf das Dateisystem zuzugreifen! Der Benutzer gibt eine Datei an (wahrscheinlich per Drag & Drop), das Skript wandelt die Datei im Speicher um, und der Benutzer wird aufgefordert, das Ergebnis herunterzuladen. All dies sollten "sichere" Aktivitäten sein, soweit der Browser betroffen ist.

[EDIT]: Ich habe es nicht im Voraus erwähnt, also sind die Poster, die mit "Flash" geantwortet haben, berechtigt, aber ein Teil dessen, was ich tue, ist ein Versuch, hervorzuheben, was mit reinem HTML5 gemacht werden kann... also ist Flash in meinem Fall ausgeschlossen. (Obwohl es eine vollkommen gültige Antwort für jeden ist, der eine "echte" Webanwendung macht.) Da dies der Fall ist, sieht es so aus, als hätte ich kein Glück, es sei denn, ich möchte den Server einbeziehen. Trotzdem vielen Dank!

2voto

tgraupmann Punkte 71

Dieser Thread war von unschätzbarem Wert, um herauszufinden, wie man eine Binärdatei generiert und zum Herunterladen der benannten Datei auffordert, und das alles im Client-Code ohne Server.

Der erste Schritt bestand für mich darin, den binären Blob aus den gespeicherten Daten zu erzeugen. Es gibt viele Beispiele dafür, wie man dies für einen einzelnen Binärtyp macht. In meinem Fall habe ich ein Binärformat mit mehreren Typen, die man als Array übergeben kann, um den Blob zu erstellen.

saveAnimation: function() {

    var device = this.Device;
    var maxRow = ChromaAnimation.getMaxRow(device);
    var maxColumn = ChromaAnimation.getMaxColumn(device);
    var frames = this.Frames;
    var frameCount = frames.length;

    var writeArrays = [];

    var writeArray = new Uint32Array(1);
    var version = 1;
    writeArray[0] = version;
    writeArrays.push(writeArray.buffer);
    //console.log('version:', version);

    var writeArray = new Uint8Array(1);
    var deviceType = this.DeviceType;
    writeArray[0] = deviceType;
    writeArrays.push(writeArray.buffer);
    //console.log('deviceType:', deviceType);

    var writeArray = new Uint8Array(1);
    writeArray[0] = device;
    writeArrays.push(writeArray.buffer);
    //console.log('device:', device);

    var writeArray = new Uint32Array(1);
    writeArray[0] = frameCount;
    writeArrays.push(writeArray.buffer);
    //console.log('frameCount:', frameCount);

    for (var index = 0; index < frameCount; ++index) {

      var frame = frames[index];

      var writeArray = new Float32Array(1);
      var duration = frame.Duration;
      if (duration < 0.033) {
        duration = 0.033;
      }
      writeArray[0] = duration;
      writeArrays.push(writeArray.buffer);

      //console.log('Frame', index, 'duration', duration);

      var writeArray = new Uint32Array(maxRow * maxColumn);
      for (var i = 0; i < maxRow; ++i) {
        for (var j = 0; j < maxColumn; ++j) {
          var color = frame.Colors[i][j];
          writeArray[i * maxColumn + j] = color;
        }
      }
      writeArrays.push(writeArray.buffer);
    }

    var blob = new Blob(writeArrays, {type: 'application/octet-stream'});

    return blob;
}

Der nächste Schritt besteht darin, den Browser dazu zu bringen, den Benutzer zum Herunterladen dieses Blob mit einem vordefinierten Namen aufzufordern.

Alles, was ich brauchte, war ein benannter Link, den ich in HTML5 einfügte und den ich zur Umbenennung des ursprünglichen Dateinamens wiederverwenden konnte. Ich habe ihn versteckt gehalten, da der Link nicht angezeigt werden muss.

<a id="lnkDownload" style="display: none" download="client.chroma" href="" target="_blank"></a>

Der letzte Schritt ist die Aufforderung an den Benutzer, die Datei herunterzuladen.

var data = animation.saveAnimation();
var uriContent = URL.createObjectURL(data);
var lnkDownload = document.getElementById('lnkDownload');
lnkDownload.download = 'theDefaultFileName.extension';
lnkDownload.href = uriContent;
lnkDownload.click();

2voto

Peeter Vois Punkte 66

Beim Testen der "ahref"-Methode habe ich festgestellt, dass die Webentwickler-Tools von Firefox und Chrome durcheinander kommen. Ich musste das Debugging neu starten, nachdem a.click() ausgegeben wurde. Dasselbe passierte mit dem FileSaver (er verwendet dieselbe ahref-Methode, um die Speicherung vorzunehmen). Um das Problem zu umgehen, habe ich ein neues temporäres Fenster erstellt, das Element a darin eingefügt und es dort angeklickt.

    function download_json(dt) {
        var csv = ' var data = ';
        csv += JSON.stringify(dt, null, 3);

        var uricontent = 'data:application/octet-stream,' + encodeURI(csv);

        var newwin = window.open( "", "_blank" );
        var elem = newwin.document.createElement('a');
        elem.download = "database.js";
        elem.href = uricontent;
        elem.click();
        setTimeout(function(){ newwin.close(); }, 3000);

    }

1voto

Ilyas karim Punkte 4100

Hier finden Sie eine Anleitung zum Exportieren von Dateien als ZIP:

Bevor wir anfangen, gibt es eine Bibliothek zum Speichern von Dateien, der Name der Bibliothek ist fileSaver.js, Sie können diese Bibliothek hier finden. Fangen wir an. Binden Sie nun die erforderlichen Bibliotheken ein:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.4/jszip.min.js"  type="text/javascript"></script>
<script type="text/javascript" src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.js" ></script>

Kopieren Sie nun diesen Code und dieser Code wird eine Zip-Datei mit einer Datei hello.txt mit dem Inhalt Hello World herunterladen. Wenn alles gut funktioniert, wird eine Datei heruntergeladen.

<script type="text/javascript">
    var zip = new JSZip();
    zip.file("Hello.txt", "Hello World\n");
    zip.generateAsync({type:"blob"})
    .then(function(content) {
        // see FileSaver.js
        saveAs(content, "file.zip");
    });
</script>

Dadurch wird eine Datei namens file.zip heruntergeladen. Sie können hier mehr lesen: http://www.wapgee.com/story/248/guide-to-create-zip-files-using-javascript-by-using-jszip-library

0voto

Itamar Smirra Punkte 86

Für einfache Dateien wie 'txt' oder 'js' können Sie das Paket fs-browsers .
Es hat schöne und einfache Download- und Exportmethoden für die Client-Seite, die keinen Server aufrufen.

import { exportFile } from 'fs-browsers';
const onExportClick = (textToExport) => {
  // Export to txt file
  exportFile(textToExport);
}

Wenn Sie den Dateinamen oder sogar den Dateityp ändern möchten, können Sie dies ganz einfach mit dieser Funktion tun:

import { exportFile } from 'fs-browsers';
const onExportClick = (textToExport) => {
  // Export to js file called 'file.js'
  exportFile(textToExport, { fileName: 'file.js' });
}

Für komplexere Dateien müssen Sie, wie Sie sagten, einen Server einbeziehen.
Das Paket kann dies auch mit Excel-Dateien ("xls") tun, wenn Sie dies benötigen.

import { exportFile, EXCEL_FILE } from 'fs-browsers';
const data = [{ "id": 5, "name": "John", "grade": 90, "age": 15 }, { "id": 7, "name": "Nick", "grade": 70, "age": 17 }];
const headings = ["Student ID", "Student Name", "Test Grade", "Student Age"];
exportFile(data, { type: EXCEL_FILE, headings: headings, fileName: 'grades.xls' });

Vielleicht wird es in Zukunft auch andere Arten von Dateien geben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X