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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17836273/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 09:48:36  来源:igfitidea点击:

Export javascript data to CSV file without server interaction

javascriptexport-to-csv

提问by Paul

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

回答by adeneo

There's always the HTML5 downloadattribute :

总是有 HTML5download属性:

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 downloadattribute (Edge does however).

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

回答by Manu Sharma

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

回答by user2608223

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

查看adeeo的答案,但不要忘记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/

回答by Alexander

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.

欢迎拉取请求。

回答by Thyselius

See adeneo's answer, but to make this work in Excel in all countries you should add "SEP=," to the first line of the file. This will set the standard separator in Excel and will not show up in the actual document

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

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

回答by Pulkit Aggarwal

We can easily create and export/download the excel file with any separator (in this answer I am using the comma separator) using javascript. I am not using any external package for creating the excel file.

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