解决导出带有汉字的csv格式文件在英文操作系统下,汉字显示为问号的问题
前言
公司承接的一个二次开发伪cms项目(下简称:管理器)中有一个客户需要的导出数据功能。项目在长时间的运营后,数据越来越多,导出一万条数据需要近5分钟,现使用空余时间尝试缩短数据导出时间。
优化数据库查询
管理器中的数据导出功能是先从数据库中获取数据,再使用PHPExcel库生成xls文件。
进行数据库查询优化后(添加索引,使用连表查询,简化sql),数据库查询时间缩短到0.3秒内。再次进行数据导出,发现导出时间依然将近5分钟。
优化导出excel为csv
在分段输出程序运行时间后,确定了是PHPExcel库生成xls文件占用了大量时间。
通过网上搜索后发现php使用PHPExcel库生成xls文件慢是通病,很多人建议直接拼接字符串导出csv以代替使用PHPExcel库。
将导出格式改为csv后速度的确是大大提高,不到1秒数据导出就完成了。
编码格式问题
本地测试通过后,提交升级的第一天,客户就发现问题了,在我们公司内打开没问题的csv。到他们电脑上打开,所有汉字均变成问号?
,和客户沟通后发现,原来是他们的office的默认语言是英文。但是由于客户公司内部规定,不能随意更改。
通过添加文件头解决
在把本地电脑里excel的语言也设置为默认英语后,问题能够重现了。
不使用iconv
对汉字内容转码的情况下,导出数据csv默认的编码方式是UTF-8
,在经过多方测试后,发现只要把csv文件的编码方式设置为UTF-8-BOM
,也就是为UTF-8
多加了一个文件头,两个文件在十六进制编码下进行对比差异如下。
两下对比,多出的文件头是ef bb bf
,这是Unicode签名BOM(Byte Order Mark),网上有很多关于BOM的介绍,这里不细究。
于是在程序输出csv时,在文件的开头处加上这个BOM,英文版excel就能正确读取带有汉字的csv了。
总结
一些外企内部有规定必须使用英文版操作系统甚至office的默认语言也必须是英文,这就导致了没有内置编码方式设置的csv在非汉语环境下打开产生汉字变问号的问题。
在制作导出数据功能时,假如需要导出带汉字的csv文件,最好加上文件头,这样无论excel的默认语言是什么,只要系统内置了汉语文字编码,就能够正常显示汉字。