我有一个非常简单的东西,只输出一些CSV格式的东西,但它必须是UTF-8.我在TextEdit、TextMate或Dreamweaver中打开这个文件,它会正确显示UTF-8字符,但如果我在Excel中打开它,它会做这种愚蠢的事情.以下是我文件开头的内容:

header("content-type:application/csv;charset=UTF-8");
header("Content-Disposition:attachment;filename=\"CHS.csv\"");

这一切似乎都有想要的效果,除了Excel(Mac,2008)不想正确地导入它.在EXCEL中没有选项可供我"以UTf-8格式打开"或其他格式,所以…我有点烦了.

我似乎在任何地方都找不到任何明确的解决方案,尽管很多人都有同样的问题.我看到的最多的事情是包含BOM,但我不能确切地想出如何做到这一点.正如你在上面看到的,我只是echo个数据,我没有写任何文件.如果我需要的话,我可以这么做,我只是不是因为在这一点上看起来不需要这样做.有什么帮助吗?

更新:我试着将BOM表回复为echo pack("CCC", 0xef, 0xbb, 0xbf);,这是我刚从一个试图检测BOM的网站上提取的.但Excel在导入时只是将这三个字符附加到第一个单元格中,仍然会弄乱特殊字符.

推荐答案

引用a Microsoft support engineer

Excel for Mac目前不支持UTF-8

Update, 2017:这适用于Office 2016之前的所有版本的Microsoft Excel for Mac.较新版本(来自Office 365)现在确实支持UTF-8.

为了输出Windows和OS X上Excel都能成功读取的UTF-8内容,您需要做两件事:

  1. 确保将UTF-8 CSV文本转换为UTF-16LE

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    
  2. 确保将UTF-16LE byte order mark添加到文件的开头

    chr(255) . chr(254)
    

下一个仅在OS X(但not Windows)上使用Excel出现的问题是,当查看带有逗号分隔值的CSV文件时,Excel将只呈现一行,所有文本以及第一行中的逗号.

避免这种情况的方法是使用制表符作为分隔值.

我使用了this function from the PHP comments(使用制表符"\t"而不是逗号),它在OS X和Windows Excel上运行得非常好.

请注意,要解决一个以空列作为行尾的问题,我必须更改代码行,该行表示:

    $field_cnt = count($fields);

    $field_cnt = count($fields)-1;

正如本页面上的其他一些 comments 所说,其他Electron 表格应用程序,如OpenOffice Calc、苹果自己的数字和Google Doc的Electron 表格,对带有逗号的UTF-8文件没有问题.

请参阅the table in this question,了解Excel中Unicode CSV文件的适用和不适用之处


As a side note, I might add that if you are using Composer, you should have a look at adding League\Csv 到 your requires. League\Csv has a really nice API for building CSV files.

要使用League\Csv创建CSV文件,请查看this example

Php相关问答推荐

Laravel 11 api资源PUT请求模型没有查询结果

用户信息更新期间Laravel邮箱验证问题

管理员订单列表中的自定义列与WooCommerce 8.6.1一起消失

WordPress:将自定义单选输入字段添加到用户配置文件

MariaDB 11.3.2+PHP:服务器向客户端发送未知的字符集(0).请向开发人员报告

如何在不指定symfony列的情况下从数据库中获取行数组

将一个情态形式放在细丝v3中的形式中间

laravel中获取的数据会自动更改时间戳值

隐藏WooCommerce管理子菜单;主页;来自store 经理

$this->;db->;update();CodIgnitor中的功能不工作

wp_insert_post() 和 WordPress 中查询字符串的多个帖子

PHP 解析 XML 以获取多个深度的所有字符串值

通过ajax发送数据到下拉列表未完全设置为所选

使用 Laravel 和 Vue 进行图像表单验证

如何将文件上传添加到 WooCommerce 结帐?

从 Laravel 机制中排除目录并直接访问该目录

Laravel:ArgumentCountError: 函数 App\Mail 的参数太少

显示时间范围内的可用空位,同时考虑已预订的空位

使用 Eloquent 更新现有的外键值

为什么 ECDSA 384 签名验证在 GO 中失败,但在 PHP 中却没有?