如何在 PHP 中输​​出 Excel 可以正确读取的 UTF-8 CSV?

Posted

技术标签:

【中文标题】如何在 PHP 中输​​出 Excel 可以正确读取的 UTF-8 CSV?【英文标题】:How can I output a UTF-8 CSV in PHP that Excel will read properly? 【发布时间】:2011-05-19 22:14:58 【问题描述】:

我有一个非常简单的东西,它只是以 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,但我无法完全弄清楚如何做到这一点。正如你在上面看到的,我只是echoing 这个数据,我没有写任何文件。如果需要,我可以这样做,我只是不是因为在这一点上似乎不需要它。有什么帮助吗?

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

【问题讨论】:

Excel 没有提供调整传入文件字符集的选项?你100%确定吗?我手边没有副本,所以无法尝试,但我想必须在某个地方有一个下拉框。 这是 Mac 上的 Excel - 它似乎比 PC 上的 Excel 更受限制。 “打开”对话框中根本没有下拉菜单,除了可以打开哪些文件类型。我到处都看过。如果它在那里,它是模糊的。我会说 98% 肯定。 微软office还是openoffice? 微软在这方面更好,没有办法(我发现)让 OpenOffice 检测到字符集,甚至没有 BOM。该死的。 BOM 对 Microsoft Excel 2008 for Mac 也没有影响。 【参考方案1】:

我有同样(或类似)的问题。

在我的例子中,如果我在输出中添加一个 BOM,它会起作用:

header('Content-Encoding: UTF-8');
header('Content-type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename=Customers_Export.csv');
echo "\xEF\xBB\xBF"; // UTF-8 BOM

我相信这是一个非常丑陋的 hack,但它对我有用,至少对 Excel 2007 Windows 来说是这样。不确定它是否可以在 Mac 上运行。

【讨论】:

丑陋,但超级有用。谢谢。 不幸的是,我很确定这在 OS X 上根本无法正常工作。我认为它实际上可能会在您导入时显示 BOM(警告:模糊的记忆。) 这是正确的。至少,我尝试过在前面添加 BOM,就像上面的示例一样,但它确实只是在开头显示了一些时髦的字符,并继续显示错误的特殊字符(在 Excel 2011 中测试)。这似乎在所有设置中最适合我:***.com/a/1648671/1005334(使用 php)。 我不断收到关于这个问题的提醒,因为显然很多其他人都偶然发现了这个问题。我希望我可以将其标记为正确,因为它被很多人赞成。不幸的是,我终于试了一下这个解决方案(很久以前就放弃了那个项目),它在 Excel 2008 for Mac 中对我不起作用。很高兴它对你有用。我赞成该解决方案。但它并不能解决 Excel for Mac 2008 的问题。如果有人在 Mac 上运气好,一定要告诉我(显然是每个人)。 我不认为应该使用Content-Encoding 标头来告诉字符集。这与压缩有关:developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…【参考方案2】:

引用a Microsoft support engineer,

Excel for Mac 目前不支持 UTF-8

2017 年更新Office 2016 之前的所有 Microsoft Excel for Mac 版本都是如此。较新的版本(来自 Office 365)现在支持 UTF-8。

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

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

    mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
    

    确保将UTF-16LE byte order mark 添加到文件的开头

    chr(255) . chr(254)
    

仅在 OS X(但 不是 Windows)上的 Excel 中出现的下一个问题是,在查看具有逗号分隔值的 CSV 文件时,Excel 将仅呈现一行,并且所有文本以及第一行中的逗号。

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

我使用了this function from the PHP comments(使用制表符“\t”而不是逗号),它在 OS X 和 Windows Excel 上运行良好。

请注意,要解决以空列作为行尾的问题,我确实必须更改以下代码行:

    $field_cnt = count($fields);

    $field_cnt = count($fields)-1;

正如此页面上的其他一些 cmets 所说,其他电子表格应用程序(例如 OpenOffice Calc、Apple 自己的 Numbers 和 Google Doc 的电子表格)在使用逗号的 UTF-8 文件时没有问题。

请参阅the table in this question,了解哪些适用于 Excel 中的 Unicode CSV 文件,哪些不起作用


