Я следил за этим сообщением Как экспортировать информацию о массиве JavaScript в csv (на стороне клиента)?, чтобы получить вложенный массив js, написанный как файл csv.
Массив выглядит так:
var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]];
Код, указанный в ссылке, хорошо работает, за исключением того, что после третьей строки файла csv все остальные значения находятся на одной строке
например.
name1,2,3
name2,4,5
name3,6,7
name4,8,9name5,10,11 и т.д. и т.д.
Может ли кто-нибудь пролить свет на то, почему это? То же самое можно использовать в Chrome или FF.
Спасибо
ИЗМЕНИТЬ
jsfiddle http://jsfiddle.net/iaingallagher/dJKz6/
Иэйн
Ответ 1
Цитированный ответ был неправильным. Вы должны были изменить
csvContent += index < infoArray.length ? dataString+ "\n" : dataString;
в
csvContent += dataString + "\n";
Кстати, приведенный код является неоптимальным. Вы должны избегать многократного добавления к строке. Вместо этого вы должны добавить массив, и в конце сделать array.join("\n"). Как это:
var lineArray = [];
data.forEach(function (infoArray, index) {
var line = infoArray.join(",");
lineArray.push(index == 0 ? "data:text/csv;charset=utf-8," + line : line);
});
var csvContent = lineArray.join("\n");
Что касается того, почему цитируемый ответ был неправильным (забавно, что он был принят!): index
, второй параметр функции обратного вызова forEach
, является индексом в зацикленном массиве, и нет смысла сравнивать его с размером infoArray
, который является элементом указанного массива (который тоже является массивом).
Ответ 2
Общая форма:
var ids = []; <= this is your array/collection
var csv = ids.join(",");
В вашем случае вам придется немного адаптироваться
Ответ 3
Я создал этот код для создания приятных, читаемых файлов csv:
var objectToCSVRow = function(dataObject) {
var dataArray = new Array;
for (var o in dataObject) {
var innerValue = dataObject[o]===null?'':dataObject[o].toString();
var result = innerValue.replace(/"/g, '""');
result = '"' + result + '"';
dataArray.push(result);
}
return dataArray.join(' ') + '\r\n';
}
var exportToCSV = function(arrayOfObjects) {
if (!arrayOfObjects.length) {
return;
}
var csvContent = "data:text/csv;charset=utf-8,";
// headers
csvContent += objectToCSVRow(Object.keys(arrayOfObjects[0]));
arrayOfObjects.forEach(function(item){
csvContent += objectToCSVRow(item);
});
var encodedUri = encodeURI(csvContent);
var link = document.createElement("a");
link.setAttribute("href", encodedUri);
link.setAttribute("download", "customers.csv");
document.body.appendChild(link); // Required for FF
link.click();
document.body.removeChild(link);
}
В вашем случае, поскольку вы используете массивы в массиве вместо объектов в массиве, вы пропустите часть заголовка, но вы можете сами добавить имена столбцов, поставив вместо этой части:
// headers
csvContent += '"Column name 1" "Column name 2" "Column name 3"\n';
Секрет в том, что пространство разделяет столбцы в файле csv, и мы помещаем значения столбца в двойные кавычки, чтобы допускать пробелы, и избегаем любых двойных кавычек в самих значениях.
Также обратите внимание, что я заменяю нулевые значения пустой строкой, потому что это соответствует моим потребностям, но вы можете изменить это и заменить его на что угодно.
Ответ 4
для простого csv достаточно одной map() и join():
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
Этот метод также позволяет вам указать разделитель столбцов, отличный от запятой во внутренней части join
. например, вкладка: 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, '');
Ответ 5
Если ваши данные содержат какие-либо символы новой строки или запятые, вам нужно будет избежать их первого:
const escape = text =>
text.replace(/\\/g, "\\\\")
.replace(/\n/g, "\\n")
.replace(/,/g, "\\,")
escaped_array = test_array.map(fields => fields.map(escape))
Затем просто выполните:
csv = escaped_array.map(fields => fields.join(","))
.join("\n")
Если вы хотите сделать его загружаемым в браузере:
dl = "data:text/csv;charset=utf-8," + csv
window.open(encodeURI(dl))
Ответ 6
Следующий код был написан на ES6, и он будет работать в большинстве браузеров без проблем.
var test_array = [["name1", 2, 3], ["name2", 4, 5], ["name3", 6, 7], ["name4", 8, 9], ["name5", 10, 11]];
// Construct the comma seperated string
// If a column values contains a comma then surround the column value by double quotes
const csv = test_array.map(row => row.map(item => (typeof item === 'string' && item.indexOf(',') >= 0) ? '"${item}"': String(item)).join(',')).join('\n');
// Format the CSV string
const data = encodeURI('data:text/csv;charset=utf-8,' + csv);
// Create a virtual Anchor tag
const link = document.createElement('a');
link.setAttribute('href', data);
link.setAttribute('download', 'export.csv');
// Append the Anchor tag in the actual web page or application
document.body.appendChild(link);
// Trigger the click event of the Anchor link
link.click();
// Remove the Anchor link form the web page or application
document.body.removeChild(link);
Ответ 7
Выбранный ответ, вероятно, правильный, но кажется бесполезным неясным.
Я нашел Shomz Fiddle, чтобы быть очень полезным, но опять же, бесполезно неясно. (Edit: теперь я вижу, что Fiddle основан на OP Fiddle.)
Здесь моя версия (я создал Fiddle для), который, я думаю, более ясен:
function downloadableCSV(rows) {
var content = "data:text/csv;charset=utf-8,";
rows.forEach(function(row, index) {
content += row.join(",") + "\n";
});
return encodeURI(content);
}
var rows = [
["name1", 2, 3],
["name2", 4, 5],
["name3", 6, 7],
["name4", 8, 9],
["name5", 10, 11]
];
$("#download").click(function() {
window.open(downloadableCSV(rows));
});
Ответ 8
const escapeString = item => (typeof item === 'string') ? '"${item}"' : String(item)
const arrayToCsv = (arr, seperator = ';') => arr.map(escapeString).join(seperator)
const rowKeysToCsv = (row, seperator = ';') => arrayToCsv(Object.keys(row))
const rowToCsv = (row, seperator = ';') => arrayToCsv(Object.values(row))
const rowsToCsv = (arr, seperator = ';') => arr.map(row => rowToCsv(row, seperator)).join('\n')
const collectionToCsvWithHeading = (arr, seperator = ';') => '${rowKeysToCsv(arr[0], seperator)}\n${rowsToCsv(arr, seperator)}'
// Usage:
collectionToCsvWithHeading([
{ title: 't', number: 2 },
{ title: 't', number: 1 }
])
// Outputs:
"title";"number"
"t";2
"t";1