如何将JavaScript数组信息导出到csv(在客户端)?

How to export JavaScript array info to csv (on client side)?

提问人:Sam007 提问时间:2/20/2013 最后编辑:Bourbia BrahimSam007 更新时间:8/29/2023 访问量:987815

问:

我知道有很多这种性质的问题,但我需要使用 JavaScript 来做到这一点。我正在使用数组中的所有属性信息,如下所示:Dojo 1.8

[["name1", "city_name1", ...]["name2", "city_name2", ...]]

知道如何将其导出到客户端吗?CSV

javascript csv 导出 客户端 dojo-1.8 reactjs

评论


答:

1277赞 Default 2/20/2013 #1

您可以在原生 JavaScript 中执行此操作。您必须将数据解析为正确的 CSV 格式(假设您对数据使用数组,如问题中所述):

const rows = [
    ["name1", "city1", "some other info"],
    ["name2", "city2", "more info"]
];

let csvContent = "data:text/csv;charset=utf-8,";

rows.forEach(function(rowArray) {
    let row = rowArray.join(",");
    csvContent += row + "\r\n";
});

或较短的方法(使用箭头函数):

const rows = [
    ["name1", "city1", "some other info"],
    ["name2", "city2", "more info"]
];

let csvContent = "data:text/csv;charset=utf-8," 
    + rows.map(e => e.join(",")).join("\n");

然后,您可以使用 JavaScript 和函数下载 CSV 文件,如下所示:window.openencodeURI

var encodedUri = encodeURI(csvContent);
window.open(encodedUri);

编辑:

如果要为文件指定特定名称,则必须执行一些不同的操作,因为不支持使用该方法访问数据 URI。为了实现这一点,您可以创建一个隐藏的 DOM 节点并设置其属性,如下所示:window.open<a>download

var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "my_data.csv");
document.body.appendChild(link); // Required for FF

link.click(); // This will download the data file named "my_data.csv".

评论

6赞 Default 2/20/2013
据我所知,没有办法使用 .但是,您可以创建一个隐藏链接,该链接的属性设置为所需的文件名。然后“单击”此链接将以您想要的名称下载文件,我会将其添加到我的答案中。window.opendownload
14赞 Hardbyte 2/25/2014
我必须添加才能获得 FF 的全力支持。document.body.appendChild(link);
29赞 aredridel 7/23/2015
这个答案是错误的:它会失败.这将在应该输出一列时输出两列。data = [["Hello, world"]]
27赞 Abhidemon 7/12/2016
这适用于 ~7000 行。但是开始给出这个错误:NETWORK_INVALID_REQUEST。还有其他机构也面临这个问题吗?功能或其他方面的数据有上限吗?我使用 Chrome 作为浏览器。encodeURIComponent()
35赞 mdubez 7/14/2017
@Abhidemon 答案是你必须对这么大的东西使用 blob 类型,然后它就可以正常工作了,例如: blob = new Blob([csvContent], {type: “text/csv”});href = 窗口。URL.createObjectURL(blob);更多详情:stackoverflow.com/a/19328891/1854079
36赞 Dzarek 11/8/2013 #2

@Default的解决方案在Chrome上运行完美(非常感谢!),但我在IE上遇到了问题。

下面是一个解决方案(适用于 IE10):

var csvContent=data; //here we load our csv data 
var blob = new Blob([csvContent],{
    type: "text/csv;charset=utf-8;"
});

navigator.msSaveBlob(blob, "filename.csv")

评论

1赞 Sergey Sob 12/17/2020
不适用于 Chrome。前缀“ms”甚至在测试之前就已经很清楚了:)希望 WebKit 有类似的东西
0赞 degr 2/3/2022
msSaveBlob - 已弃用的功能
39赞 Uxonith 12/17/2013 #3

我来这里是为了寻找更多的 RFC 4180 合规性,但我没有找到实现,所以我根据自己的需要制作了一个(可能效率低下的)实现。我想我会和大家分享。

var content = [['1st title', '2nd title', '3rd title', 'another title'], ['a a a', 'bb\nb', 'cc,c', 'dd"d'], ['www', 'xxx', 'yyy', 'zzz']];

var finalVal = '';

