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

Pau*_*aul 75 javascript export-to-csv

如果我们在nodeJS服务器上,我们可以编写一个头,设置一个mime类型,并发送它:

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

并且由于标题,浏览器将为命名的csv文件创建下载.

当在浏览器中生成有用的数据时,将其置于CSV文件中的一种解决方案是使用ajax,将其上传到服务器,(可选择将其保存在那里)并让服务器使用这些头将其发送回csv在浏览器下载回来.

但是,我希望100%的浏览器解决方案不涉及与服务器的乒乓.

所以在我看来,可以打开一个新窗口并尝试使用META标记等效设置标题.

但是这在最近的Chrome中对我不起作用.

我确实得到一个新窗口,它包含csvString,但不作为下载.

我想我希望在底部标签中下载或在底部标签中下载一个空白的新窗口.

我想知道元标记是否正确或是否还需要其他标记.

有没有办法让这项工作没有将其强加给服务器?

用于在浏览器中创建CSV的JsFiddle(不工作 - 输出窗口但无法下载)

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);
Run Code Online (Sandbox Code Playgroud)

ade*_*neo 157

始终存在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();
Run Code Online (Sandbox Code Playgroud)

小提琴

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

可以在此处找到
有关哪些浏览器支持下载属性的概述.对于不支持的浏览器,必须在服务器端设置适当的标头.


显然有IE10和IE11的黑客攻击,它不支持该download属性(但是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();
}
Run Code Online (Sandbox Code Playgroud)

  • a.href ='data:attachment/csv,'+ encodeURIComponent(csvString); (19认同)
  • 无法弄清楚如何设置文件名,但我确信它可能以某种方式.它通常是`attachment; filename = somefile.csv`但这对csv字符串似乎不起作用? (2认同)

Man*_*rma 30

@adeneo答案适用于Firefox和Chrome ...对于IE,可以使用以下内容.

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

  • 我可以确认这在IE11中有效,并且更新了我的库[html5csv](https://github.com/DrPaulBrewer/html5csv)以包含基于此技术的IE 11支持.我在代码评论中记下了你的帖子.非常感谢. (3认同)

小智 15

请参阅adeneo的回答,但不要忘记encodeURIComponent!

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

另外,我需要为行分隔符执行"\ r \n"而不仅仅是"\n".

var csvString = csvRows.join("\r\n");
Run Code Online (Sandbox Code Playgroud)

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


Ale*_*der 7

一旦我将JS代码打包到一个小型库中:

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

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

请享用 :)

欢迎提出拉动请求.