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

时间:2021-09-15 03:48:36

If we were on a nodeJS server, we could write a header, set a mime type, and send it:

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

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.

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

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.

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

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

但是,我想要100%的浏览器解决方案,不涉及与服务器的乒乓。

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

所以我想到可以打开一个新窗口并尝试使用META标记等效设置标题。

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

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

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

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

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)

用于在浏览器中创建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);

4 个解决方案

#1


152  

There's always the HTML5 download attribute :

始终有HTML5下载属性:

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

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

If the attribute has a value, the value will be used as the pre-filled file name in the Save prompt that 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).
Works in Opera as well, but does not set the filename (as of July 2013).
Does not seem to work in IE9 (big suprise) (as of July 2013).

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

An overview over what browsers support the download attribute can be found Here
For non-supporting browsers, one has to set the appropriate headers on the serverside.

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


Apparently there is a hack for IE10 and IE11, which doesn't support the download attribute (Edge does however).

显然有一个IE10和IE11的黑客,它不支持下载属性(但是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


24  

@adeneo answer works for Firefox and chrome... For IE the below can be used.

@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


15  

See adeneo's answer, but don't forget encodeURIComponent!

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

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

Also, I needed to do "\r\n" not just "\n" for the row delimiter.

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

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

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

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

#4


7  

Once I packed JS code doing that to a tiny library:

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

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

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

The Code, Documentation and Demo/Playground are provided on Github.

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

Enjoy :)

请享用 :)

Pull requests are welcome.

欢迎提出拉动请求。

#1


152  

There's always the HTML5 download attribute :

始终有HTML5下载属性:

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

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

If the attribute has a value, the value will be used as the pre-filled file name in the Save prompt that 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).
Works in Opera as well, but does not set the filename (as of July 2013).
Does not seem to work in IE9 (big suprise) (as of July 2013).

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

An overview over what browsers support the download attribute can be found Here
For non-supporting browsers, one has to set the appropriate headers on the serverside.

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


Apparently there is a hack for IE10 and IE11, which doesn't support the download attribute (Edge does however).

显然有一个IE10和IE11的黑客,它不支持下载属性(但是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


24  

@adeneo answer works for Firefox and chrome... For IE the below can be used.

@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


15  

See adeneo's answer, but don't forget encodeURIComponent!

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

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

Also, I needed to do "\r\n" not just "\n" for the row delimiter.

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

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

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

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

#4


7  

Once I packed JS code doing that to a tiny library:

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

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

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

The Code, Documentation and Demo/Playground are provided on Github.

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

Enjoy :)

请享用 :)

Pull requests are welcome.

欢迎提出拉动请求。