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


77

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

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

并且由于存在标题,浏览器将为命名的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);


@Vengarioth数据URL肯定足够晦涩难懂。这当然不是很明显,我还没有看到可以做到这一点的库,2011年的另一个回答是说它无法完成。
保罗

@Italo回答了类似的数据URL技巧,将其发送给stackoverflow.com/questions/4639372/export-to-csv-in-jquery
Paul,

Answers:


161

总有HTML5download属性:

此属性(如果存在)表明作者打算将超链接用于下载资源,以便当用户单击链接时,将提示他们将其另存为本地文件。

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

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中进行了测试,在最新版本中有效(截至2013年7月)
同样适用于Opera,但未设置文件名(截至2013年7月)截至2013年7月,
似乎在IE9(大惊喜)中不起作用。

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


显然,有针对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();
}

2
无法确定如何设置文件名,但是我敢肯定它是有可能的。通常,attachment;filename=somefile.csv但这似乎不适用于csv字符串?
adeneo

19
a.href ='data:attachment / csv,'+ encodeURIComponent(csvString);
Paul

1
我怀疑它们可能会转换回实际文件中……但是不确定
Paul

1
该文件名在Chrome中不适用于我。当我将a.href更改为此时,它起作用了:a.href = window.URL.createObjectURL(new Blob([csvString],{type:“ attachment / csv”})));
Facio Ratio 2014年

1
@FacioRatio Google在Chrome中进行了更改。破坏了设置文件名的能力。请参阅:code.google.com/p/chromium/issues/detail?id=373182
保罗

31

@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');
}


3
我可以在IE11中确认这项工作,并且已经更新了我的库html5csv以包括基于此技术的IE 11支持。我在代码注释中记下了您的帖子。非常感谢。
Paul

15

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

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

另外,我需要对行定界符执行的不仅仅是“ \ n”。

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

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



2

请参阅adeneo的答案,但是要在所有国家/地区都可以在Excel中使用此功能,应在文件的第一行添加“ SEP =”。这将在Excel中设置标准分隔符,并且不会显示在实际文档中

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

我怀疑R或Pandas(Python)是否会像在csv文件中那样。
保罗

1
@Paul可能是对的,但就我而言,我需要制作一个csv文件以在excel中打开,并且我希望它以可表象的方式打开,而不管其位置如何。如果您有一个更好的解决方案,我很想听听!
Thyselius '18 -10-19

1

我们可以使用javascript轻松创建和导出/下载带有任何分隔符的excel文件(在此答案中,我使用的是逗号分隔符)。我没有使用任何外部软件包来创建excel文件。

    var Head = [[
        'Heading 1',
        'Heading 2', 
        'Heading 3', 
        'Heading 4'
    ]];

    var row = [
       {key1:1,key2:2, key3:3, key4:4},
       {key1:2,key2:5, key3:6, key4:7},
       {key1:3,key2:2, key3:3, key4:4},
       {key1:4,key2:2, key3:3, key4:4},
       {key1:5,key2:2, key3:3, key4:4}
    ];

for (var item = 0; item < row.length; ++item) {
       Head.push([
          row[item].key1,
          row[item].key2,
          row[item].key3,
          row[item].key4
       ]);
}

var csvRows = [];
for (var cell = 0; cell < Head.length; ++cell) {
       csvRows.push(Head[cell].join(','));
}
            
var csvString = csvRows.join("\n");
let csvFile = new Blob([csvString], { type: "text/csv" });
let downloadLink = document.createElement("a");
downloadLink.download = 'MYCSVFILE.csv';
downloadLink.href = window.URL.createObjectURL(csvFile);
downloadLink.style.display = "none";
document.body.appendChild(downloadLink);
downloadLink.click();

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.