背景
在使用Java代码生成csv文件时,使用Notepad++/Sublime Text之类的文本编辑器打开是没有问题的,但是可视化效果不好,故而考虑使用Excel打开,可是却出现乱码问题。
概述
BOM,Byte Order Mark,字节顺序标记,一种文件头部协议,存储在文件头部,用于标识文件编码。
如果使用UTF-8编码生成CSV文件,会发现CSV文件虽然可以用记事本打开,但是用Excel打开就会出现乱码。
原理:Excel在读取csv时是通过读取文件头上的bom来识别编码的,如果文件头无bom信息,则默认按照unicode编码读取。(bom是微软定义的一种文件头部协定,存储在文件头部,存储内容就是标识文件编码的信息。)而生成csv的平台不一定遵循微软的bom协议,导致如果输出非unicode编码的csv文件(如utf-8),并且没有生成bom信息的话,Excel自动按照unicode编码读取,就会出现乱码问题。解决:只需将非unicode编码的csv文件,用文本编辑器(Notepad++)打开并转换为带bom的编码形式(具体编码方式随意),问题解决。
问题
每次都是手动去修改并转换编码,那不是很傻么?既然CSV是程序生成的,那怎么用程序解决这个乱码问题?
Java
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(Files.newOutputStream(tempFile.toPath(),
StandardOpenOption.APPEND), StandardCharsets.UTF_8));
// fix
bw.write(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
bw.write();
bw.newLine();
bw.flush();
bw.close();
Python
import csv
# utf-8-sig
csv_file = open("writer.csv", "w+", newline = '', encoding = 'utf-8-sig')
writer = csv.writer(csv_file )
writer.writerow(text)