PHP标题Excel和UTF-8

23
ob_start();

echo 'Désçàui';

header("Content-Type:   application/vnd.ms-excel; charset=utf-8");
header("Content-type:   application/x-msexcel; charset=utf-8");
header("Content-Disposition: attachment; filename=Test.xls"); 
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private",false); 

ob_end_flush();

жҲ‘еңЁExcelж–Ү件дёӯзңӢеҲ°зҡ„жҳҜDГғВ©sГғВ§ГғВ ui

然иҖҢпјҢеҪ“жҲ‘е°қиҜ•ж—¶пјҢжҲ‘еҫ—еҲ°дәҶDГ©sçàui

ob_start();
echo 'Désçàui';
header("Content-Type:   text/html; charset=utf-8");
ob_end_flush();

有没有专家能提供帮助?

PS. 文件是在DW中保存的,标题/编码为Unicode(UTF-8)。


2
一个实体只能有一种内容类型。 - Gumbo
1
我认为为一个甚至不是文本的 MIME 类型提供 charset 属性是没有意义的。 - Álvaro González
2
一个纯文本块何时被认为是Excel文件的一部分了? - Mark Baker
8个回答

28

来源 http://www.mwasif.com/2007/5/download-data-csv-using-php/

解决方案适用于我

Danish Zahur说:

2009年10月7日下午7:23

如果您的内容是UTF-8格式,则无需转换编码。只需要在头部之后以UTF-8 BOM启动文件/输出流即可。

echo pack("CCC",0xef,0xbb,0xbf);

并且头应该包含编码UTF-8

header( "Content-type: application/vnd.ms-excel; charset=UTF-8" );

它会像魅力一样工作,因为Excel将使用BOM字节识别文件字符集。


1
我真的不明白这是怎么运作的!谢谢!! - Tomas Gonzalez
如果我添加了“echo pack”这个东西,字符实际上显示得很好,但所有项目都变成了一个Excel单元格,如果我删除它,字符显示为未知符号,但数组的每个项目都在不同的单元格中,如预期。 - sulaiman
这是目前的工作解决方案(截至2020年)。非常感谢! - Lis

23

我不确定,但可能是 Excel 不能处理 utf8(可能取决于版本)。但它可以处理 utf16,因此尝试转换字符集。 这对我有用(在Excel2002中):

echo mb_convert_encoding('Désçàui','utf-16','utf-8');

echo mb_convert_encoding($r->lastname,'utf-16','utf-8'); - user285594
谢谢您,先生。7年后仍然非常有用。 - b1919676

20
我不知道你是如何生成Excel文件的。但是,如果你是从HTML输出中生成的,你可以在开头添加以下内容:
```html ```
此致,敬礼。

11

这个带有UTF-8 BOM的代码行使我的UTF-8字符正常工作:

 header("Content-type: application/vnd.ms-excel");
 header("Content-Disposition: attachment; filename='".$file_name."'");
 header("Pragma: no-cache");
 header("Expires: 0");
 echo "\xEF\xBB\xBF"; //UTF-8 BOM
 echo $out;

1
这是唯一一个与Excel 2016完美兼容的解决方案。感谢Mladen Janjetovic! - theking2

4

将utf8转换为html实体对我很有用:

$str = 'utf-string ...';
if (mb_detect_encoding($str ) == 'UTF-8') {
   $str = mb_convert_encoding($str , "HTML-ENTITIES", "UTF-8");
}

header('Content-type: application/x-msdownload; charset=utf-16');
header('Content-Disposition: attachment; filename=companies.xls');
header('Pragma: no-cache');
header('Expires: 0');

echo $str ; 

3

content-type头信息仅适用于浏览器,对于下载的文件没有影响。一旦文件被保存,如何处理文件中的数据由应用程序决定。

你展示的例子本身就不是一个有效的Excel文件。当遇到它认为是损坏的文件时,Excel可能会切换到一些默认处理方式,假设使用windows-1252或其他单字节字符集。

你需要提供一个正确的文件给Excel打开。或者,你可以使用旧的“输出HTML但保存为XLS”的技巧,在HTML文件中指定UTF-8编码。


1
你好,能否告诉我如何创建Excel文件吗?谢谢,独角兽。 - Jeremy Roy
2
@Jeremy Roy - 有许多库可以让你从PHP创建真正的Excel文件。就我个人而言,我会推荐使用PHPExcel。 - Mark Baker
1
@Unicorn,您能否提供一个例子来展示那个丑陋但是可行的解决方案吗?我指的是生成一个HTML文件,但将其下载为xls格式。谢谢。 - Mohammad Naji

2

尝试一下这个

<?php
header("Content-Type: application/vnd.ms-excel");
header('Content-Disposition: attachment; filename="sample.xls"');
echo "
    <html xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\" xmlns=\"http://www.w3.org/TR/REC-html40\">
    <html>
        <head><meta http-equiv=\"Content-type\" content=\"text/html;charset=utf-8\" /></head>
        <body>
";

echo "
    <table>
      <tr>
        <th rowspan=\"2\" nowrap=\"nowrap\">เลขที่บัญชี</th>
        <th rowspan=\"2\" nowrap=\"nowrap\">ชื่อ-สกุล ลูกค้า</th>
        <th rowspan=\"2\" nowrap=\"nowrap\">OS/Balance</th>
        <th rowspan=\"2\" nowrap=\"nowrap\">วันที่</th>
        <th rowspan=\"2\" nowrap=\"nowrap\">เวลา</th>
        <th rowspan=\"2\" nowrap=\"nowrap\">Action Code</th>
        <th rowspan=\"2\" nowrap=\"nowrap\">Amount</th>
        <th colspan=\"5\" nowrap=\"nowrap\">ผลการติดตาม</th>
      </tr>
      <tr>
        <th nowrap=\"nowrap\">ที่อยู่บ้าน</th>
        <th nowrap=\"nowrap\">เบอร์โทรบ้าน</th>
        <th nowrap=\"nowrap\">เบอร์โทรมือถือ</th>
        <th nowrap=\"nowrap\">ที่อยู่ที่ทำงาน</th>
        <th nowrap=\"nowrap\">เบอร์โทรที่ทำงาน</th>
      </tr>
      <tr>
        <td>acc</td>
        <td>name</td>
        <td>balance</td>
        <td>date</td>
        <td>time</td>
        <td>code</td>
        <td>amount</td>
        <td>h-addr</td>
        <td>h-tel</td>
        <td>cell</td>
        <td>w-addr</td>
        <td>w-tel</td>
      </tr>
    </table>
";

echo "</body></html>";

?>

你好!如果我添加“echo”\xEF\xBB\xBF”; //UTF-8 BOM”,你的示例对我有效。但是,您知道如何在Excel中制作没有空白间隔的常规表格吗? - mdBender

1

试试这个:

header('Content-Transfer-Encoding: binary');
header("Content-Type: application/octet-stream"); 
header("Content-Transfer-Encoding: binary"); 
header('Expires: '.gmdate('D, d M Y H:i:s').' GMT'); 
header('Content-Disposition: attachment; filename = "Export '.date("Y-m-d").'.xls"'); 
header('Pragma: no-cache'); 

//these characters will make correct encoding to excel 
echo chr(255).chr(254).iconv("UTF-8", "UTF-16LE//IGNORE", $out); 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接