新項目,大概情況是這樣的:可能存在多國、不同語種使用者,比喻有中文、繁體中文,韓文、日本等等,開發時選擇了UTF-8編碼,開發順利,沒有問題。昨天做了一個csv導出功能,導出的東西完全亂了:
設置mb_convert_encoding($content,"gb2312","UTF-8")的時候中文正常
設置mb_convert_encoding($content,"shift-jis","UTF-8")的時候日文正常
設置mb_convert_encoding($content,"UTF-8","UTF-8")的時候,都不正常
google了一下原因,我理解的大概意思是微軟的csv等不支持uft-8編碼,而是支持UTF-16LE編碼,故做以下設置
//輸出BOM
echo(chr(255).chr(254));
echo(mb_convert_encoding($content,"UTF-16LE","UTF-8"));
各種語言正常顯示
以下是完整function,支持雙字節文件名(比如日文或中文文件名)不亂碼
<?php
/**
*導出到CSV文件
* @param $data 導出數組
* @param $file_name 文件名
*/
function export_csv($data,$file_name='')
{
$file_name = $file_name.'_'.date('YmdHi').'.csv';
$encoded_filename = urlencode($file_name);
$encoded_filename = str_replace("+","%20",$encoded_filename );
$content = array_to_string($data);
header('Cache-control: private');
//判斷瀏覽器,輸出雙字節文件名不亂碼
$ua = $_SERVER["HTTP_USER_AGENT"];
if (preg_match("/MSIE/", $ua)) {
header('Content-Disposition: attachment; filename="' . $encoded_filename . '"');
}
else if (preg_match("/Firefox/", $ua)) {
header('Content-Disposition: attachment; filename*="utf8\'\'' . $file_name . '"');
}
else {
header('Content-Disposition: attachment; filename="' . $file_name . '"');
}
if(function_exists('mb_convert_encoding')){
header('Content-type: text/csv; charset=UTF-16LE');
//輸出BOM
echo(chr(255).chr(254));
echo(mb_convert_encoding($content,"UTF-16LE","UTF-8"));
exit;
}
}
/**
*導出數據轉換
* @param $result
*/
function array_to_string($result)
{
if(empty($result)){
return i("沒有符合您要求的數據!^_^");
}
$size_result = count($result);
for($i = 0 ; $i < $size_result ; $i++) {
$data .= $result[$i]."\n";
}
return $data;
}
?>