作为旁注,我可能会补充一点,如果您使用的是Composer,您应该看看将League\Csv 添加到您的要求中。 League\Csv 有 a really nice API for building CSV files。

要将League\Csv 与这种创建 CSV 文件的方法一起使用,请查看this example

【讨论】:

叫我笨蛋,但我做不到。我使用 mb_convert_encoding 函数转换了我的数据,并在文件内容之前输出了 BOM,但是当我在 Excel 中打开文件时,我只得到一行汉字。我现在仍在使用逗号而不是制表符,但大概这不会导致我所看到的。 此解决方案还为我解决了 Mac 和 Windows 上的 UTF8 问题。我还发现在 CSV 文件中添加带有 sep=;sep=, 的行会告诉 Excel 如何分隔 CSV 并再次正确创建列。 我发现如果我将字符串作为 BOM 开始,然后在另一行添加 "sep=,\n",然后在另一行添加数据,事情就会出现乱码。如果我在一行中完成所有操作($csv = chr(255) . chr(254) /* BOM */ . "sep=,\n" . mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');),一切都很好。现在在 Mac 上一切看起来都很棒。我没有要测试的 Windows。 唯一对我有用的东西。微软的不一致从未停止让我感到惊讶。保存普通的 csv 文件使用“,”作为分隔符,但如果有 BOM,则出于某种原因使用“\t”保存。 .csv 中的 C 代表“COMMA”该死的。真的不难做到。 在我的 Excel Mac 2011 中,将 chr(255).chr(254) 放在文件的开头会将所有字符转换为中文(或韩文,无法真正区分)。唯一对我有用的解决方案是使用 iconv【参考方案3】:

这是我的做法(提示浏览器下载 csv 文件):

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=file.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
echo "\xEF\xBB\xBF"; // UTF-8 BOM
echo $csv_file_content;
exit();

当您在 Mac 上点击空格键时,它修复了 CSV 预览中的 UTF8 编码问题。但在 Excel Mac 2008 中没有...不知道为什么

【讨论】:

UTF-8 BOM 代码行通过导出到 xls 节省了我的时间 我正在寻找一种以 utf8 格式直接输出到浏览器的方法,当我看到这篇文章时,这是我的解决方案,其中包含 BOM 和二进制传输标头的这篇文章。 $outstream = fopen( "php://output", 'w' ); fputs( $outstream, "\xEF\xBB\xBF" ); foreach ( $export as $fields ) fputcsv( $outstream, $fields ); fclose( $outstream ); 错字 - 删除双 ))【参考方案4】:

在我的情况下,以下工作非常好地使带有 UTF-8 字符的 CSV 文件在 Excel 中正确显示。

$out = fopen('php://output', 'w');
fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF));
fputcsv($out, $some_csv_strings);

0xEF 0xBB 0xBF BOM 标头会让 Excel 知道正确的编码。

【讨论】:

为你加油兄弟 fprintf($out, chr(0xEF).chr(0xBB).chr(0xBF)); 谢谢老兄,这个工作得很好,而其他解决方案却没有。【参考方案5】:

