我在导出带有中文字符的UTF-8 CSV上已经困了好几天,这些字符在Windows Excel上显示乱码文字。我正在使用PHP,并且已经添加了BOM字节标记并尝试了编码,但根本没有运气。
他们在Notepad ++,Google Spreadsheet甚至Mac Numbers上都可以正常使用。但不是Excel,这是客户的要求。使用Notepad ++打开时,编码显示为UTF-8。如果我手动将其更改为UTF-8并保存,则Excel上的文件打开正常。
似乎BOM字节标记没有保存在输出中,因为Notepad ++始终将其检测为没有BOM的UTF-8。
此外,CSV未保存在服务器上。数据从数据库中检索,然后直接导出。
以下是我的代码:
// Setup headers
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Content-Description: File Transfer');
header("Content-type: text/csv");
header("Content-disposition: filename=".$filename.".csv");
header("Pragma: no-cache");
// First Method
$fp = fopen('php://output', 'w');
// Add BOM to fix UTF-8 in Excel, but doesn't work
fputs($fp, chr(0xEF) . chr(0xBB) . chr(0xBF) );
if ($fp) {
fputcsv($fp, array("Header"), ",");
fputcsv($fp, array($string_with_chinese_chars), ",");
}
fclose($fp);
exit();
// Second Method
$csv = "";
$sep = ",";
$newline = "\n"; // Also tried with PHP_EOL
$csv .= "Header";
$csv .= $newline;
$csv .= $string_with_chinese_chars;
$csv .= $newline;
// Tried all the below ways but doesn't work.
// Method 2.1
print chr(255) . chr(254) . mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8');
// Method 2.2
print chr(239) . chr(187) . chr(191) . $csv;
// Method 2.3
print chr(0xEF).chr(0xBB).chr(0xBF);
print $newline;
print $csv;
答案 0 :(得分:1)
根据您上面的评论,您的脚本看起来像是在UTF-8 BOM之前意外打印出换行符(十六进制0A
),导致Excel无法将输出识别为UTF-8。
由于您使用的是PHP,请确保脚本中的<?php
标记之前没有空行,或者可能包含的任何其他PHP文件中没有空行。还要确保在结束?>
标记之后,您包含的任何文件都没有任何空格(如果有)。
在实践中,这可能很难做到,因为许多文本编辑都坚持总是在最后一行的末尾添加换行符。因此,最安全和最简单的解决方案就是简单地leave out the ?>
marker from your PHP files,除非你打算打印出它后面的内容。 PHP不需要?>
存在,并且在不打算混合的文件中使用PHP和文字模板HTML(或其他文本)只是要求这样的错误。
答案 1 :(得分:1)
以下代码对我有用。在CSV内容之前输出utf-8-bom字符:
echo "\xEF\xBB\xBF"; // utf-8 bom
echo $csv;
答案 2 :(得分:0)
我通常这样做:
header('Content-Type: application/csv');
header('Content-Disposition: attachment; filename="filename.csv"');
header('Cache-Control: max-age=0');
// BOM header UTF-8
echo "\xEF\xBB\xBF";
$fh = @fopen('php://output', 'w');
...
我使用";"
作为分隔符,因为excel大多数不会自动形成","
答案 3 :(得分:0)
希望这可以帮助某人。 对我有用的是我必须把两个都放:
...
echo chr(0xEF) . chr(0xBB) . chr(0xBF);
$file = fopen('php://output', 'w');
fputs($file, chr(0xEF) . chr(0xBB) . chr(0xBF));
...
我不是PHP方面的专家,所以我无法解释为什么这样做有效,我希望这对某人有帮助,因为我也很难解决此问题。