Download textarea contents as a file using only Javascript (no server-side)
Asked Answered
E

9

33

I am being asked to make a "download" button that downloads the contents of a textarea on the same page as a file, with the browser's "Save As..." dialog showing up. Copy/paste would do the job just fine, but it is a "requirement".

Right now, I am just posting the contents of the textarea to the server, which echos them back with Content-disposition: attachment slapped on. Is there a way to do this with just client-side Javascript?

Economically answered 4/3, 2009 at 7:12 Comment(0)
W
31

This may be what you are looking for: http://thiscouldbebetter.wordpress.com/2012/12/18/loading-editing-and-saving-a-text-file-in-html5-using-javascrip/

It uses the browser's download dialogue, but supports only FF and Chrome, and maybe more browsers now?


   function saveTextAsFile(textToWrite, fileNameToSaveAs)
    {
    	var textFileAsBlob = new Blob([textToWrite], {type:'text/plain'}); 
    	var downloadLink = document.createElement("a");
    	downloadLink.download = fileNameToSaveAs;
    	downloadLink.innerHTML = "Download File";
    	if (window.webkitURL != null)
    	{
    		// Chrome allows the link to be clicked
    		// without actually adding it to the DOM.
    		downloadLink.href = window.webkitURL.createObjectURL(textFileAsBlob);
    	}
    	else
    	{
    		// Firefox requires the link to be added to the DOM
    		// before it can be clicked.
    		downloadLink.href = window.URL.createObjectURL(textFileAsBlob);
    		downloadLink.onclick = destroyClickedElement;
    		downloadLink.style.display = "none";
    		document.body.appendChild(downloadLink);
    	}
    
    	downloadLink.click();
    }
<textarea id=t>Hey</textarea><br>
<button onclick=saveTextAsFile(t.value,'download.txt')>Download</button>
Wunderlich answered 12/10, 2013 at 9:17 Comment(3)
Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.Solidago
Today it is not neccessary anymore to check for webkitURL. caniuse.com/#search=URL Seems also that Edge still doesnot support this featureRecalcitrant
"Error: destroyClickedElement is not defined" . copying code from the internet is not good for health.Lapham
F
10

I found a simple solution here: https://codepen.io

My text area:<br />
<textarea rows='10' cols='80' id='myTextArea' ></textarea>

<br /><br />

Download button: <br />
<input value='download' type='button'
onclick='doDL(document.getElementById("myTextArea").value)' />


<script type='text/javascript'>
function doDL(s){
    function dataUrl(data) {return "data:x-application/text," + escape(data);}
    window.open(dataUrl(s));
}
</script>

Hope it will help.

Frenetic answered 5/7, 2013 at 10:31 Comment(3)
you are using an invalid content type; doesn't application/octet-stream have the same effect?Medius
@CyrLop -- awesome answer you posted here.... do you know if theres a way to hardcode a file name so the save dialoge opens with a filename the user can edit, but that is for instance, the current date -- yyyymmdd.txt ?Petronella
@tamak, see my answer below based on this one.Hix
R
9

You could try window.location = "data:application/octet-stream,"+text but that doesn't provide a mechanism through which you can suggest a name, and also IE has a very small cap on the maximum length of a data URI which could be a problem.

Roumell answered 4/3, 2009 at 7:28 Comment(1)
And it's not even possible with IE6.Shortage
L
7

There were some javascript libraries that did this kind of thing, via small embedded SWF file. For example this one.

Latona answered 7/6, 2010 at 23:0 Comment(2)
This is more of an answer to the question in my opinion. I mean, it helped me and thanks for that :)Casserole
Are there other libraries like this one?Hughmanick
R
5

You can use data: URIs and give it a file name, while still downloading the text. Try this:

document.getElementById("download").onclick = function(){
  var l = document.createElement("a");
  l.href = "data:text/plain;charset=UTF-8," + document.getElementById("dload-txt").value;
  l.setAttribute("download", document.getElementById("dload-fn").value);
  l.click();
}
textarea { width: 200px; height: 75px }
input { width: 200px }
<textarea placeholder="Enter text to download" id="dload-txt"></textarea><br/>
<input placeholder="Enter file name to download as" id="dload-fn"/><br/><br/>
<button id="download">Download</button>

This works in most browsers.

What it does is get the necessary data from the textarea and input, create a link that has an href to data:text/plain;UTF-8,<textarea data>, and set the download attribute with the name set by the <input> element. Then click the link, which will download the text.

The only not-all-browser-compatible things here are:

  1. data: URIs for storing the data as a link. data: URIs on CanIUse

  2. click() function to click the link. HTMLElement.click() on CanIUse

  3. download attribute to signify a download. download attribute on CanIUse

So basically:

  • Does not work in IE

  • Does not work in Opera Mini

  • Does not work in very early versions of Firefox, Chrome, Safari, Opera, and iOS Safari

Otherwise, this works in all major browsers, and doesn't need any Blob object.

Blob construction on CanIUse

Blob URLs on CanIUse

Red answered 10/12, 2020 at 20:8 Comment(1)
don't forget if you want to use special character like \n you have to encode the text l.href = "data:text/csv;charset=UTF-8," + encodeURIComponent(content);Samadhi
H
4

Absolutely possible using this cross browser JavaScript implementation of the HTML5 saveAs function: https://github.com/koffsyrup/FileSaver.js

If all you want to do is save text then the above script works in all browsers(including all versions of IE), no SWF required.

Hydrodynamic answered 28/5, 2015 at 13:32 Comment(0)
H
4

Based on @Cyrlop's answer and https://mcmap.net/q/452793/-how-to-rename-downloaded-files-from-window-open-in-javascript, this gives a way to specify a filename:

            function doDownload(str) {
              function dataUrl(data) {
                return "data:x-application/xml;charset=utf-8," + escape(data);
              }
              var downloadLink = document.createElement("a");
              downloadLink.href = dataUrl(str);
              downloadLink.download = "foo.xml";

              document.body.appendChild(downloadLink);
              downloadLink.click();
              document.body.removeChild(downloadLink);
            }

@Superphonic's solution is likely nicer if you don't mind including more bytes in your JavaScript.

Hix answered 15/5, 2019 at 15:58 Comment(1)
Know of any way to get it to prompt the user for a save as?Rostellum
A
1

It might be possible by creating a frame, writing contents there, then calling document.execCommand('saveas', ...) in IE and something with nsIFilePicker in Mozilla, but I believe that would require some extraordinary privileges (like being part of the browser itself).

Assyrian answered 4/3, 2009 at 7:38 Comment(2)
Possible indeed and requires no special privilege.. see here: jsfiddle.net/YhdSC/1 (IE only though :/)Neuberger
Yes, the privilege part was more about Firefox.Assyrian
E
-2

Short answer: it's not posible. You have to POST it to server, and response from server can be "Content-disposition: attachment".

Edda answered 4/3, 2009 at 7:16 Comment(2)
This answer is objectively wrong given I've personally tested and gotten one of these answers working.Rostellum
Not sure how this ended up in the VLQ queue - it is an answer (just a possibly wrong one). Wrong answers are not very low quality.Beadle

© 2022 - 2024 — McMap. All rights reserved.