我刚刚处理了同样的问题,并提出了两个解决方案。

    使用PHPExcel 类 as suggested by bpeterson76。

    使用此类生成最广泛兼容的文件,我能够从 UTF-8 编码数据生成一个文件,该文件在 Excel 2008 Mac、Excel 2007 Windows 和 Google Docs 中打开良好。 使用 PHPExcel 的最大问题是速度慢且占用大量内存,这对于合理大小的文件来说不是问题,但 如果您的 Excel/CSV 文件有数百或数千行,则此库变得无法使用

    这是一个 PHP 方法,它将获取一些 TSV 数据并将 Excel 文件输出到浏览器,注意它使用 Excel5 Writer,这意味着该文件应该与旧版本的 Excel 兼容,但我不再有权访问对任何人,所以我无法测试它们。

    function excel_export($tsv_data, $filename) 
        $export_data = preg_split("/\n/", $tsv_data);
        foreach($export_data as &$row) 
            $row = preg_split("/\t/", $row);
        
    
        include("includes/PHPExcel.php");
        include('includes/PHPExcel/Writer/Excel5.php');
    
        $objPHPExcel = new PHPExcel();          
    
        $objPHPExcel->setActiveSheetIndex(0);
        $sheet = $objPHPExcel->getActiveSheet();
        $row = '1';
        $col = "A";
        foreach($export_data as $row_cells) 
            if(!is_array($row_cells))  continue; 
                foreach($row_cells as $cell) 
                    $sheet->setCellValue($col.$row, $cell);
                    $col++;
                
            $row += 1;
            $col = "A";
        
    
        $objWriter = new PHPExcel_Writer_Excel5($objPHPExcel);
        header('Content-Type: application/vnd.ms-excel');
        header('Content-Disposition: attachment;filename="'.$filename.'.xls"');
        header('Cache-Control: max-age=0');
        $objWriter->save('php://output');   
        exit;   
    
    

    由于 PHPExcel 的效率问题,我还必须弄清楚如何生成与 UTF-8 和 Excel 兼容的 CSV 或 TSV 文件。

    我能想到的最好的文件是与 Excel 2008 Mac 和 Excel 2007 PC 兼容,但不兼容 Google Docs,这对于我的应用程序来说已经足够了。 我找到了解决方案here,特别是this answer,但您也应该阅读accepted answer,因为它解释了问题。

    这是我使用的 PHP 代码,注意我使用的是 tsv 数据(制表符作为分隔符而不是逗号):

    header ( 'HTTP/1.1 200 OK' );
    header ( 'Date: ' . date ( 'D M j G:i:s T Y' ) );
    header ( 'Last-Modified: ' . date ( 'D M j G:i:s T Y' ) );
    header ( 'Content-Type: application/vnd.ms-excel') ;
    header ( 'Content-Disposition: attachment;filename=export.csv' );
    print chr(255) . chr(254) . mb_convert_encoding($tsv_data, 'UTF-16LE', 'UTF-8');
    exit;
    

【讨论】:

我在 Windows-7 Excel 2007 上面临同样的问题并尝试了所有建议但失败:( UTF-16LE 解决方案是行之有效的解决方案。请注意,您必须正确格式化 tsv,并且它必须是 tsc,所以制表符分隔,而不是逗号分隔。另请参阅 Marc 的帖子:***.com/a/1648671/1697370【参考方案6】:

我遇到了同样的问题,解决方法如下:

    header('Content-Encoding: UTF-8');
    header('Content-Type: text/csv; charset=utf-8' );
    header(sprintf( 'Content-Disposition: attachment; filename=my-csv-%s.csv', date( 'dmY-His' ) ) );
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');

    $df = fopen( 'php://output', 'w' );

    //This line is important:
    fputs( $df, "\xEF\xBB\xBF" ); // UTF-8 BOM !!!!!

    foreach ( $rows as $row ) 
        fputcsv( $df, $row );
    
    fclose($df);
    exit();

【讨论】:

【参考方案7】:

Excel 不支持 UTF-8。您必须将 UTF-8 文本编码为 UCS-2LE。

mb_convert_encoding($output, 'UCS-2LE', 'UTF-8');

【讨论】:

最好使用上面建议的 UTF-16LE,它涵盖了存在的每个字符。 我注意到这个 mb_convert_encoding 工作正常,并在我导出的 XLS 文件中正确显示变音符号。我有 mysql 默认配置和 apache + php 设置为使用 utf-8【参考方案8】:

对此进行跟进:

看来问题出在 Mac 上的 Excel 上。这不是我生成文件的方式,因为即使 从 Excel 生成 CSV 也会破坏它们。我另存为CSV,重新导入,所有字符都乱了。

所以……似乎没有正确的答案。谢谢大家的建议。

我想说,就我所读到的所有内容而言,@Daniel Magliola 关于 BOM 的建议可能是其他计算机的最佳答案。但它仍然没有解决我的问题。

【讨论】:

由于 UTF8 支持在 Mac 和 Windows 之间不一致,最好的办法是完全使用不同的编码。我发现 cp1252 通常与 Microsoft 的东西配合得很好。 en.wikipedia.org/wiki/Windows-1252 本,这个问题有一个正确的答案:)看我的!【参考方案9】:

