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();

What I'm getting in the excel file is Désçàui

However, I do get Désçàui when I try

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

Any help experts?

PS. The file is saved in DW with Title/Encoding Unicode(Utf-8).

3
  • 2
    An entity can only have one content type. Commented Mar 20, 2011 at 11:57
  • 1
    I don't think it makes sense to provide a charset attribute for a MIME type that's not even text. Commented Mar 20, 2011 at 13:03
  • 2
    Since when was a block of plain text considered an Excel file? Commented Mar 20, 2011 at 16:56

8 Answers 8

28

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

Solution worked for me

Danish Zahur said,

October 7, 2009 @ 7:23 pm

If your contents are in UTF-8 format, then no need to convert encoding. Just start your file/output stream with UTF-8 BOM after headers.

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

And header should contain encoding UTF-8

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

It will work like charm because Excel will recognize file charset with BOM bytes.

Sign up to request clarification or add additional context in comments.

3 Comments

I can't understand how this REALLY WORKED! Thanks!!
if I add the "echo pack" thing the characters actually displayed good, but all the items becomes in one excel cell, if I removed this, the character displayed like unknown symbols, but each item of the array is in different cell as excpected
this is currently the working solution (as of 2020). Thank you a lot!
23

I'm not sure, but it may be that excel can not handle utf8(may depend on the version). But it can handle utf16, so try converting the charset. This works for me(in excel2002):

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

2 Comments

echo mb_convert_encoding($r->lastname,'utf-16','utf-8');
Thank you, sir. Still useful more than 7 years later.
20

I don't know how you're generating the excel file. But, if you're doing it from an HTML output, you can just add the following at the begining:

<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8" />

Regards

Comments

11

This UTF-8 BOM line of code made my UTF-8 chars work fine:

 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 Comment

This is the one solution that works like a breeze with Excel 2016. Thanks Mladen Janjetovic!
4

Converting utf8 to html-entities worked quite nicely for me :

$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 ; 

Comments

3

The content-type headers are relevant for the browser only. They have no effect on downloaded files. Once the file is saved, it is up to the application to decide how it treats the data in the file.

The example you show is not a valid Excel file in the first place. When encountering what it must think is a broken file, Excel probably switches to some default processing that assumes windows-1252 or some other single-byte character set.

You would have to give Excel a proper file to open. Alternatively, it may be possible to use the old "Output HTML but save as XLS" trick and specify a UTF-8 encoding in that HTML file.

3 Comments

Hi, could you please tell how do you create excel file? Thanks Unicorn.
@Jeremy Roy - There are a number of libraries that allow you to create real Excel files from PHP. Personally, I'd recommend PHPExcel
@Unicorn Would you please link an example with that ugly (but working) solution? I'm talking about generating an HTML file but downloading it as xls. Thank you
2

try this

<?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>";

?>

1 Comment

Hi! Your example works for me if I add - "echo "\xEF\xBB\xBF"; //UTF-8 BOM" then it works great. But do you know hot to make usual table in excel without empty space ?
1

Try this:

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); 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.