CSV文件乱码问题解析:BOM标记与UTF-8编码的重要性
什么是CSV文件?

逗号分隔值(英文名:Comma Separator Value)常被用于数据转换的中间文件。例如,可以将 Mysql 中的数据导出到 CSV 中。在 web 系统中时常会有导出报表数据的需求,同时也会用到 csv 格式。使用 utf-8 编码来导出 CSV 文件时,打开后其中的中文会变成乱码(在 Windows 下,CSV 文件默认与 Microsoft Excel 关联),而用文本编辑器打开则是正常的,但排版较为混乱。原因在于缺少 BOM,这是微软多此一举的行为。
什么是BOM?
Byte Order Mark 是一种头部结构,它是由微软所定义的。
Microsoft 建议所有的 Unicode 文件要识别的话,应该以 ZERO WIDTH NOBREAK SPACE 字符开头。它被当作一个“特征符”或者“字节顺序标记(byte-order mark,BOM)”,用以识别文件中所使用的编码以及字节顺序(big-endian 或者 little-endian),其具体的对应关系可参照下表。
Bytes Encoding Form
UTF-32 编码,大端序,十六进制表示为 00 00 FE FF
FF FE 00 00 为 UTF-32 编码格式,且采用小端序。
FE FF UTF-16, big-endian
FF FE UTF-16, little-endian
EF BB BF UTF-8
类 Unix 系统没有使用 BOM。因为使用 BOM 会对现有的 ASCII 文件的语法约定造成破坏。
我们在使用 PHP 导出 csv 文件时,若仅使用 file_put_contents 或者 fwrite 来写入表格数据。而我们生成 csv 的平台不一定遵循微软的 bom 协议,这样就会导致,若输出非 unicode 编码的 csv 文件(像 utf-8 这种),并且没有生成 bom 信息,那么 Excel 会自动按照 unicode 编码进行读取,从而出现乱码问题。而没有写入BOM头信息,就会出现打开中文乱码的情况。
PHP中文乱码解决
Excel 在读取 csv 时,会通过读取文件头上的 bom 来对编码进行识别。倘若文件头不存在 bom 信息,那么就会默认按照 unicode 编码来读取。
如果要使用 utf-8 格式,那么需要确保 php 源码是 utf-8 的。我们可以在第一行写入与 utf-8 对应的 BOM 信息。
代码如下:
$bom 等于使用 pack 函数以 'CCC' 的格式打包三个字节,分别是 0xef、0xbb 和 0xbf;这与上面的情况相对应。
将字符串 $bom 写入到文件 pythontab.csv 中,并且是以追加的方式进行写入。
使用 file_put_contents 函数将 $someData 写入到 'pythontab.csv' 文件中,且采用 FILE_APPEND 模式进行追加写入,即写入你希望写入表格的数据。
前后都省略了部分代码,仅写出了最为关键的部分,其余部分请大家自行进行补充。
这样生成的csv就不会出现中文乱码问题啦。
注意:写入的BOM头信息要和文件的编码对应。