这在 Excel 中适用于 Windows 和 Mac OS。

修复 Excel 中不显示包含变音符号、西里尔字母、希腊字母和货币符号的字符的问题。

function writeCSV($filename, $headings, $data)    

    //Use tab as field separator
    $newTab  = "\t";
    $newLine  = "\n";

    $fputcsv  =  count($headings) ? '"'. implode('"'.$newTab.'"', $headings).'"'.$newLine : '';

    // Loop over the * to export
    if (! empty($data)) 
      foreach($data as $item) 
        $fputcsv .= '"'. implode('"'.$newTab.'"', $item).'"'.$newLine;
      
    

    //Convert CSV to UTF-16
    $encoded_csv = mb_convert_encoding($fputcsv, 'UTF-16LE', 'UTF-8');

    // Output CSV-specific headers
    header('Set-Cookie: fileDownload=true; path=/'); //This cookie is needed in order to trigger the success window.
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
    header("Content-Transfer-Encoding: binary");
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/excel

    exit;

【讨论】:

这个解决方案让我也可以为 Google 表格导出工作(其他一些失败) 这个解决方案几乎是完美的,我刚刚发现一个单元格包含双引号时的一个问题 " ,它被跳过了..【参考方案10】:

CSV 文件必须包含字节顺序标记。

或者按照建议和解决方法,只需使用 HTTP 正文回显它

【讨论】:

【参考方案11】:

添加:

fprintf($file, chr(0xEF).chr(0xBB).chr(0xBF));

或者:

fprintf($file, "\xEF\xBB\xBF");

在将任何内容写入 CSV 文件之前。

例子:

<?php
$file = fopen( "file.csv", "w");
fprintf( $file, "\xEF\xBB\xBF");
fputcsv( $file, ["english", 122, "বাংলা"]);
fclose($file);

【讨论】:

【参考方案12】:

不需要使用mb_convert_encoding 转换已经编码为utf-8 的文本。只需在原内容前面加上三个字符:

$newContent = chr(239) . chr(187) . chr(191) . $originalContent

对我来说,这解决了 csv 文件中特殊字符的问题。

【讨论】:

难以置信;我尝试了至少 10 种其他解决方案,当通过 fputs 与 UTF-8 BOM 结合使用时,对我来说唯一的解决方案似乎是这个。 这些字符是什么?一定是什么魔法咒语。在这里尝试了所有其他答案后,唯一对我有用的解决方案。 这些字符组合起来称为“字节对象标记”,它告诉应用程序检查它的其余内容应该被视为 UTF-8。【参考方案13】:

因为 UTF8 编码不能很好地与 Excel 配合使用。您可以使用iconv() 将数据转换为另一种编码类型。

例如

iconv('UTF-8', 'ISO-8859-1//TRANSLIT', $value),

【讨论】:

这是唯一适用于 Excel Mac 2011 的解决方案【参考方案14】:
**This is 100% works fine in excel for both Windows7,8,10 and also All Mac OS.**
//Fix issues in excel that are not displaying characters containing diacritics, cyrillic letters, Greek letter and currency symbols.

function generateCSVFile($filename, $headings, $data) 

    //Use tab as field separator
    $newTab  = "\t";
    $newLine  = "\n";

    $fputcsv  =  count($headings) ? '"'. implode('"'.$newTab.'"', $headings).'"'.$newLine : '';

    // Loop over the * to export
    if (! empty($data)) 
      foreach($data as $item) 
        $fputcsv .= '"'. implode('"'.$newTab.'"', $item).'"'.$newLine;
      
    

    //Convert CSV to UTF-16
    $encoded_csv = mb_convert_encoding($fputcsv, 'UTF-16LE', 'UTF-8');

    // Output CSV-specific headers
    header('Set-Cookie: fileDownload=true; path=/'); //This cookie is needed in order to trigger the success window.
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: private",false);
    header("Content-Type: application/octet-stream");
    header("Content-Disposition: attachment; filename=\"$filename.csv\";" );
    header("Content-Transfer-Encoding: binary");
    header('Content-Length: '. strlen($encoded_csv));
    echo chr(255) . chr(254) . $encoded_csv; //php array convert to csv/excel
    exit;

