PHP导出excel乱码的终极解决大法

今天在使用PHP导出excel或者csv的过程中,发现导出的数据发生乱码情况,在尝试了网上很多的解决办法之后,终于发现了解决办法。


问题出现原因

原来在Windows下用记事本之类的程序将文本文件保存为UTF-8格式时,记事本会在文件头前面加上几个不可见的字符(EF BB BF),就是所谓的BOM(Byte order Mark)。

在utf-8编码文件中BOM在文件头部,占用三个字节,用来标示该文件属于utf-8编码,现在已经有很多软件识别bom头,但是还有些不能识别bom头,比如PHP就不能识别bom头,这也是用记事本编辑utf-8编码后执行就会出错的原因了。

不仅限于 记事本保存的文件,只要在文件的开口包含了EF BB BF 几个不可见的字符(十六进制应该是是xEFxBBxBF,用二进制编辑文件可见)。这像是一个约定俗成的东西,当系统看到这玩意的时候,就会觉得你这个文件是UTF-8编码的。
如果你的接口是UTF-8的,你需要强制下载一个文件,比如csv.excel在默认情况(中文背景)下,认为csv是GB编码的,所以如果米有bom头,那你给用户呈现的文件,可能就是乱码了。


解决办法

知道问题出现的原因了那么问题就很好解决,只需要在生成文件时输出BOM头即可。

以在laravel中导出excel为例

1
2
3
4
5
6
7
8
9
Excel::create($title, function ($excel) use ($data, $type, $rows) {
$excel->sheet('导出excel', function ($sheet) use ($data, $type, $rows) {
$sheet->rows($data);
});

// 设置bom防止中文乱码
echo chr(0xEF) . chr(0xBB) . chr(0xBF);

})->export($type);

至此问题解决,导出的excel或csv可以毫无障碍的浏览量。