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協議,轉載請註明來源