将JavaScript数据导出到CSV文件,无需服务器交互

如果我们在一个nodeJS服务器上,我们可以写一个头文件,设置一个MIMEtypes,然后发送它:

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

由于标题,浏览器将为指定的csv文件创build一个下载。

当在浏览器中生成有用的数据时,获取CSV文件的一个解决scheme是使用ajax,将其上传到服务器(也许可以select将其保存在那里),然后让服务器将这些头信息发送回来csv在浏览器中下载回来。

不过,我想要一个100%的浏览器解决scheme,不涉及与服务器的乒乓。

所以我想到了,我们可以打开一个新的窗口,并尝试设置与META标签等效的标题。

但是这在最近的Chrome中并不适用于我。

我得到一个新的窗口,它包含csvString,但不作为下载。

我想我希望得到一个底部的选项卡下载或在底部的选项卡下载一个空白的新窗口。

我想知道meta标签是否正确或者是否还需要其他标签。

有没有办法让这个工作,而不是把它推到服务器?

JsFiddle在浏览器中创build一个CSV(不工作 – 输出窗口,但没有下载)

 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); 

总是有HTML5的download属性:

此属性(如果存在)表示作者希望超链接用于下载资源,以便当用户单击链接时,系统会提示将其保存为本地文件。

如果该属性有一个值,则该值将在用户单击链接时打开的“保存”提示中用作预先填充的文件名。

 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(); 

小提琴

在Chrome和Firefox中testing,在最新版本(截至2013年7月)中工作正常
也适用于Opera,但不设置文件名(截至2013年7月)
似乎没有在IE9(大惊喜) (截至2013年7月)工作

浏览器支持下载属性的概述可以在这里find
对于不支持的浏览器,必须在服务器端设置适当的标题。


显然有IE10和IE11 ,不支持download属性的黑客攻击 (然而边缘不过)

 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(); } 

@adeneo的答案适用于Firefox和铬…对于IE下面可以使用。

 if (window.navigator.msSaveOrOpenBlob) { var blob = new Blob([decodeURIComponent(encodeURI(result.data))], { type: "text/csv;charset=utf-8;" }); navigator.msSaveBlob(blob, 'FileName.csv'); } 

看到adeneo的答案,但不要忘记encodeURIComponent

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

此外,我需要为行分隔符“\ r \ n”而不是“\ n”。

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

修改小提琴: http : //jsfiddle.net/7Q3c6/

一旦我把JS代码打包到一个小图书馆:

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

代码,文档和演示/游乐场都在Github上提供。

请享用 :)

拉请求是受欢迎的。

在1行中使用reactjs的组件react-csv

 <CSVLink data={yourData} filename="persons.csv" ></CSVLink> 

 const {CSVLink} = ReactCSV; const myData =[ ['firstname', 'lastname', 'email'] , ['Ahmed', 'Tomi' , 'ah@smthing.co.com'] , ['Raed', 'Labes' , 'rl@smthing.co.com'] , ['Yezzi','Min l3b', 'ymin@cocococo.com'] ]; const element = (<CSVLink data={myData} >Download Here</CSVLink>) ; ReactDOM.render( <div> <div>{element} </div> <span>If click does not work, "right click" then "Open in new Tab"</span> </div> , document.querySelector('section') ) 
 <script src="ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <script src="https://cdn.rawgit.com/abdennour/react-csv/d46773cc/cdn/react-csv-latest.min.js" type="text/javascript"></script> <section />