前情提要:
公司需要搞一个产新品信息导出 包括产品详情 但是产品详情里面包含了不少的csv分隔符,;
原本只需要按照正常步骤将内容用双引号""包裹起来即可,但是在后续的测试中
导出后使用microsoft excel打开文件时产品详情依旧出现了分隔符导致的错位
也就是我们不愿意看到的胡乱分行分列。
这里做一个小笔记,防止以后忘记
PHP生成csv
1 设置header头
header("Content-type: text/csv; charset=utf-8"); //定义输出的文件类型csv,编码为utf-8 header("Content-Disposition:attachment;filename={$file_name}"); //设置附件下载,“生成文件名称”=自定义 header("Content-Description:File Transfer"); //只是File Transfer无具体意义 header('Content-Type:text/comma-separated-values;charset=UTF-8'); //确保csv文件文本以逗号分隔符分隔 header('Cache-Control:must-revalidate,post-check=0,pre-check=0'); //及时更新缓存 header('Expires:0'); //设置缓存已过期 header('Pragma:public'); //缓存所有信息 header('content-transfer-encoding:binary'); //不区分编码,接收传输的任何数据
2 针对中文以及mac os打开utf8出现乱码问题
添加BOM头
print(chr(0xEF).chr(0xBB).chr(0xBF))
tips: 来源 德问社区 董琛 的回答
为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE字符开头。
这作为一个”特征符”或”字节顺序标记(byte-order mark,BOM)”来识别文件中使用的编码和字节顺序(big-endian或little-endian),
具体的对应关系见下表。
Bytes Encoding Form
00 00 FE FF UTF-32, big-endian
FF FE 00 00 UTF-32, little-endian
FE FF UTF-16, big-endian
FF FE UTF-16, little-endian
EF BB BF UTF-8
以UTF-8无BOM格式编码,因此要想导出Microsoft Excel可以正常显示的UTF-8的CSV文件,需要显式的输出BOM
3 针对大文本分隔符导致的错位
csv是一个根据分隔符区分的一个文本,本身针对某一格是没有容量的说法的
但是当我们使用excel打开csv时,excel的某一格是有容量限制的
据我目前得到的结果大约为32000个字符左右,因此在输出大文本的时候需要将大文本进行切割
每一格的容量为32000即可有效避免出现 明明已经处理了每一格但是是还是有文本出现了换行换列的情况
tips: 这里贴上php的处理
//使用mb_strlen获取正确的字符数
$len = mb_strlen ($description);
//这里使用mb函数,如果是含有中文就使用mb_substr函数,不然截取会不正确 $description_p1 = mb_strcut($description, 0, 32000); $description_p2 = mb_strcut($description, 31999, 32000);