动态生成CSV文件下载时UTF特殊字符显示异常问题咨询
问题原因
- 缺少UTF-8 BOM标记:绝大多数桌面办公软件(尤其是微软Excel)识别UTF-8编码的CSV文件时,需要文件开头有一个特殊的BOM(字节顺序标记)
\ufeff,否则会默认用系统本地编码解析文件,导致特殊字符乱码 - 纯data URI编码局限性:
encodeURI是为URI场景设计的编码规则,直接用来处理文件内容容易出现边界异常,用Blob对象处理二进制文件流兼容性和稳定性更好
修正后的完整代码
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 = ''; // 新增UTF-8 BOM头,解决办公软件编码识别问题 const BOM = '\ufeff'; csvContent += BOM; // headers csvContent += objectToCSVRow(Object.keys(arrayOfObjects[0])); arrayOfObjects.forEach(function(item){ csvContent += objectToCSVRow(item); }); // 改用Blob生成文件流,替代原有的data URI + encodeURI方案 const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' }); const url = URL.createObjectURL(blob); var link = document.createElement("a"); link.setAttribute("href", url); link.setAttribute("download", "customers.csv"); document.body.appendChild(link); // 火狐浏览器必填 link.click(); document.body.removeChild(link); // 释放objectURL占用的内存 URL.revokeObjectURL(url); }
验证
调用测试代码即可正常导出包含特殊字符的CSV,不会出现乱码:
exportToCSV([{spanishChars:"ñé"}])
方案说明
- 完全保留原有代码的对象转CSV行、动态生成表头的逻辑,不需要修改业务侧的调用方式
- 兼容所有主流浏览器和Excel、WPS等办公软件的CSV解析规则
- Blob方案相比原data URI方案,还支持导出更大体积的CSV文件,没有URI长度限制
内容的提问来源于stack exchange,提问作者diCoy
相关产品推荐
相关产品推荐