for (var i = 0; i < content.length; i++) {
    var value = content[i];

    for (var j = 0; j < value.length; j++) {
        var innerValue =  value[j]===null?'':value[j].toString();
        var result = innerValue.replace(/"/g, '""');
        if (result.search(/("|,|\n)/g) >= 0)
            result = '"' + result + '"';
        if (j > 0)
            finalVal += ',';
        finalVal += result;
    }

    finalVal += '\n';
}

console.log(finalVal);

var download = document.getElementById('download');
download.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(finalVal));
download.setAttribute('download', 'test.csv');

希望这将在未来对某人有所帮助。这结合了 CSV 的编码以及下载文件的功能。在我关于 jsfiddle 的示例中。您可以下载文件(假设是 HTML 5 浏览器)或在控制台中查看输出。

更新:

Chrome 现在似乎失去了为文件命名的功能。我不确定发生了什么或如何修复它,但是每当我使用此代码(包括 jsfiddle)时,下载的文件现在都被命名为 .download.csv

评论

0赞 Uxonith 3/20/2014
克里斯,我没有用数字数据:)测试它
0赞 Uxonith 3/21/2014
我不知道最后的空检查是否一定是预期的行为。Null 与空字符串有很大不同。如果要实现这一点,我会建议使用自定义 null 值(例如:'[[NULL]]')。可能还需要 undefined 的例外,但我建议不要用空字符串替换 null。
0赞 Uxonith 6/7/2014
我测试过,发现你是对的。这似乎适用于 Chrome 和 Opera。Safari 浏览器只会打开一个包含内容的页面。IE浏览器...嗯,是IE。对于我的情况,可悲的是,我将生成我的 CSV 服务器端并以这种方式提供服务。
43赞 Monu 5/29/2014 #4

在 Chrome 35 更新中,下载属性行为已更改。

https://code.google.com/p/chromium/issues/detail?id=373182

要在 Chrome 中执行此操作,请使用此

var pom = document.createElement('a');
var csvContent=csv; //here we load our csv data 
var blob = new Blob([csvContent],{type: 'text/csv;charset=utf-8;'});
var url = URL.createObjectURL(blob);
pom.href = url;
pom.setAttribute('download', 'foo.csv');
pom.click();

评论

2赞 Gabriel 1/21/2019
你也可以检查这个:github.com/mholt/PapaParse/issues/175#issuecomment-201308792
0赞 Tarilonte 9/9/2021
完美工作!
8赞 Mauri 6/14/2014 #5
//It work in Chrome and IE ... I reviewed and readed a lot of answer. then i used it and tested in both ... 

var link = document.createElement("a");

if (link.download !== undefined) { // feature detection
    // Browsers that support HTML5 download attribute
    var blob = new Blob([CSV], { type: 'text/csv;charset=utf-8;' });
    var url = URL.createObjectURL(blob);            
    link.setAttribute("href", url);
    link.setAttribute("download", fileName);
    link.style = "visibility:hidden";
}

if (navigator.msSaveBlob) { // IE 10+
   link.addEventListener("click", function (event) {
     var blob = new Blob([CSV], {
       "type": "text/csv;charset=utf-8;"
     });
   navigator.msSaveBlob(blob, fileName);
  }, false);
}

document.body.appendChild(link);
link.click();
document.body.removeChild(link);

//Regards
357赞 Xavier John 7/24/2014 #6

根据上面的答案,我创建了这个函数,我已经在 IE 11、Chrome 36 和 Firefox 29 上进行了测试

function exportToCsv(filename, rows) {
    var processRow = function (row) {
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0)
                result = '"' + result + '"';
            if (j > 0)
                finalVal += ',';
            finalVal += result;
        }
        return finalVal + '\n';
    };

    var csvFile = '';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }

    var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    } else {
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}

例如:https://jsfiddle.net/jossef/m3rrLzk0/

评论

9赞 MrYellow 2/6/2015
可以回退到 .window.openelselink.download !== undefined
5赞 joseph_morris 3/4/2015
这是一段不错的代码。你有没有机会愿意在比 CC-BY-SA 的 SO 默认值更自由的东西下许可它?例如,CC0、MIT、BSD、Apache、X11 ......meta.stackexchange.com/questions/12527/......
1赞 Blaise 9/2/2015
我一直在使用这种方法在相当多的 Web 应用程序中实现 Excel 导出。但 Chrome 43+ 现在已经将 DOM 属性移到了原型链中。在 处抛出异常。B/c DOM 属性是只读的。更多详细信息可以在 updates.html5rocks.com/2015/04/...的“在严格模式下写入只读属性将引发错误”部分找到link.style.visibility='hidden'
3赞 Vladimir Kostov 5/17/2019
这个回应是迄今为止最好的回应。它包括带有特殊字符和括号的大小写。
5赞 Liran H 6/29/2019
我使用了这个答案的下载部分,它在 Chrome 上运行良好,谢谢!
95赞 Arne H. Bitubekk 3/27/2015 #7

此解决方案应适用于 Internet Explorer 10+、Edge、新旧版本的 Chrome、FireFox、Safari、++

接受的答案不适用于 IE 和 Safari。

// Example data given in question text
var data = [
  ['name1', 'city1', 'some other info'],
  ['name2', 'city2', 'more info']
];

// Building the CSV from the Data two-dimensional array
// Each column is separated by ";" and new line "\n" for next row
var csvContent = '';
data.forEach(function(infoArray, index) {
  dataString = infoArray.join(';');
  csvContent += index < data.length ? dataString + '\n' : dataString;
});

// The download function takes a CSV string, the filename and mimeType as parameters
// Scroll/look down at the bottom of this snippet to see how download is called
var download = function(content, fileName, mimeType) {
  var a = document.createElement('a');
  mimeType = mimeType || 'application/octet-stream';

  if (navigator.msSaveBlob) { // IE10
    navigator.msSaveBlob(new Blob([content], {
      type: mimeType
    }), fileName);
  } else if (URL && 'download' in a) { //html5 A[download]
    a.href = URL.createObjectURL(new Blob([content], {
      type: mimeType
    }));
    a.setAttribute('download', fileName);
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  } else {
    location.href = 'data:application/octet-stream,' + encodeURIComponent(content); // only this mime type is supported
  }
}