【讨论】:

一般来说,如果答案包含对代码的用途的解释,以及为什么在不介绍其他人的情况下解决问题的原因,答案会更有帮助。【参考方案15】:

您可以使用 iconv 转换您的 CSV 字符串。 例如:

$csvString = "Möckmühl;in Möckmühl ist die Hölle los\n";
file_put_contents('path/newTest.csv',iconv("UTF-8", "ISO-8859-1//TRANSLIT",$csvString) );

【讨论】:

很棒的示例文本 ;)【参考方案16】:

我调查后发现 UTF-8 在 MAC 和 Windows 上运行不佳,所以我尝试使用 Windows-1252 ,它对它们都支持良好,但您必须在 ubuntu 上选择编码类型。 这是我的代码$valueToWrite = mb_convert_encoding($value, 'Windows-1252');

$response->headers->set('Content-Type', $mime . '; charset=Windows-1252');
    $response->headers->set('Pragma', 'public');
    $response->headers->set('Content-Endcoding','Windows-1252');
    $response->headers->set('Cache-Control', 'maxage=1');
    $response->headers->set('Content-Disposition', $dispositionHeader);
    echo "\xEF\xBB\xBF"; // UTF-8 BOM

【讨论】:

【参考方案17】:

您必须使用编码“Windows-1252”。

header('Content-Encoding: Windows-1252');
header('Content-type: text/csv; charset=Windows-1252');
header("Content-Disposition: attachment; filename=$filename");

也许你必须转换你的字符串:

private function convertToWindowsCharset($string) 
  $encoding = mb_detect_encoding($string);

  return iconv($encoding, "Windows-1252", $string);

【讨论】:

【参考方案18】:

您可以在导出之前将 3 个字节附加到文件中,它适用于我。在做之前那个系统只能在 Windows 和 HP -UX 中运行,但在 Linux 中失败了。

FileOutputStream fStream = new FileOutputStream( f );
final byte[] bom = new byte[]  (byte) 0xEF, (byte) 0xBB, (byte) 0xBF ;
OutputStreamWriter writer = new OutputStreamWriter( fStream, "UTF8" );
fStream.write( bom );

在文件开头有一个 UTF-8 BOM(3 个字节,十六进制 EF BB BF)。否则 Excel 将根据您的语言环境的默认编码(例如 cp1252)而不是 utf-8 来解释数据

Generating CSV file for Excel, how to have a newline inside a value

【讨论】:

【参考方案19】:

我在 Mac 上,在我的情况下,我只需要使用 "sep=;\n" 指定分隔符并像这样以 UTF-16LE 编码文件:

$data = "sep=;\n" .mb_convert_encoding($data, 'UTF-16LE', 'UTF-8');

【讨论】:

【参考方案20】:

对我来说,上述解决方案均无效。以下是我为解决问题所做的工作: 在 PHP 代码中使用此函数修改值:

$value = utf8_encode($value);

此输出值在 Excel 工作表中正确输出。

【讨论】:

【参考方案21】:

当我有一个导入数据的 Excel VBA 例程时,我遇到了同样的问题。由于 CSV 是纯文本格式,因此我通过编程方式在写字板等简单文件编辑器中打开数据,然后将其重新保存为 unicode 文本,或者从那里将其复制到剪贴板并将其粘贴到 Excel 中来解决这个问题。如果 excel 没有自动将 CSV 解析为单元格,则可以使用内置的“文本到列”功能轻松解决。

【讨论】:

我试过了!但它已经编码为 un​​icode 文本……将其保存为 unicode 文本不会改变任何内容。如果不正确解释所有特殊字符,我如何将其保存为纯文本? 我认为“将其保存为 Unicode 文本”,Alain 可能意味着“UTF-16LE”。 Windows 经常(遗憾地)使用“Unicode”来错误地引用带有前导 BOM 的 UTF-16LE 或 UTF-16LE。记事本的文件 -> 保存对话框以这种方式使用“Unicode”。【参考方案22】:

当您将其保存为 .txt 文件并在 Excel 中以逗号作为分隔符打开该文件时,问题是否仍然存在?

