JavaScript: bestand maken en opslaan

Ik heb gegevens die ik naar een bestand wil schrijven en open een bestandsdialoogvenster waarin de gebruiker kan kiezen waar hij het bestand wil opslaan. Het zou geweldig zijn als het in alle browsers zou werken, maar het moet in Chrome werken. Ik wil dit allemaal aan de klantzijde doen.

Eigenlijk wil ik weten wat ik in deze functie moet zetten:

saveFile: function(data)
{
}

Waar de functie gegevens inneemt, laat de gebruiker een locatie selecteren om het bestand op te slaan en maakt op die locatie een bestand met die gegevens.

Het gebruik van HTML is ook prima, als dat helpt.


Antwoord 1, autoriteit 100%

Een zeer kleine verbetering van de code door Awesomeness01(geen ankertag nodig) met toevoeging zoals voorgesteld door trueimage(ondersteuning voor IE):

// 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); 
    }
}

Getest om correct te werken in Chrome, FireFox en IE10.

In Safari worden de gegevens in een nieuw tabblad geopend en zou men dit bestand handmatig moeten opslaan.


Antwoord 2, autoriteit 48%

Dit project op github ziet er veelbelovend uit:

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

FileSaver.js implementeert de W3C saveAs() FileSaver-interface in
browsers die dit niet standaard ondersteunen.

Bekijk hier ook de demo:

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


Antwoord 3, autoriteit 48%

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>

Antwoord 4, autoriteit 15%

Het is niet mogelijk om de locatie te kiezen om het bestand op te slaan voordat u het maakt. Maar het is mogelijk, in ieder geval in Chrome, om bestanden te genereren met alleen JavaScript. Hier is een oud voorbeeld van mij van het maken van een CSV-bestand. De gebruiker wordt gevraagd om het te downloaden. Dit werkt helaas niet goed in andere browsers, vooral niet in 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>

Antwoord 5, autoriteit 5%

Voor de nieuwste browser, zoals Chrome, kun je de File API gebruiken zoals in deze tutorial:

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

Antwoord 6, autoriteit 4%

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.json', 'text/json')">Create file</button>

Antwoord 7, autoriteit 3%

Dit geprobeerd in de console, en het werkt.

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));

Antwoord 8, autoriteit 3%

function SaveBlobAs(blob, file_name) {
    if (typeof navigator.msSaveBlob == "function")
        return navigator.msSaveBlob(blob, file_name);
    var saver = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
    var blobURL = saver.href = URL.createObjectURL(blob), 
        body = document.body;
    saver.download = file_name;
    body.appendChild(saver);
    saver.dispatchEvent(new MouseEvent("click"));
    body.removeChild(saver);
    URL.revokeObjectURL(blobURL);
}

Antwoord 9, Autoriteit 2%

U kunt dit niet puur in JavaScript doen. JavaScript Draait met browsers heeft nog niet genoeg toestemming (er zijn voorstellen geweest) vanwege veiligheidsredenen.

In plaats daarvan zou ik aanraden download :

Een kleine JavaScript + Flash-bibliotheek die de creatie en download van tekstbestanden zonder serverinteractie mogelijk maakt.

U kunt een eenvoudige demo hier waar u de inhoud levert en / annulering / foutbehandelingsfunctionaliteit.


Antwoord 10

Voor Chrome en Firefox heb ik een puur javascript-methode gebruikt.

(Mijn aanvraag kan geen gebruik maken van een pakket, zoals Blob.jsomdat het wordt geserveerd van een speciale motor: een DSP met een WWWEB-server die in en weinig ruimte voor alles is voldaan.)

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';
}

Opmerkingen, waarschuwingen en wezelwoorden:

  • Ik heb succes gehad met deze code in zowel Chrome- als Firefox-clients die draaien in Linux (Maipo) en Windows (7 en 10) omgevingen.
  • Als sourceTextechter groter is dan een MB, loopt Chrome soms (soms) vast in zijn eigen download zonder enige storingsindicatie; Firefox heeft dit gedrag tot nu toe niet vertoond. De oorzaak kan een blobbeperking in Chrome zijn. Eerlijk gezegd weet ik het gewoon niet; als iemand enig idee heeft hoe te corrigeren (of op zijn minst te detecteren), gelieve te posten. Als de downloadafwijking optreedt en de Chrome-browser wordt gesloten, genereert deze een diagnose zoals:
  • Deze code is niet compatibel met Edge of Internet Explorer; Ik heb Opera of Safari niet geprobeerd.

Antwoord 11

StreamSaveris een alternatief om zeer grote bestanden op te slaan zonder dat alle gegevens in de geheugen.
In feite emuleert het alles wat de server doseert bij het opslaan van een bestand, maar alle clientzijde met servicemedewerker.

Je kunt de schrijver ophalen en er handmatig Uint8Array’s naartoe schrijven of een binaire readableStream naar de beschrijfbare stream sturen

Er zijn een paar voorbeeldmet:

  • Meerdere bestanden opslaan als zip
  • een readableStream doorsturen van bijvoorbeeld Responseof blob.stream()naar StreamSaver
  • handmatig naar de beschrijfbare stream schrijven terwijl je iets typt
  • of een video/audio hercoderen

Hier is een voorbeeld in zijn eenvoudigste vorm:

const fileStream = streamSaver.createWriteStream('filename.txt')
new Response('StreamSaver is awesome').body
  .pipeTo(fileStream)
  .then(success, error)

Als je een blob wilt opslaan, converteer je die gewoon naar een readableStream

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

Antwoord 12

Javascript heeft een FileSystem API. Als je ermee om kunt gaan dat de functie alleen in Chrome werkt, is een goed startpunt: http://www.html5rocks.com/en/tutorials/file/filesystem/.

Other episodes