Export javascript data to CSV file without server interaction

If we were on the node of the JS server, we could write the header, set the mime type and send it:

res.header("Content-Disposition", "attachment;filename="+name+".csv"); res.type("text/csv"); res.send(200, csvString); 

and because of the headers, the browser will create a download for the named csv file.

When useful data is generated in the browser, one of the solutions for receiving it in a CSV file is to use ajax, upload it to the server (perhaps, if necessary, save it there) and force the server to send it with these headers to load csv in the browser.

However, I would like the 100% browser solution to not include ping pong with the server.

So it occurred to me that you could open a new window and try to set a title with the equivalent of the META tag.

But this does not work for me in recent Chrome.

I get a new window and it contains csvString, but it does not fulfill the load function.

I think I expected to get either the download on the bottom tab, or an empty new window with the download on the bottom tab.

I am wondering if the meta tags are correct or if other tags are needed.

Is there any way to do this work without clicking on the server?

JsFiddle for creating CSV in the browser (does not work - displays a window, but without loading)

 var A = [['n','sqrt(n)']]; // initialize array of rows with header row as 1st item for(var j=1;j<10;++j){ A.push([j, Math.sqrt(j)]) } var csvRows = []; for(var i=0,l=A.length; i<l; ++i){ csvRows.push(A[i].join(',')); // unquoted CSV row } var csvString = csvRows.join("\n"); console.log(csvString); var csvWin = window.open("","",""); csvWin.document.write('<meta name="content-type" content="text/csv">'); csvWin.document.write('<meta name="content-disposition" content="attachment; filename=data.csv"> '); csvWin.document.write(csvString); 
+70
javascript export-to-csv
Jul 24 '13 at 14:02
source share
4 answers

There is always an HTML5 download attribute:

This attribute, if present, indicates that the author intends to use the hyperlink that will be used to download the resource, so that when the user clicks on the link, they will be asked to save it as a local file.

If the attribute has a value, the value will be used as the pre-populated file name in the Save prompt, which opens when the user clicks on the link.

 var A = [['n','sqrt(n)']]; for(var j=1; j<10; ++j){ A.push([j, Math.sqrt(j)]); } var csvRows = []; for(var i=0, l=A.length; i<l; ++i){ csvRows.push(A[i].join(',')); } var csvString = csvRows.join("%0A"); var a = document.createElement('a'); a.href = 'data:attachment/csv,' + encodeURIComponent(csvString); a.target = '_blank'; a.download = 'myFile.csv'; document.body.appendChild(a); a.click(); 

Fiddle

Tested in Chrome and Firefox, works fine in the newest versions (as of July 2013).
Also works in Opera, but does not set the file name (as of July 2013).
It doesn't seem to work in IE9 (big surprise) (as of July 2013).

An overview of which browsers support the download attribute can be found here.
For non-supporting browsers, you must set the appropriate headers on the server.




There seems to be a hack for IE10 and IE11 , which does not support the download attribute (however, Edge).

 var A = [['n','sqrt(n)']]; for(var j=1; j<10; ++j){ A.push([j, Math.sqrt(j)]); } var csvRows = []; for(var i=0, l=A.length; i<l; ++i){ csvRows.push(A[i].join(',')); } var csvString = csvRows.join("%0A"); if (window.navigator.msSaveOrOpenBlob) { var blob = new Blob([csvString]); window.navigator.msSaveOrOpenBlob(blob, 'myFile.csv'); } else { var a = document.createElement('a'); a.href = 'data:attachment/csv,' + encodeURIComponent(csvString); a.target = '_blank'; a.download = 'myFile.csv'; document.body.appendChild(a); a.click(); } 
+150
Jul 24 '13 at 14:12
source share

Answer @adeneo works for Firefox and chrome ... For IE you can use below.

 if (window.navigator.msSaveOrOpenBlob) { var blob = new Blob([decodeURIComponent(encodeURI(result.data))], { type: "text/csv;charset=utf-8;" }); navigator.msSaveBlob(blob, 'FileName.csv'); } 
+22
Dec 30 '15 at 2:51
source share

See adeneo answer, but don't forget encodeURIComponent !

 a.href = 'data:application/csv;charset=utf-8,' + encodeURIComponent(csvString); 

Also, I needed to make "\ r \ n" not just "\ n" for the line separator.

 var csvString = csvRows.join("\r\n"); 

Revised fiddle: http://jsfiddle.net/7Q3c6/

+15
Jul 14 '14 at 3:28
source share

Once I packed the JS code by doing this in a tiny library:

https://github.com/AlexLibs/client-side-csv-generator

Code, documentation, and a demo / playground are provided on Github.

Enjoy :)

Pull requests are welcome.

+7
Jan 04 2018-01-15T00:
source share



All Articles