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

IT技术 javascript csv export client-side dojo-1.8
2021-01-09 04:50:14

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

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

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

6个回答

您可以在本机 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");

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

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

编辑:

如果你想给你的文件一个特定的名字,你必须做一些不同的事情,因为不支持使用该window.open方法访问数据 URI 为了实现这一点,您可以创建一个隐藏的<a>DOM 节点并设置其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".
@Abhidemon 答案是你必须对大的东西使用 blob 类型,然后它才能正常工作,例如: blob = new Blob([csvContent], {type: "text/csv"}); href = window.URL.createObjectURL(blob); 更多详情:stackoverflow.com/a/19328891/1854079
2021-03-26 04:50:14
这适用于大约 7000 行。但是开始给出这个错误:NETWORK_INVALID_REQUEST还有其他机构也面临这个问题吗?encodeURIComponent()功能或其他方面的数据是否有上限我使用 Chrome 作为浏览器。
2021-03-27 04:50:14
我必须添加document.body.appendChild(link);才能在 FF 中获得全面支持。
2021-04-02 04:50:14
据我所知,没有办法使用window.open. 但是,您可以创建一个隐藏链接,该链接的download属性设置为您想要的文件名。然后“单击”此链接将以您想要的名称下载文件,我会将其添加到我的答案中。
2021-04-03 04:50:14
这个答案是错误的:它会失败 case data = [["Hello, world"]]当它应该输出一列时,它将输出两列。
2021-04-07 04:50:14

基于上面的答案,我创建了这个功能,我在 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/

我使用了这个答案的下载部分,它在 Chrome 上运行良好,谢谢!
2021-03-26 04:50:14
这个回应是迄今为止最好的回应。它包括带有特殊字符和括号的情况。
2021-04-02 04:50:14
我一直在使用这种方法在相当多的 Web 应用程序中实现 Excel 导出。但是 Chrome 43+ 现在已经将 DOM 属性移动到原型链中。在 处抛出异常link.style.visibility='hidden'B/c DOM 属性是只读的。更多细节可以在updates.html5rocks.com/2015/04/... 的“在严格模式下写入只读属性将引发错误”部分下找到
2021-04-03 04:50:14
这是一段不错的代码。您是否愿意在比 CC-BY-SA 的 SO 默认设置更自由的情况下获得许可?例如,CC0、MIT、BSD、Apache、X11。. . meta.stackexchange.com/questions/12527/...
2021-04-07 04:50:14
可能会下降,回到window.openelselink.download !== undefined
2021-04-08 04:50:14

此解决方案应适用于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

适用于最新的 Chrome、IE 和 Firefox。谢谢!
2021-03-13 04:50:14
(至少,HTML5 代码)无需setTimeout.
2021-03-17 04:50:14
@StubbornShowaGuy 很酷,然后我将从示例代码中删除 setTimeout :)
2021-03-22 04:50:14
这里唯一真正的跨浏览器解决方案。请注意,它适用于 Safari 10.10 和移动版 Safari。但是,该iframe部分可以仅替换为 location.href = ...
2021-03-31 04:50:14
注意:函数中有一个错字,它实际上是URL.createObjectURL(以URLnot结尾Url)。
2021-04-09 04:50:14

我来这里是为了寻求更多的 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.

我不知道最后一次空检查是否一定是预期的行为。Null 与空字符串非常不同。如果要实现这一点,我会推荐一个自定义的空值(例如:'[[NULL]]')。也可能需要 undefined 的例外,但我建议不要用空字符串替换 null。
2021-03-12 04:50:14
我已经测试过,发现你是对的。这似乎适用于 Chrome 和 Opera。Safari 只会打开一个包含内容的页面。Internet Explorer...好吧,它是 IE。对于我的情况,遗憾的是,我将生成我的 CSV 服务器端并以这种方式提供服务。
2021-03-14 04:50:14
很好,克里斯,我没有用数字数据测试它:)
2021-04-01 04:50:14

在 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();
完美运行!
2021-03-10 04:50:14
2021-03-30 04:50:14