PHP 產生 CSV 檔案供下載是常見需求。本文涵蓋資料組裝、數值欄位防止科學記號/前導零消失、UTF-8 轉 Big5/GB2312 相容 Excel、正確 HTTP 標頭輸出的完整流程。
\"\t 強制文字格式Excel 開啟 CSV 時會自動將純數字轉為數值型別,導致前導零消失(如 00001 變 1)、長數字轉科學記號。解法:在每欄值前加上 \"\t(雙引號 + 製表符),Excel 會視為文字格式保留原貌。
<?php
// 假設 $lists 為資料庫查詢結果陣列
$lists = $this->dbo->query($sql);
$exportdata = '規則ID,規則名稱,匹配等級,規則動作,服務類型,關鍵字1,關鍵字2,關鍵字3,匹配字符,設置時間,有效期' . "\n";
$date = date("YmdHis");
if (!empty($lists)) {
foreach ($lists as $key => $value) {
$time = date("Y-m-d H:i:s", $value['add_time']);
// 每欄前加 "\t" 強制文字格式,欄位間用逗號分隔,換行用 \n
$exportdata .= "\"\t" . $value['Rule_id'] . "\","
. "\"\t" . $value['Rule_name'] . "\","
. "\"\t" . $value['Matching_level'] . "\","
. "\"\t" . $value['Rule_action'] . "\","
. "\"\t" . $value['Service_type'] . "\","
. "\"\t" . $value['Keyword1'] . "\","
. "\"\t" . $value['Keyword2'] . "\","
. "\"\t" . $value['Keyword3'] . "\","
. "\"\t" . $value['Matching_word'] . "\","
. "\"\t" . $value['Set_time'] . "\","
. "\"\t" . $value['Validation_time'] . "\"\n";
}
}
$filename = "plcnetinfo_{$date}.csv";
// HTTP 下載標頭
header("Content-Type: application/vnd.ms-excel; charset=utf-8");
header("Content-Disposition: attachment; filename=\"{$filename}\"");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Pragma: public");
// 輸出前轉碼:Excel 相容性較好用 GB2312/Big5,UTF-8 需帶 BOM
echo mb_convert_encoding($exportdata, "GB2312", "UTF-8");
?>
| 環節 | 做法 | 說明 |
|---|---|---|
| 數值保真 | \"\t{$val}\" | 雙引號包裹 + 前置製表符,Excel 強制辨識為文字 |
| 欄位分隔 | 逗號 , | CSV 標準,含逗號的欄位已被雙引號包裹 |
| 換行 | \n | Unix 換行,Excel 可識別;Windows 可用 \r\n |
| 編碼轉換 | mb_convert_encoding($data, 'GB2312', 'UTF-8') | 中文 Excel 相容性最佳;UTF-8 需輸出 BOM (chr(239).chr(187).chr(191)) |
| 檔名編碼 | filename*=UTF-8''{urlencode($filename)} | RFC 5987 格式,解決中文檔名亂碼(現代瀏覽器支援) |
fputcsv():內建函數自動處理逗號、引號跳脫,效能優於字串拼接;ob_flush()、flush() 避免記憶體耗盡;echo "\xEF\xBB\xBF"; 寫入 BOM;str_replace('"', '""', $val));$fp = fopen('php://output', 'w');
// 寫入 BOM (UTF-8)
fwrite($fp, "\xEF\xBB\xBF");
// 寫入標題
fputcsv($fp, ['規則ID','規則名稱','匹配等級','規則動作','服務類型','關鍵字1','關鍵字2','關鍵字3','匹配字符','設置時間','有效期']);
foreach ($lists as $row) {
// 前置 \t 強制文字
$data = array_map(function($v) { return "\t" . $v; }, [
$row['Rule_id'], $row['Rule_name'], $row['Matching_level'],
$row['Rule_action'], $row['Service_type'], $row['Keyword1'],
$row['Keyword2'], $row['Keyword3'], $row['Matching_word'],
$row['Set_time'], $row['Validation_time']
]);
fputcsv($fp, $data);
}
fclose($fp);
掌握 CSV 匯出細節,能生成 Excel 完美開啟、資料零失真的報表檔案。