download(csvContent, 'dowload.csv', 'text/csv;encoding:utf-8');

运行代码片段会将模拟数据下载为 csv

归功于 dandavis https://stackoverflow.com/a/16377813/1350598

评论

1赞 StubbornShowaGuy 9/27/2016
(至少,HTML5 代码)在没有 .setTimeout
0赞 Arne H. Bitubekk 9/28/2016
@StubbornShowaGuy很酷,那么我将从示例代码中删除 setTimeout :)
0赞 walla 10/7/2016
适用于最新的 Chrome、IE 和 Firefox。谢谢!
0赞 Dan 4/6/2017
这里唯一真正的跨浏览器解决方案。请注意,它适用于 Safari 10.10 和移动 Safari。但是,该部分可以替换为 location.href = ...iframe
2赞 Nathan Hinchey 4/15/2017
注意:函数中有一个拼写错误,它实际上是(以 not 结尾)。URL.createObjectURLURLUrl
5赞 Liyosi 4/21/2015 #8

使用 csv 数据 .ie 创建 blobvar blob = new Blob([data], type:"text/csv");

如果浏览器支持保存 blob,即 ,则使用以下命令保存 csv 数据:if window.navigator.mSaveOrOpenBlob)===truewindow.navigator.msSaveBlob(blob, 'filename.csv')

如果浏览器不支持保存和打开 Blob,则将 csv 数据另存为:

var downloadLink = document.createElement('<a></a>');
downloadLink.attr('href', window.URL.createObjectURL(blob));
downloadLink.attr('download', filename);
downloadLink.attr('target', '_blank');
document.body.append(downloadLink);

完整代码片段:

var filename = 'data_'+(new Date()).getTime()+'.csv';
var charset = "utf-8";
var blob = new Blob([data], {
     type: "text/csv;charset="+ charset + ";"
});
if (window.navigator.msSaveOrOpenBlob) {
     window.navigator.msSaveBlob(blob, filename);
} else {
    var downloadLink = document.element('<a></a>');
    downloadLink.attr('href', window.URL.createObjectURL(blob));
    downloadLink.attr('download', filename);
    downloadLink.attr('target', '_blank');  
    document.body.append(downloadLink); 
    downloadLink[0].click(); 
}
2赞 Justin Stein 9/29/2015 #9

以下是我在 Java GWT 应用程序中在客户端下载 CSV 文件的方法。特别感谢 Xavier John 的解决方案。它已被验证可在 FF 24.6.0、IE 11.0.20 和 Chrome 45.0.2454.99(64 位)中运行。我希望这能为某人节省一些时间:

public class ExportFile 
{

    private static final String CRLF = "\r\n";

    public static void exportAsCsv(String filename, List<List<String>> data) 
    {
        StringBuilder sb = new StringBuilder();
        for(List<String> row : data) 
        {
            for(int i=0; i<row.size(); i++)
            {
                if(i>0) sb.append(",");
                sb.append(row.get(i));
            }
            sb.append(CRLF);
        }

        generateCsv(filename, sb.toString());
    }

    private static native void generateCsv(String filename, String text)
    /*-{
        var blob = new Blob([text], { type: 'text/csv;charset=utf-8;' });

        if (navigator.msSaveBlob) // IE 10+
        { 
            navigator.msSaveBlob(blob, filename);
        } 
        else 
        {
            var link = document.createElement("a");
            if (link.download !== undefined) // feature detection
            { 
                // Browsers that support HTML5 download attribute
                var url = URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", filename);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
            }
        }
    }-*/;
}
14赞 Madhulika Mukherjee 12/2/2015 #10

给你:

<!doctype html>  
<html>  
<head></head>  
<body>
<a href='#' onclick='downloadCSV({ filename: "stock-data.csv" });'>Download CSV</a>

<script type="text/javascript">  
    var stockData = [
        {
            Symbol: "AAPL",
            Company: "Apple Inc.",
            Price: "132.54"
        },
        {
            Symbol: "INTC",
            Company: "Intel Corporation",
            Price: "33.45"
        },
        {
            Symbol: "GOOG",
            Company: "Google Inc",
            Price: "554.52"
        },
    ];

    function convertArrayOfObjectsToCSV(args) {
        var result, ctr, keys, columnDelimiter, lineDelimiter, data;

        data = args.data || null;
        if (data == null || !data.length) {
            return null;
        }

        columnDelimiter = args.columnDelimiter || ',';
        lineDelimiter = args.lineDelimiter || '\n';

        keys = Object.keys(data[0]);

        result = '';
        result += keys.join(columnDelimiter);
        result += lineDelimiter;

        data.forEach(function(item) {
            ctr = 0;
            keys.forEach(function(key) {
                if (ctr > 0) result += columnDelimiter;

                result += item[key];
                ctr++;
            });
            result += lineDelimiter;
        });

        return result;
    }

    window.downloadCSV = function(args) {
        var data, filename, link;

        var csv = convertArrayOfObjectsToCSV({
            data: stockData
        });
        if (csv == null) return;

        filename = args.filename || 'export.csv';

        if (!csv.match(/^data:text\/csv/i)) {
            csv = 'data:text/csv;charset=utf-8,' + csv;
        }
        data = encodeURI(csv);

        link = document.createElement('a');
        link.setAttribute('href', data);
        link.setAttribute('download', filename);
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
       }