问题可能根本不是编码问题,可能只是根据 excel 标准,文件不是完美的 CSV。

【讨论】:

据我所知,CSV 格式没问题。我可以在 TextEdit 中制作“完美”的 CSV,没问题,甚至可以将 txt 重命名为 csv,因此它不会遗漏任何秘密 - CSV 只是文本文件。此外,Excel 中的格式都是完美的,只是特殊字符会中断。但以防万一,我尝试了你的建议,但遗憾的是它产生了同样的问题。 来自“他们在想什么”部门:请注意,根据 Microsoft 的说法,正确的字段分隔符取决于区域设置。一个“逗号分隔”的文件可能需要在某些语言环境中以分号分隔字段 - 除了建议 OpenOffice 之外,您无能为力 这太疯狂了 - 不幸的是,我在正确划分字段时没有遇到问题。我只是遇到了这些特殊字符的问题。【参考方案23】:

我刚刚尝试了这些标题,并在 Windows 7 PC 上安装了 Excel 2013,以正确导入带有特殊字符的 CSV 文件。字节顺序标记 (BOM) 是使它工作的最后一个关键。

header('内容编码:UTF-8'); header('内容类型: text/csv; charset=UTF-8'); header("内容配置:附件;文件名=文件名.csv"); header("Pragma: public"); header("过期时间:0"); 回声“\xEF\xBB\xBF”; // UTF-8 物料清单

【讨论】:

是的,没错,它可以在 Excel for Windows 中正常工作,但正如我的回答中所解释的,它不适用于 Excel for OS X。【参考方案24】:

适用于 Mac Excel 2008 的简单解决方案: 我为此挣扎了很多次,但这是我的简单解决方法: 在 Textwrangler 中打开 .csv 文件,该文件应正确打开您的 UTF-8 字符。现在在底部状态栏中将文件格式从“Unicode (UTF-8)”更改为“Western (ISO Latin 1)”并保存文件。 现在转到您的 Mac Excel 2008 并选择 File > Import > Select csv > Find your file > 在 File origin 中选择“Windows (ANSI)”,瞧,UTF-8 字符显示正确。至少对我有用...

【讨论】:

【参考方案25】:

我用了这个,效果很好

header('Content-Description: File Transfer');
header('Content-Type: text/csv; charset=UTF-16LE');
header('Content-Disposition: attachment; filename=file.csv');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
// output headers so that the file is downloaded rather than displayed
// create a file pointer connected to the output stream
$output = fopen('php://output', 'w');
fputs( $output, "\xEF\xBB\xBF" );
// output the column headings
fputcsv($output, array('Thông tin khách hàng đăng ký'));
// fetch the data
$setutf8 = "SET NAMES utf8";
$q = $conn->query($setutf8);
$setutf8c = "SET character_set_results = 'utf8', character_set_client =
'utf8', character_set_connection = 'utf8', character_set_database = 'utf8',
character_set_server = 'utf8'";
$qc = $conn->query($setutf8c);
$setutf9 = "SET CHARACTER SET utf8";
$q1 = $conn->query($setutf9);
$setutf7 = "SET COLLATION_CONNECTION = 'utf8_general_ci'";
$q2 = $conn->query($setutf7);
$sql = "SELECT id, name, email FROM myguests";
$rows = $conn->query($sql);
$arr1= array();
if ($rows->num_rows > 0) 
// output data of each row
while($row = $rows->fetch_assoc()) 
    $rcontent = " Name: " . $row["name"]. " - Email: " . $row["email"];  
    $arr1[]["title"] =  $rcontent;

 else 
     echo "0 results";

$conn->close();
// loop over the rows, outputting them
foreach($arr1 as $result1):
   fputcsv($output, $result1);
endforeach;

【讨论】:

以上是关于如何在 PHP 中输​​出 Excel 可以正确读取的 UTF-8 CSV?的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中输​​出图像

如何制作表格excel

如何在 C++ 中将数据读/写到 excel 2007 中?

在 HTML 文件中导出 PHP 表

excel 公式中包含带公式的单元格,如何正确引用

PHP在本地的数据库中导入EXCEL,一个编号字段假如是97875118326745.导入进去之后,变成了97875118326E+12