Как экспортировать информацию из массива JavaScript в CSV (на стороне клиента)?
Я знаю, что существует множество вопросов на эту тему, но мне нужно сделать это с использованием JavaScript. Я использую Dojo 1.8
и у меня есть вся информация об атрибутах в массиве, который выглядит следующим образом:
[["name1", "city_name1", ...], ["name2", "city_name2", ...]]
Кто-нибудь знает, как я могу экспортировать это в CSV
на стороне клиента?
5 ответ(ов)
На основе ответов выше я разработал функцию для экспорта в CSV, которую протестировал в 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) { // проверка поддержки
// Браузеры, поддерживающие атрибут download в HTML5
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);
}
}
}
Пример использования можно найти здесь.
Эта функция создает CSV-файл из массива строк. Обратите внимание на обработку значений, включая корректное экранирование кавычек и форматирование дат. Это должно работать в большинстве современных браузеров, а также в Internet Explorer 10 и выше.
Это решение должно работать с Internet Explorer 10+, Edge, старыми и новыми версиями Chrome, Firefox, Safari и др.
Принятый ответ не будет работать в IE и Safari.
Вот пример кода для создания и загрузки CSV-файла:
// Пример данных, указанных в тексте вопроса
var data = [
['name1', 'city1', 'some other info'],
['name2', 'city2', 'more info']
];
// Формируем CSV из двумерного массива данных
// Каждая колонка разделяется ";" и новая строка "\n" для следующей строки
var csvContent = '';
data.forEach(function(infoArray, index) {
dataString = infoArray.join(';');
csvContent += index < data.length ? dataString + '\n' : dataString;
});
// Функция загрузки принимает строку CSV, имя файла и mimeType в качестве параметров
// Прокрутите вниз в этом фрагменте кода, чтобы увидеть, как вызывается загрузка
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); // поддерживается только этот MIME-тип
}
}
download(csvContent, 'download.csv', 'text/csv;encoding:utf-8');
Запуск этого фрагмента кода загрузит mock-данные в формате CSV.
Кредиты dandavis https://stackoverflow.com/a/16377813/1350598
В обновлении Chrome 35 было изменено поведение атрибута download
. Чтобы это заработало в Chrome, используйте следующий код:
var pom = document.createElement('a');
var csvContent = csv; // здесь мы загружаем наши данные CSV
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();
Этот код создает временную ссылку, генерирует объект Blob
с данными CSV, и позволяет пользователю скачать файл под указанным именем 'foo.csv'.
Решение от @Default отлично работает в Chrome (большое спасибо за него!), но у меня возникла проблема с Internet Explorer.
Вот решение, которое работает в IE10:
var csvContent = data; // здесь мы загружаем наши данные CSV
var blob = new Blob([csvContent], {
type: "text/csv;charset=utf-8;"
});
navigator.msSaveBlob(blob, "filename.csv");
Это позволяет создать и скачать CSV-файл в Internet Explorer.
Ваш код работает в Chrome и IE. Я изучил много ответов на эту тему, протестировал это решение в обоих браузерах и оно действительно работает. Вкратце объясню, что делает ваш код:
- Создаётся элемент
<a>
, который будет использоваться для скачивания файла. - Происходит проверка на поддержку атрибута
download
для современных браузеров (таких как Chrome). Если поддержка есть, создаётсяBlob
с содержимым CSV и ссылка на этотBlob
устанавливается какhref
элемента<a>
. - Для Internet Explorer 10 и выше используется
msSaveBlob
, чтобы обеспечить возможность скачивания. - Элемент
<a>
добавляется в документ, выполняется клик по нему для скачивания, и затем он удаляется из документа.
Это решение довольно универсально для работы с CSV-файлами в разных браузерах. Если у вас будут дополнительные вопросы или потребуется помощь, не стесняйтесь спрашивать!
Как программно выполнять навигацию с помощью React Router?
Как условно добавлять атрибуты к компонентам React?
В чем разница между React Native и React?
Как преобразовать строку, разделённую запятыми, в массив?
Когда использовать JSX.Element, ReactNode и ReactElement?