Is possible to save JavaScript variable as file? [duplicate]
Asked Answered
K

3

34

Is there a way to convert a string from a JavaScrip variable, into a downloadable file that users can download when clicking a button ?

Thanks for any advice.

<div id="txt">Lorem Ipsum</div>
<br />
<button id="test">Download text as file !</button>
Kierstenkieselguhr answered 22/7, 2014 at 21:19 Comment(3)
you need some kind of server to write to file system. Node.js, PHP, Python, etc. JavaScript alone can't do it.Direction
#3665615Exequies
First thank you for this question, I was searching for it, but with a different title. Please can you make title more generic, something like "download text as a file with Javascript", so it will be easier to find imho.Stallings
R
83

Yes it is, you could do something like this in HTML5, using the download attribute

function download_txt() {
  var textToSave = document.getElementById('txt').innerHTML;
  var hiddenElement = document.createElement('a');

  hiddenElement.href = 'data:attachment/text,' + encodeURI(textToSave);
  hiddenElement.target = '_blank';
  hiddenElement.download = 'myFile.txt';
  hiddenElement.click();
}

document.getElementById('test').addEventListener('click', download_txt);

FIDDLE

Rancid answered 22/7, 2014 at 21:22 Comment(9)
Thank you very much, this is a great solution for me.Kierstenkieselguhr
@adeneo: Is it possible to store array of objects as text file, like var arrayToSave = [{fn:"john"},{fn:"doe"}];instead of var textToSave = 'this is a test';Socher
@MohamedHussain - It is if you use JSON.stringify to stringify it first.Rancid
This works fine on Chrome, but: Does not work at all for Firefox on OSX (43.0.3, early 2016). Works halfway on Safari; file downloads, but with default name and it opens a blank tab.Translucent
Fiddle doesn't seem to be working at all on Firefox 45 (Ubuntu) - any way around this?Vernacularism
Only works in Chrome on Windows 7. Not in firefox or IE.Surfboard
Not Work IN IE>8Sewage
Genius. This works fine on Firefox 78 for Mac OSX.Fitted
On firefox you must attach the <a> to the document first. you can fix this by using document.body.appendChild(hiddenElement) before the hiddenElement.click()Ductile
E
6

You can use a data: URI like in adeneo's answer, but another way is to use an HTML5 Blob and createObjectURL (similarly using the download attribute to create a download link).

The benefit of using createObjectURL is that there are severe size limits to data URIs in most browsers.

Example code taken from linked article:

var typedArray = GetTheTypedArraySomehow();
var blob = new Blob([typedArray], {type: 'application/octet-binary'});
    // pass a useful mime type here
var url = URL.createObjectURL(blob);
// url will be something like: blob:d3958f5c-0777-0845-9dcf-2cb28783acaf
// now you can use the url in any context that regular URLs can be used
// in, for example img.src, etc.
Elishaelision answered 22/7, 2014 at 21:27 Comment(2)
In modern browsers the length of a data URI is unlimited, some older browsers would limit it to around 65000 characters, so I wouldn't say "severe size limits" !Rancid
I could really use the rest of the example (to actually download the thing as a .json)Cray
C
1

To store a javascript variable, I suggest you to use libraries of data storage just like this one. where you can set a variable, get it , remove it ...

$.setData("key","value");
$.getData("key");
$.removeData("key");

but to store it on a file and make downloadable you have to pass by the server unless you use a javascript trick to download a file which doesn't exist, you just declare these functions

 var Download = 
    {
        click : function(node) {
            var ev = document.createEvent("MouseEvents");
            ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
            return node.dispatchEvent(ev);
        },
        encode : function(data) {
                return 'data:application/octet-stream;base64,' + btoa( data );
        },
        link : function(data, name){
            var a = document.createElement('a');
            a.download = name || self.location.pathname.slice(self.location.pathname.lastIndexOf('/')+1);
            a.href = data || self.location.href;
            return a;
        }
    };
    Download.save = function(data, name)
    {
        this.click(
            this.link(
                this.encode( data ),
                name
            )
        );
    };

and when you want to download a file, you do this

Download.save("data to be on a file","FileName.txt");

Finally, you need to combine the datastorage and the filedownload solution to get the result you're asking for

Choragus answered 22/7, 2014 at 21:34 Comment(1)
it is terrible, why don't use a single function? What is the point to create click, link and encode??? It is an example of bad programming.Avie

© 2022 - 2024 — McMap. All rights reserved.