</script>  
</body>  
</html>  

评论

1赞 Hoser 12/28/2015
很棒的答案。我赞成这个,因为出于某种原因,接受的答案将所有内容放在一列中。这会将其全部分解为单独的列,并且类似 JSON 的数据格式支持非常有用。
0赞 Jay Dubal 2/15/2017
当链接首次添加到文档正文,然后调用单击时,此功能有效。然后从 dom 中删除它。
1赞 Philip E 3/15/2017
很好的答案,唯一的缺点是当数据有列分隔符时它不能正常工作“ , ” 即地址:'10 Infinite loop lane, Room 56',注意车道后面的逗号。我建议您使用 PapaParse 链接将数据转换为 CSV,然后使用上面的 downloadCSV 方法进行实际文件下载
0赞 Aakarsh Dhawan 10/28/2019
这对我来说非常有效。只有一个问题,我在数组中有一些数字,例如“000002342”,但是当导出到 csv 时,前导零会被删除。有什么方法可以防止这种情况发生吗?
0赞 Milimetric 2/4/2016 #11

如果有人需要这个用于 knockout js,它基本上可以与建议的解决方案一起使用:

HTML格式:

<a data-bind="attr: {download: filename, href: csvContent}">Download</a>

查看模型:

// for the download link
this.filename = ko.computed(function () {
    return ko.unwrap(this.id) + '.csv';
}, this);
this.csvContent = ko.computed(function () {
    if (!this.csvLink) {
        var data = ko.unwrap(this.data),
            ret = 'data:text/csv;charset=utf-8,';

        ret += data.map(function (row) {
            return row.join(',');
        }).join('\n');

        return encodeURI(ret);
    }
}, this);
6赞 Konstantin 4/9/2016 #12

这里有两个问题:

  1. 如何将数组转换为 csv 字符串
  2. 如何将该字符串保存到文件

这里第一个问题的所有答案(除了 Milimetric 的答案)似乎都有点矫枉过正。而 Milimetric 的那个没有涵盖 altrenative 要求,例如用引号包围字符串或转换对象数组。

以下是我对此的看法:

