Php 在mac上转换为excel制作的utf-8 csv文件的问题

Php 在mac上转换为excel制作的utf-8 csv文件的问题,php,excel,csv,Php,Excel,Csv,我对编码有点生疏。 我有一个php文件,允许用户上传csv文件 我的问题是,当使用excel for mac创建文件时,如果文件包含utf-8字符(如重音字母),我的代码将无法正常工作。基本上,它将忽略重音字符 仅当使用逗号分隔值选项保存文件时,才会出现此问题 在所有其他情况下,例如在windows中创建文件或在mac上使用open office甚至excel,但将其保存为“windows”文件不会导致任何问题 mb_detect_encoding为导致问题的文件返回false 代码如下: //

我对编码有点生疏。 我有一个php文件,允许用户上传csv文件

我的问题是,当使用excel for mac创建文件时,如果文件包含utf-8字符(如重音字母),我的代码将无法正常工作。基本上,它将忽略重音字符

仅当使用
逗号分隔值
选项保存文件时,才会出现此问题

在所有其他情况下,例如在windows中创建文件或在mac上使用open office甚至excel,但将其保存为“windows”文件不会导致任何问题

mb_detect_encoding
为导致问题的文件返回false

代码如下:

// say there is the word Nestlé in the file
$content = file_get_contents(addslashes($file_name));

var_dump(mb_detect_encoding($content)); // print false


$data  = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
            //$data  = utf8_encode($content);  //doesn't work

var_dump($data); // print Nestl

ini_set('auto_detect_line_endings',TRUE);

// more code here we don't need at the moment
这个问题给了我一些启示:

关于如何解决这个问题有什么帮助或想法吗?先谢谢你

以下是Anthony发布的回复后的新代码

$content = file_get_contents(addslashes($file_name));
// i have no control on how the file is generated so i need to to the replace in the code
$content = str_replace(",", "\t",  $content);
var_dump($content);
$data  = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));


$data =  mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');
$data = chr(255) . chr(254) . $data;

var_dump($data); // this still print funny characters not the accented letter

我做错什么了吗?

这是Excel特有的问题,在Excel for Mac上更常见,因为在Mac上,UTF-8多字节字符没有正确显示。您可以使用不同的电子表格查看器(如Google Sheets)进行确认

解决方法是:

  • 使用制表符(
    \t
    )而不是逗号作为分隔符(别担心,从技术上讲,它仍然是CSV)

  • 编码为utf-8后,将整个csv字符串转换为utf-16LE:

    mb_convert_编码($csv_内容,'UTF-16LE','UTF-8')

  • 在csv字符串前面加一个小的尾端字节顺序标记(LE BOM):

    $csv\u content=chr(255)。chr(254)$csv_内容


  • 这应该就可以了。

    好吧,谢谢你,安东尼,下面这句话可以解决这个问题:

    $data = iconv('macintosh', 'UTF-8', $content);
    
    因此,我的最终代码将如下所示:

    enter code here
    
    $content = file_get_contents(addslashes($file_name));
    
    var_dump(mb_detect_encoding($content));
    // need to do this for an issue specific to Excel and more common on Excel for Mac
    // using excel on mac if the file is saved as csv using the Comma separated values option we need to use iconv and not mb_convert_encoding
    // we use mb_detect_encoding because the content of such file returns a false value
    if(!mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true)){
         //$data  = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', 'macintosh', true));
    
          $data = iconv('macintosh', 'UTF-8', $content);
    
    
     } 
        // deal with known encoding types
     else{
             $data  = mb_convert_encoding($content, 'UTF-8', mb_detect_encoding($content, 'UTF-8, ISO-8859-1', true));
     }
    

    这是osx上excel的已知问题,即缺少对csv文件的Unicode支持。有一个解决办法,我会在几分钟后发布。你没有做错另一件事,而是excel@Anthony这对我来说将是一个很好的生日礼物:)看我的编辑,我无法让你的变通方法工作,你能在我的代码中发现任何错误吗?也许是我把utf-8转换成utf-8的那条线路不起作用了,我把你的问题倒过来了。我的解决方案是输出一个可以在Mac上运行Excel的csv,而不是导入。给我几分钟看看这个解决方案是否能反过来工作。嗯,我用你的例子雀巢创建了一个测试csv。这看起来像是使用Mac OS Roman编码的,这需要
    iconv
    转换为utf-8:我猜Mac OS Roman代码块(likeé)中的字符是使用该字符集编码的,但如果字符不在该字符集中(如日语字符),则可能使用utf-16或其他编码。因此,您应该使用
    mb\u detect\u编码
    ,如果返回为false,则假设它是Mac OS Roman。这就是我刚刚完成的工作!非常感谢你帮了我的忙!