Чтобы избавиться от "битых" символов в сохранённом 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);
}
}