对于一个简单的 csv,一个 map() 和一个 join() 就足够了:

    var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]];
    var csv = test_array.map(function(d){
        return d.join();
    }).join('\n');

    /* Results in 
    name1,2,3
    name2,4,5
    name3,6,7
    name4,8,9
    name5,10,11

此方法还允许您在内部联接中指定逗号以外的列分隔符。例如,选项卡:d.join('\t')

另一方面,如果你想正确地做到这一点,并将字符串括在引号“”中,那么你可以使用一些JSON魔术:

var csv = test_array.map(function(d){
       return JSON.stringify(d);
    })
    .join('\n') 
    .replace(/(^\[)|(\]$)/mg, ''); // remove opening [ and closing ]
                                   // brackets from each line 

/* would produce
"name1",2,3
"name2",4,5
"name3",6,7
"name4",8,9
"name5",10,11

如果您有如下对象数组:

var data = [
  {"title": "Book title 1", "author": "Name1 Surname1"},
  {"title": "Book title 2", "author": "Name2 Surname2"},
  {"title": "Book title 3", "author": "Name3 Surname3"},
  {"title": "Book title 4", "author": "Name4 Surname4"}
];

// use
var csv = data.map(function(d){
        return JSON.stringify(Object.values(d));
    })
    .join('\n') 
    .replace(/(^\[)|(\]$)/mg, '');

评论

0赞 aaronbartell 6/13/2017
如果我没记错的话,我相信应该指定大括号与方括号。.replace
0赞 Konstantin 6/13/2017
.replace在返回的字符串上完成,该字符串接受一个对象并返回一个值数组values()
0赞 aaronbartell 6/13/2017
当我尝试您的代码时,没有找到该方法。values()
0赞 Konstantin 6/13/2017
谢谢!在 Chrome 中,它可以在不显式调用 .我更正了这个例子。values()Object
0赞 Bim 9/20/2016 #13

我添加了 Xavier Johns 函数,以便在需要时也包含字段标题,但使用 jQuery。$.each 位需要更改为原生 javascript 循环

function exportToCsv(filename, rows, headers = false) {
    var processRow = function (row) {
        row = $.map(row, function(value, index) {
            return [value];
        });
        var finalVal = '';
        for (var j = 0; j < row.length; j++) {
            if(i == 0 && j == 0 && headers == true){
                var ii = 0;
                $.each(rows[i], function( index, value ) {
                    //console.log(index);
                    var fieldName = index === null ? '' : index.toString();
                    //console.log(fieldName);
                    var fieldResult = fieldName.replace(/"/g, '""');
                    //console.log(fieldResult);
                    if (fieldResult.search(/("|,|\n)/g) >= 0){
                        fieldResult = '"' + fieldResult + '"';
                    }
                    //console.log(fieldResult);
                    if (ii > 0){
                        finalVal += ',';
                        finalVal += fieldResult;
                    }else{
                        finalVal += fieldResult;
                    }
                    ii++;
                    //console.log(finalVal);
                });
                finalVal += '\n';
                //console.log('end: '+finalVal);
            }
            var innerValue = row[j] === null ? '' : row[j].toString();
            if (row[j] instanceof Date) {
                innerValue = row[j].toLocaleString();
            };
            var result = innerValue.replace(/"/g, '""');
            if (result.search(/("|,|\n)/g) >= 0){
                result = '"' + result + '"';
            }
            if (j > 0){
                finalVal += ',';
                finalVal += result;
            }else{
                finalVal += result;
            }
        }
        return finalVal + '\n';
    };
    var csvFile = '';
    for (var i = 0; i < rows.length; i++) {
        csvFile += processRow(rows[i]);
    }
    var blob = new Blob([csvFile], { type: 'text/csv;charset=utf-8;' });
    if (navigator.msSaveBlob) { // IE 10+
        navigator.msSaveBlob(blob, filename);
    }else{
        var link = document.createElement("a");
        if (link.download !== undefined) { // feature detection
            // Browsers that support HTML5 download attribute
            var url = URL.createObjectURL(blob);
            link.setAttribute("href", url);
            link.setAttribute("download", filename);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    }
}

评论

0赞 TaouBen 8/30/2021
我们知道您知道 Angular,但是谁在这里要求它作为解决方案?
0赞 Ronald G 9/21/2016 #14

这是基于已接受答案的修改答案,其中数据将来自 JSON。

            JSON Data Ouptut:
             0 :{emails: "SAMPLE Co., [email protected]"}, 1:{emails: "Another CO. , [email protected]"}


            JS:
            $.getJSON('yourlink_goes_here', { if_you_have_parameters}, function(data) {
            var csvContent = "data:text/csv;charset=utf-8,";
            var dataString = '';
             $.each(data, function(k, v) {
                dataString += v.emails + "\n";
             });

            csvContent += dataString;

            var encodedUri = encodeURI(csvContent);
            var link = document.createElement("a");
            link.setAttribute("href", encodedUri);
            link.setAttribute("download", "your_filename.csv");
            document.body.appendChild(link); // Required for FF

            link.click();
        });
1赞 Marquistador 10/26/2016 #15

上面的答案有效,但请记住,如果您以 .xls 格式打开,列 ~~might~~ 用 代替 分隔,答案对我来说 https://stackoverflow.com/a/14966131/6169225 很好用,只要我在数组上使用而不是 .'\t'','.join('\t').join(',')

评论

0赞 gabrielAnzaldo 10/4/2017
适用于 .xls 文件,顺便说一句,我有一个小问题,当文本太长并且超过网格的大小时,工作表看起来不太好,有什么提示可以解决这个问题吗?
8赞 Abdennour TOUMI 11/25/2016 #16

ES6 的单箭头功能:

const dataToCsvURI = (data) => encodeURI(
`data:text/csv;charset=utf-8,${data.map((row, index) =>  row.join(',')).join(`\n`)}`
);

然后:

window.open(
  dataToCsvURI(
   [["name1", "city_name1"/*, ...*/], ["name2", "city_name2"/*, ...*/]]
  )
);

如果有人需要这个 就在那里

评论

3赞 Matt Parrilla 3/24/2017
图书馆就像一个魅力。对于任何使用模块的人来说,这都是很好的解决方案。react-csv
0赞 unpollito 9/26/2018
这无法观察到 CSV 文件中有字段和逗号的情况。
1赞 Chrillewoodz 9/6/2017 #17

这是一个 Angular 友好的版本:

  constructor(private location: Location, private renderer: Renderer2) {}

  download(content, fileName, mimeType) {

    const a = this.renderer.createElement('a');

    mimeType = mimeType || 'application/octet-stream';

    if (navigator.msSaveBlob) {

      navigator.msSaveBlob(new Blob([content], {
        type: mimeType
      }), fileName);
    }
    else if (URL && 'download' in a) {

      const id = GetUniqueID();

      this.renderer.setAttribute(a, 'id', id);
      this.renderer.setAttribute(a, 'href', URL.createObjectURL(new Blob([content], {
        type: mimeType
      })));

      this.renderer.setAttribute(a, 'download', fileName);

      this.renderer.appendChild(document.body, a);

      const anchor = this.renderer.selectRootElement(`#${id}`);

      anchor.click();

      this.renderer.removeChild(document.body, a);
    }
    else {
      this.location.go(`data:application/octet-stream,${encodeURIComponent(content)}`);
    }
  };
7赞 John Rix 10/20/2017 #18

