问题概述
如今的AUT导出csv文件的功能已经相当的常见,而打开文件后内容显示为乱码的现象也着实屡见不鲜,即便编码时候特意指定了码表为UTF-8,如下所示。
public void exportCSV(){
OutputStreamWriter fwriter = new OutputStreamWriter(
new FileOutputStream(new File("csv/export.csv")), "UTF-8");
ICsvBeanWriter writer = new CsvBeanWriter(fwriter,
CsvPreference.EXCEL_PREFERENCE);
…
}
既然指定了码表,为何用 Excel 打开 UTF-8 编码的 CSV 文件后,内容依然会是乱码呢?究其原因,竟是Excel本身默认会以 ANSI 格式打开,不做编码识别。
规避手段
对于这种情况,我们可以采用最简洁的规避手段。
1. 打开 Excel
2. 选中DATA -> From Text
3. 选择UTF-8编码的CSV文件,出现文本导入向导Import
4. 选择Delimited -> Next
5. 勾选Comma,去掉Tab -> Next
6. 最后点击确定完成
说它最简介,是因为不需要dev改动任何一处代码,即可达到目的。然而这终究只能称之为一个workaround,而非solution
解决方案
为了彻底解决该问题,我们需要引入一个叫做BOM的东西,关于其定义,wiki如是说——
字节顺序标记(英语:byte-order mark,BOM)是位于码点U+FEFF的统一码字符的名称。当以UTF-16或UTF-32来将UCS/统一码字符所组成的字符串编码时,这个字符被用来标示其字节序。它常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的记号。
修改代码,在导出CSV文件时,引入includeBOM,再次查验CSV文件内容,这下大家应该可以彻底跟乱码说bye bye了吧!
// Include the byte order mark (BOM) for UTF-8 encoding.
private function includeBOM(value:String):ByteArray {
var byteArray:ByteArray = new ByteArray();
byteArray.writeByte(0xEF);
byteArray.writeByte(0xBB);
byteArray.writeByte(0xBF);
byteArray.writeUTFBytes(value);
return byteArray;
}