JavaScript: Create and save file

JavaScript: Create and save file

I have data that I want to write to a file, and open a file dialog for the user to choose where to save the file. It would be great if it worked in all browsers, but it has to work in Chrome. I want to do this all client-side.
Basically I want to know what to put in this function:
saveFile: function(data)
{
}

Where the function takes in data, has the user select a location to save the file, and creates a file in that location with that data.
Using HTML is fine too, if that helps.

Solutions/Answers:

Solution 1:

A very minor improvement of the code by Awesomeness01 (no need for anchor tag) with addition as suggested by trueimage (support for 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); 
    }
}

Tested to be working properly in Chrome, FireFox and IE10.

Related:  Mobile Safari: Javascript focus() method on inputfield only works with click?

In Safari, the data gets opened in a new tab and one would have to manually save this file.

Solution 2:

This project on github looks promising:

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

FileSaver.js implements the W3C saveAs() FileSaver interface in
browsers that do not natively support it.

Also have a look at the demo here:

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

Solution 3:

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>

And you would then download the file by putting the download attribute on the anchor tag.

The reason I like this better than creating a data url is that you don’t have to make a big long url, you can just generate a temporary url.

Solution 4:

Choosing the location to save the file before creating it is not possible. But it is possible, at least in Chrome, to generate files using just JavaScript. Here is an old example of mine of creating a CSV file. The user will be prompted to download it. This, unfortunately, does not work well in other browsers, especially 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>

Solution 5:

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>

Solution 6:

For latest browser, like Chrome, you can use the File API as in this tutorial:

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