Как из JS сгенерить CSV файл для MS Excel?

Как сформировать CSV файл, который нормально отроется в Excel? Средствами JS.

Волнует кодировка кириллического текста и разделитель столбцов, который, как я понял, каждый себе устанавливает по настроению (региональным настройкам) в Windows.

Для сохранения файла прямо со страницы пользуюсь FileSaver.js.

Например, есть данные в две колонки:
var data = [
  [123,"первая строка вторая колонка в кириллице"],
  [456,"вторая строка"]
];
data = data.map(function(el){ return [el[0], '"' + el[1] + '"'].join(',') + "\r\n"; });
saveAs( new Blob( data, {type : 'text/csv'}), 'data.csv' );


Fiddle — при нажатии на кнопку предолжит сохранить CSV файл – он нормально открывается в Google Spreadsheets и Preview на Mac OS X видит это как нормальную таблицу:
195df0f5c6df41daac231ea03db03037.png
А на Windows Excel открывает в один столбец с битой кодировкой:
9cb53a9b716f4d22a2e581a586d1578e.jpg
Как формировать данные посетителям под Windows?
  • Вопрос задан
  • 7834 просмотра
Пригласить эксперта
Ответы на вопрос 3
@vylegzhanin
Замените это
saveAs( new Blob( rows, {type : 'text/csv'}), 'data.csv' );

на это
saveAs( new Blob( rows, {type : 'text/csv;charset=utf-8'}), 'data.csv' );
Ответ написан
@SunSpire
Чтобы избавиться от "битых" символов в сохранённом CSV-файле, следует вручную перекодировать кириллицу, и сохранить исходные данные в бинарный массив. Вот JS-функция, которую я использую для генерирования лабораторных отчетов в формате CSV:

// перехватываем событие message и вызываем нужную нам функцию
(function(p) {
    window.alert = function() {
        sData = arguments[0];       
        download(sData) 
    };
})(window.alert);

// функция скачивания файла на жесткий диск
function download(data) {                
         
         // делаем перекодировку кириллических символов
         var uint8 = new Uint8Array(data.length);
         for(var i = 0; i < data.length; i++) {
             x = data.charCodeAt(i);
             if (x >= 1040 && x <= 1103) { // Символы А..Я а..я
                 x -= 848;
             } else if (x == 1025) {   // Символ Ё
                 x = 168;
             } else if (x == 1105) {   // Символ ё
                 x = 184;
             }
             uint8[i] = x;
         }

         // имя сохраняемого файла
         filename = "lab_report.csv"     
    
         // сохраняем файл (в качестве данных - массив)
         var file = new Blob([uint8], {type: 'text/csv'});    

         if (window.navigator.msSaveOrOpenBlob) // IE10+
             window.navigator.msSaveOrOpenBlob(file, filename);
         else { // Others
             var a = document.createElement("a"),
                     url = URL.createObjectURL(file);
             a.href = url;
             a.download = filename;
             document.body.appendChild(a);
             a.click();
             setTimeout(function() {
                 document.body.removeChild(a);
                 window.URL.revokeObjectURL(url);  
         }, 0); 
    }
}
Ответ написан
abyrkov
@abyrkov
JavaScripter
Попробуйте прогнать этим конвертером - stackoverflow.com/questions/2696481/encoding-conve...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы