php 網站點選生成csv檔案,解決亂碼問題
阿新 • • 發佈:2018-12-23
2012-01-10
abloz.com
周海漢 2012.1.10
先上一首詩:
鋤禾日當午,春運訂票苦 。 95105,一撥一上午。 撥了一上午,車票還沒譜。 過年回不回,心裡很痛苦。 為何會這樣,只能問政府。 作者:白交易
慶賀多路出擊終於買到了2012春運火車票,雖然是硬坐票,多年未擠火車了,這次要甩開膀子幹了:)
php點選,從資料庫生成csv格式的檔案供下載,有兩個問題:
1.中文檔名,在不同的瀏覽器下可能出現亂碼
2.內容的亂碼問題
重要建議,對部署在linux上,採用utf8編碼的資料庫和php檔案,直接將內容轉為gbk,可以用mb_convert_encoding或者iconv,這樣省很多麻煩。不要轉為utf16le格式的csv,否則還是容易遇到問題。utf8格式的csv有嗎?沒有。所以在windows上的csv格式,只有用gbk內容最簡單。
有一個fputcsv函式,可以將array轉成以逗號分隔的內容。header()函式可以讓瀏覽器生成可以下載的csv檔案。
<span style="font-family: Courier New;"> function query_to_csv($query, $filename="", $attachment = true, $headers = true)
{
if( empty( $filename ) )
{
$filename = "abloz_com_".date("Ymd").".csv";
}
header('Cache-control: private');
if($attachment) {
// send response headers to the browser
//判斷瀏覽器,輸出雙位元組檔名不亂碼
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+","%20",$encoded_filename );
$fp = fopen('php://output', 'w');
$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''' . $filename . '"');
}
else {
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
//if(function_exists('mb_convert_encoding')){
//header('Content-type: text/csv; charset=UTF-16LE');
header( 'Content-Type: text/csv' );
<span style="font-family: Courier New;"> } else {
$fp = fopen($filename, 'w');
}
$result = mysql_query($query, $this->conn) or die( mysql_error( $this->conn ) );
if($headers) {
// output header row (if at least one row exists)
$row = mysql_fetch_assoc($result);
if($row) {
$row = array_map("utf8togbk",array_keys($row));
fputcsv($fp,$row );//,mb_convert_encoding(',',"UTF-16LE","UTF-8")
// reset pointer back to beginning
mysql_data_seek($result, 0);
}
}
while($row = mysql_fetch_assoc($result)) {
$row = array_map("utf8togbk",$row);
fputcsv($fp, $row);//,mb_convert_encoding(',',"UTF-16LE","UTF-8")
}
fclose($fp);
}
<span style="font-family: Courier New;">function utf8togbk($elem)
{
return mb_convert_encoding($elem,"GBK","UTF-8");//"auto" = "ASCII,JIS,UTF-8,EUC-JP,SJIS".
}</span></span></span>
如果轉為utf16-le格式,還要寫bom,而且就算內容轉成功,fputcsv函式生成的分隔符“,”還是ansi的,開啟還是亂碼。除非自己寫一個直接生成csv格式的函式。
為了防止麻煩,就用utf8格式了。
對於下載時檔名亂碼問題,根據瀏覽器,提供不同的header,進行解決:
<span style="font-family: Courier New;"> //判斷瀏覽器,輸出雙位元組檔名不亂碼
$encoded_filename = urlencode($filename);
$encoded_filename = str_replace("+","%20",$encoded_filename );
$fp = fopen('php://output', 'w');
$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''' . $filename . '"');
}
else {
header('Content-Disposition: attachment; filename="' . $filename . '"');
}
</span>
對ie和firefox進行特殊處理。
query_to_csv是一個db類的成員函式,所以connection直接用了成員變數。如果是獨立函式,可以將conn做成全域性或引數傳入。
用法:
<span style="font-family: Courier New;"> require_once 'mydb_code.php';
$db = new mydb();</span>
<span style="font-family: Courier New;"> $sql = "SELECT * FROM users";
</span><span style="font-family: Courier New;">// output as a csv attachment
$db->query_to_csv($sql, "周海漢.csv");</span>
如非註明轉載, 均為原創. 本站遵循知識共享CC協議,轉載請註明來源
