如何将JavaScript数组信息导出到csv(在客户端)?
我知道有很多这种性质的问题,但我需要使用JavaScript来做到这一点。 我正在使用Dojo 1.8
并拥有数组中的所有属性信息,如下所示:
[["name1", "city_name1", ...]["name2", "city_name2", ...]]
任何想法如何可以导出到CSV
在客户端?
你可以在原生JavaScript中做到这一点。 您必须将数据parsing为正确的CSV格式(假设您正如问题中所描述的那样使用数据arrays作为数据):
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"; // add carriage return });
然后你可以使用JavaScript的window.open
和encodeURI
函数来下载CSV文件,如下所示:
var encodedUri = encodeURI(csvContent); window.open(encodedUri);
编辑:
如果你想给你的文件一个特定的名字,你必须做一点不同的事情,因为不支持使用window.open
方法访问数据URI。 为了实现这一点,你可以创build一个隐藏的<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".
基于上面的答案,我创build了这个function,我testing了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/
这个解决scheme应该可以在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');
我来到这里寻求更多的RFC 4180的合规性,我没有find一个实现,所以我做了一个(可能是低效的)为我自己的需要。 我想我会分享给大家。
var content = [['1st title', '2nd title', '3rd title', 'another title'], ['aa 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
。
来自@Default的解决scheme在Chrome上非常完美(非常感谢!),但IE浏览器遇到问题。
这是一个解决scheme(适用于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")
在Chrome 35更新中,下载属性行为已更改。
https://code.google.com/p/chromium/issues/detail?id=373182
在铬中使用这个,使用这个
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();
你去了:
<!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); link.click(); } </script> </body> </html>
//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
用csv数据创build一个blob .ie var blob = new Blob([data], type:"text/csv");
如果浏览器支持保存blob if window.navigator.mSaveOrOpenBlob)===true
,那么使用以下命令保存csv数据: window.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(); }
ES6的一个箭头function:
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"/*, ...*/]] ) );
如果有人需要这样的反应 , react-csv
就在那里
这里有两个问题:
- 如何将数组转换为csvstring
- 如何将该string保存到文件
第一个问题的所有答案(除了Milimetric之外的)在这里看起来似乎是一个矫枉过正的问题。 而Milimetric的则不包括altrenative的要求,比如用引号或者转换对象数组的方式围绕string。
这是我的这个:
对于一个简单的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')
另一方面,如果你想正确地做,并用引号括起string“”,那么你可以使用一些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, '');
以下是我在Java GWT应用程序中在客户端上下载CSV文件的方式。 特别感谢Xavier John提供的解决scheme。 已经validation在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); } } }-*/; }
这里是一个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)}`); } };
上面的答案工作,但请记住,如果你打开.xls格式,列~~可能会被分隔'\t'
而不是','
,答案https://stackoverflow.com/ a / 14966131/6169225对我来说效果不错,只要我用.join('\t')
而不是.join(',')
。
如果有人需要这个淘汰赛的JS,它基本上可以工作与build议的解决scheme:
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);
我添加到Xavier约翰斯function还包括字段标题,如果需要的话,尽pipe使用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); } } }
这是基于接受的答案的修改答案,其中数据将来自JSON。
JSON Data Ouptut: 0 :{emails: "SAMPLE Co., peter@samplecompany.com"}, 1:{emails: "Another CO. , ronald@another.com"} 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(); });
这里有很多关于将数据转换为CSV的自定义解决scheme,但是几乎所有的解决scheme都会根据数据types进行各种警告,这些数据的types将正确格式化,而不会跳过Excel或类似的内容。
为什么不使用事实certificate: 爸爸parsing
Papa.unparse(data[, config])
那么就把这个和本地的下载解决scheme结合起来吧。 @ArneHB的一个看起来不错。