这里有很多用于将数据转换为 CSV 的滚动解决方案,但几乎所有解决方案在正确格式化数据类型方面都有各种警告,而不会绊倒 Excel 等。

为什么不使用经过验证的东西:Papa Parse

Papa.unparse(data[, config])

然后只需将其与此处的本地下载解决方案之一结合使用,例如。一个接一个@ArneHB看起来不错。

1赞 Michael_Scharf 11/17/2017 #19

我使用此函数将 an 转换为 csv 文件。如果单元格包含 、a 或其他空格(空格除外),则引用该单元格:string[][]",

/**
 * Takes an array of arrays and returns a `,` sparated csv file.
 * @param {string[][]} table
 * @returns {string}
 */
function toCSV(table) {
    return table
        .map(function(row) {
            return row
                .map(function(cell) {
                    // We remove blanks and check if the column contains
                    // other whitespace,`,` or `"`.
                    // In that case, we need to quote the column.
                    if (cell.replace(/ /g, '').match(/[\s,"]/)) {
                        return '"' + cell.replace(/"/g, '""') + '"';
                    }
                    return cell;
                })
                .join(',');
        })
        .join('\n'); // or '\r\n' for windows

}

注意:除非是 polyfilled,否则在 Internet Explorer < 11 上不起作用。map

备注:如果单元格包含数字,则可以添加 before 以将数字转换为字符串。cell=''+cellif (cell.replace...

或者你可以用 ES6 把它写成一行:

t.map(r=>r.map(c=>c.replace(/ /g, '').match(/[\s,"]/)?'"'+c.replace(/"/g,'""')+'"':c).join(',')).join('\n')
25赞 Serdar Didan 4/21/2018 #20

适用于所有语言

        function convertToCsv(fName, rows) {
        var csv = '';
        for (var i = 0; i < rows.length; i++) {
            var row = rows[i];
            for (var j = 0; j < row.length; j++) {
                var val = row[j] === null ? '' : row[j].toString();
                val = val.replace(/\t/gi, " ");
                if (j > 0)
                    csv += '\t';
                csv += val;
            }
            csv += '\n';
        }

        // for UTF-16
        var cCode, bArr = [];
        bArr.push(255, 254);
        for (var i = 0; i < csv.length; ++i) {
            cCode = csv.charCodeAt(i);
            bArr.push(cCode & 0xff);
            bArr.push(cCode / 256 >>> 0);
        }

        var blob = new Blob([new Uint8Array(bArr)], { type: 'text/csv;charset=UTF-16LE;' });
        if (navigator.msSaveBlob) {
            navigator.msSaveBlob(blob, fName);
        } else {
            var link = document.createElement("a");
            if (link.download !== undefined) {
                var url = window.URL.createObjectURL(blob);
                link.setAttribute("href", url);
                link.setAttribute("download", fName);
                link.style.visibility = 'hidden';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                window.URL.revokeObjectURL(url);
            }
        }
    }



    convertToCsv('download.csv', [
        ['Order', 'Language'],
        ['1', 'English'],
        ['2', 'Español'],
        ['3', 'Français'],
        ['4', 'Português'],
        ['5', 'čeština'],
        ['6', 'Slovenščina'],
        ['7', 'Tiếng Việt'],
        ['8', 'Türkçe'],
        ['9', 'Norsk bokmål'],
        ['10', 'Ελληνικά'],
        ['11', 'беларускі'],
        ['12', 'русский'],
        ['13', 'Українська'],
        ['14', 'հայերեն'],
        ['15', 'עִברִית'],
        ['16', 'اردو'],
        ['17', 'नेपाली'],
        ['18', 'हिंदी'],
        ['19', 'ไทย'],
        ['20', 'ქართული'],
        ['21', '中国'],
        ['22', '한국어'],
        ['23', '日本語'],
    ])

评论

1赞 Mar1009 11/23/2019
你能帮我了解什么是UTF-16代码块以及这里有什么用途吗?
0赞 Serdar Didan 11/28/2019
嗨,Mar1009。对于某些语言,这是必需的。例如,西里尔字母。
0赞 cdauth 11/10/2020
如果下载的数据稍大,这将导致网络错误。包装它会有所帮助,请参阅此处window.URL.revokeObjectURL(url);setTimeout()
0赞 tequilacat 4/9/2021
对于 Excel 365 商业应用版,我必须删除 BOM 标记,因为 Excel 无法识别列。如果没有 BOM,Unicodeness 和列都可以识别。我想知道其他版本的表现如何。bArr.push(255, 254)
20赞 Vignesh Subramanian 9/20/2018 #21

您可以使用以下代码将数组导出为使用 Javascript 的 CSV 文件。

这也处理特殊字符部分

var arrayContent = [["Séjour 1, é,í,ú,ü,ű"],["Séjour 2, é,í,ú,ü,ű"]];
var csvContent = arrayContent.join("\n");
var link = window.document.createElement("a");
link.setAttribute("href", "data:text/csv;charset=utf-8,%EF%BB%BF" + encodeURI(csvContent));
link.setAttribute("download", "upload_data.csv");
link.click(); 

这是工作 jsfiddle 的链接

评论

0赞 Yimin Rong 9/26/2023
这应该被标记为正确答案:简短,切中要害,没有特殊情况。我所做的唯一修改是用空格替换内部 CR/LF。
2赞 Imal Hasaranga Perera 3/27/2019 #22

只需尝试一下,这里的一些答案不处理 unicode 数据和带有逗号的数据,例如日期。

function downloadUnicodeCSV(filename, datasource) {
    var content = '', newLine = '\r\n';
    for (var _i = 0, datasource_1 = datasource; _i < datasource_1.length; _i++) {
        var line = datasource_1[_i];
        var i = 0;
        for (var _a = 0, line_1 = line; _a < line_1.length; _a++) {
            var item = line_1[_a];
            var it = item.replace(/"/g, '""');
            if (it.search(/("|,|\n)/g) >= 0) {
                it = '"' + it + '"';
            }
            content += (i > 0 ? ',' : '') + it;
            ++i;
        }
        content += newLine;
    }
    var link = document.createElement('a');
    link.setAttribute('href', 'data:text/csv;charset=utf-8,%EF%BB%BF' + encodeURIComponent(content));
    link.setAttribute('download', filename);
    link.style.visibility = 'hidden';
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
};
42赞 Glen Thompson 5/3/2019 #23

人们正在尝试创建自己的 csv 字符串,但在边缘情况下失败,例如特殊字符,这肯定是一个已解决的问题,对吧?

papaparse - 用于 JSON 到 CSV 编码。.Papa.unparse()

import Papa from "papaparse";

const downloadCSV = (args) => {  

  let filename = args.filename || 'export.csv';
  let columns = args.columns || null;

  let csv = Papa.unparse({ data: args.data, fields: columns})
  if (csv == null) return;

  var blob = new Blob([csv]);
  if (window.navigator.msSaveOrOpenBlob)  // IE hack; see http://msdn.microsoft.com/en-us/library/ie/hh779016.aspx
      window.navigator.msSaveBlob(blob, args.filename);
  else
  {
      var a = window.document.createElement("a");
      a.href = window.URL.createObjectURL(blob, {type: "text/plain"});
      a.download = filename;
      document.body.appendChild(a);
      a.click();  // IE: "Access is denied"; see: https://connect.microsoft.com/IE/feedback/details/797361/ie-10-treats-blob-url-as-cross-origin-and-denies-access
      document.body.removeChild(a);
  }

}

用法示例

downloadCSV({ 
  filename: "filename.csv",
  data: [{"a": "1", "b": "2"}],
  columns: ["a","b"]
});

https://github.com/mholt/PapaParse/issues/175 - 有关浏览器支持讨论,请参阅此注释。

评论

1赞 totalhack 9/5/2020
我添加了一个简单的答案,该答案用于下载部分。如果您认为这是更好的方法,请随时更新或复制。Papa ParseFileSaver.js
0赞 Garr Godfrey 11/30/2021
你有没有一个特殊字符的例子,打破了用“”替换“的简单方法?解析 CSV 很棘手,应该处理引号内的换行符、引号中的逗号等。但是生成 CSV 非常简单
0赞 Taha Attari 4/6/2023
PapaParse 有很多设置,例如特殊字符/转义字符等。我想说这是大多数用例的正确解决方案,因为 CSV 是一种臭名昭著的繁琐格式,有许多陷阱,天真搜索的人可能/可能不知道。快速的原生 JS 解决方案很酷,但不应该是最佳答案或推荐的解决方案。
1赞 Vik2696 10/15/2019 #24

下载CSV文件

  let csvContent = "data:text/csv;charset=utf-8,";
  rows.forEach(function (rowArray) {
    for (var i = 0, len = rowArray.length; i < len; i++) {
      if (typeof (rowArray[i]) == 'string')
        rowArray[i] = rowArray[i].replace(/<(?:.|\n)*?>/gm, '');
      rowArray[i] = rowArray[i].replace(/,/g, '');
    }

    let row = rowArray.join(",");
    csvContent += row + "\r\n"; // add carriage return
  });
  var encodedUri = encodeURI(csvContent);
  var link = document.createElement("a");
  link.setAttribute("href", encodedUri);
  link.setAttribute("download", "fileName.csv");
  document.body.appendChild(link);
  link.click();

评论

0赞 Garr Godfrey 11/30/2021
如果条目不是字符串,这看起来会失败,因为您最终仍然会调用它们,并且您永远不会将 Numbers 转换为字符串。此外,它还从我们可能想要保留的字符串中删除了各种字符!replace
8赞 dabeng 2/24/2020 #25

下面是一个原生的 js 解决方案。

function export2csv() {
  let data = "";
  const tableData = [];
  const rows = [
    ['111', '222', '333'],
    ['aaa', 'bbb', 'ccc'],
    ['AAA', 'BBB', 'CCC']
  ];
  for (const row of rows) {
    const rowData = [];
    for (const column of row) {
      rowData.push(column);
    }
    tableData.push(rowData.join(","));
  }
  data += tableData.join("\n");
  const a = document.createElement("a");
  a.href = URL.createObjectURL(new Blob([data], { type: "text/csv" }));
  a.setAttribute("download", "data.csv");
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}
<button onclick="export2csv()">Export array to csv file</button>

1赞 Mladen Mitrovic 5/29/2020 #26

如果您正在寻找一个非常快速的解决方案,您还可以给这个小型库一个机会,它将为您创建和下载 CSV 文件:https://github.com/mbrn/filefy

用法非常简单:

import { CsvBuilder } from 'filefy';

var csvBuilder = new CsvBuilder("user_list.csv")
  .setColumns(["name", "surname"])
  .addRow(["Eve", "Holt"])
  .addRows([
    ["Charles", "Morris"],
    ["Tracey", "Ramos"]
  ])
  .exportFile();
19赞 totalhack 9/5/2020 #27

老问题有很多很好的答案,但这是另一个简单的选择,它依赖于两个流行的库来完成它。一些答案提到了Papa Parse,但为下载部分推出了自己的解决方案。 结合Papa Parse和FileSaver.js,您可以尝试以下操作:

const dataString = Papa.unparse(data, config);
const blob = new Blob([dataString], { type: 'text/csv;charset=utf-8' });
FileSaver.saveAs(blob, 'myfile.csv');

此处介绍了 的选项。configunparse

评论

0赞 Andreas Covidiot 8/6/2022
在我看来,这是最短(不容易出错)并且可能是最强大的跨浏览器方法,在这一点上,功能基于维护的库。谢谢。
5赞 Vladimir 10/21/2020 #28

来自 react-admin

function downloadCsv(csv, filename) {
    const fakeLink = document.createElement('a');
    fakeLink.style.display = 'none';
    document.body.appendChild(fakeLink);
    const blob = new Blob([csv], { type: 'text/csv' });
    if (window.navigator && window.navigator.msSaveOrOpenBlob) {
        // Manage IE11+ & Edge
        window.navigator.msSaveOrOpenBlob(blob, `${filename}.csv`);
    } else {
        fakeLink.setAttribute('href', URL.createObjectURL(blob));
        fakeLink.setAttribute('download', `${filename}.csv`);
        fakeLink.click();
    }
};

downloadCsv('Hello World', 'any-file-name.csv');

评论

0赞 Aleks 2/6/2021
您的代码将创建一个包含单行的 CSV 文件,而不考虑数据的大小
117赞 kolypto 6/27/2021 #29

一个简约但功能齐全的解决方案:)

/** Convert a 2D array into a CSV string
 */
function arrayToCsv(data){
  return data.map(row =>
    row
    .map(String)  // convert every value to String
    .map(v => v.replaceAll('"', '""'))  // escape double quotes
    .map(v => `"${v}"`)  // quote it
    .join(',')  // comma-separated
  ).join('\r\n');  // rows starting on new lines
}

例:

let csv = arrayToCsv([
  [1, '2', '"3"'],
  [true, null, undefined],
]);

结果:

"1","2","""3"""
"true","null","undefined"

现在将其下载为文件:


/** Download contents as a file
 * Source: https://stackoverflow.com/questions/14964035/how-to-export-javascript-array-info-to-csv-on-client-side
 */
function downloadBlob(content, filename, contentType) {
  // Create a blob
  var blob = new Blob([content], { type: contentType });
  var url = URL.createObjectURL(blob);

  // Create a link to download it
  var pom = document.createElement('a');
  pom.href = url;
  pom.setAttribute('download', filename);
  pom.click();
}

下载它:

downloadBlob(csv, 'export.csv', 'text/csv;charset=utf-8;')

save dialog

resulting file

评论

16赞 Garr Godfrey 11/30/2021
这已经很晚了,但确实是这里最好的答案。
3赞 jave.web 12/18/2022
社区应该以这个 A 为例:-) , Separator, Enclosure, Escape(character) 是可以用来存储格式字符的通用术语。(这里是转义和外壳 - 并不总是这样,您必须将此信息传输到 CSV 接收器)"
0赞 o-az 9/9/2023
我将删除创建的锚元素和对象 url。参见 : developer.mozilla.org/en-US/docs/Web/API/URL/...URL: revokeObjectURL()document.body.removeChild(pom)
1赞 danielson317 9/11/2023
这里是最好的答案,但希望看到这一点得到改进,只有在单元格内容中包含连接字符时才添加引号。
0赞 DarkCrazy 7/12/2022 #30

这个库有很大帮助:https://www.npmjs.com/package/json-to-csv-in-browser

它会自动将 json 数组转换为 csv 文件,如果您想提示 Web 用户下载 csv 文件,它甚至为您提供下载功能。 它就像一个魅力,代码很少。

import { JsonArray, download } from 'json-to-csv-in-browser'

const arr = [
    {name : ` vader`, age : 53},
    {name : "what", age : 38},
    {name : "ever", age : 22}
]
const jsonArray = new JsonArray(arr);
const str = jsonArray.convertToCSVstring();
download("my.csv", str);

干杯!

编辑:再测试一下,如果你的值上有逗号,它就不能很好地工作

评论

0赞 7/20/2022
此库用于 TypeScript