77

If we were on a nodeJS server, we could write a header, set a 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 a browser, one solution to getting it in a CSV file is to use ajax, upload it to the server, (perhaps optionally save it there) and get the server to send it back with these headers to become a csv download back at the browser.

However, I would like a 100% browser solution that does not involve ping-pong with the server.

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

But this doesn't work for me in recent Chrome.

I do get a new window, and it contains the csvString, but does not act as a download.

I guess I expected to get either a download in a bottom tab or a blank new window with a download in a bottom tab.

I'm wondering if the meta tags are correct or if other tags are also needed.

Is there a way to make this work without punting it to the server?

JsFiddle for Creating a CSV in the Browser (not working - outputs window but no download)

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

6 回答 6

162

总是有 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 月)
似乎在 IE9 中不起作用(大惊喜)(截至 2013 年 7 月)

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


显然IE10 和 IE11有一个 hack ,它不支持该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();
}
于 2013-07-24T14:12:47.047 回答
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');
}

于 2014-12-30T02:51:36.773 回答
15

请参阅 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/

于 2014-07-14T03:28:27.547 回答
7

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

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

Github 上提供了代码、文档和演示/游乐场。

享受 :)

欢迎请求请求。

于 2015-01-04T00:39:28.337 回答
2

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

var csvString = "SEP=, \n" + csvRows.join("\r\n");
于 2018-10-15T11:59:19.023 回答
2

我们可以使用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();

于 2018-09-28T10:03:16.150 回答