Coder Perfect

How do I make a file in memory that the user may download without going via the server?

Problem

Is there a way to produce a text file on the client side and have the user download it without having to communicate with the server? I understand I can’t write directly to their PC for security reasons, but can I build anything and have them store it?

Asked by Joseph Silber

Solution #1

For HTML5-capable browsers, a simple solution…

Usage

download('test.txt', 'Hello world!');

Answered by Matěj Pokorný

Solution #2

Data URIs can be used. Browser support varies; check Wikipedia for further information. Example:

<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>

The octet-stream command causes a download prompt to appear. If not, it will most likely open in the browser.

You can use the following for CSV:

<a href="data:application/octet-stream,field1%2Cfield2%0Afoo%2Cbar%0Agoo%2Cgai%0A">CSV Octet</a>

Take a look at the jsFiddle example.

Answered by Matthew Flaschen

Solution #3

An example (without jQuery or any other library) for Internet Explorer 10+, Firefox, and Chrome:

function save(filename, data) {
    const blob = new Blob([data], {type: 'text/csv'});
    if(window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(blob, filename);
    }
    else{
        const elem = window.document.createElement('a');
        elem.href = window.URL.createObjectURL(blob);
        elem.download = filename;        
        document.body.appendChild(elem);
        elem.click();        
        document.body.removeChild(elem);
    }
}

After removing elem, you may want to execute URL.revokeObjectURL, depending on your situation. The documentation for URL.createObjectURL says:

Answered by Ludovic Feltz

Solution #4

All of the above examples work properly in Chrome and Internet Explorer, but not in Firefox. Consider adding an anchor to the body and then deleting it after the click.

var a = window.document.createElement('a');
a.href = window.URL.createObjectURL(new Blob(['Test,Text'], {type: 'text/csv'}));
a.download = 'test.csv';

// Append anchor to body.
document.body.appendChild(a);
a.click();

// Remove anchor from body
document.body.removeChild(a);

Answered by naren

Solution #5

I’m happily using FileSaver.js. Its compatibility is pretty good (IE10+ and everything else), and it’s very simple to use:

var blob = new Blob(["some text"], {
    type: "text/plain;charset=utf-8;",
});
saveAs(blob, "thing.txt");

Answered by Daniel Buckmaster

Post is based on https://stackoverflow.com/questions/3665115/how-to-create-a-file-in-memory-for-user-to-download-but-not-through-server