在Web 開發中,有時我們需要通過後端動態生成一個CSV 報表,並提供給用戶下載,而不是事先生成好一個文件放在服務器上供下載。 PHP 的header()函數可以用來修改HTTP 響應頭,配合輸出內容,就能實現這種“模擬下載”的效果。
本文將帶你一步步實現這個功能。
首先,我們需要有一份要輸出的CSV 數據。可以是從數據庫提取出來的,也可以是手工準備的數組。
$data = [
['姓名', '郵箱', '註冊時間'],
['張三', 'zhangsan@m66.net', '2025-05-01 10:00:00'],
['李四', 'lisi@m66.net', '2025-05-02 11:30:00'],
['王五', 'wangwu@m66.net', '2025-05-03 14:15:00'],
];
使用header()函數告訴瀏覽器這是一個文件下載響應,而不是普通的網頁輸出。特別重要的是:
Content-Type告訴瀏覽器這是CSV 文件;
Content-Disposition設置附件形式,提供下載文件的名字;
Cache-Control和Pragma幫助避免緩存問題。
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="report.csv"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
可以用fopen('php://output', 'w')將內容直接寫入輸出流,不需要生成中間文件。
$output = fopen('php://output', 'w');
foreach ($data as $row) {
fputcsv($output, $row);
}
fclose($output);
<?php
$data = [
['姓名', '郵箱', '註冊時間'],
['張三', 'zhangsan@m66.net', '2025-05-01 10:00:00'],
['李四', 'lisi@m66.net', '2025-05-02 11:30:00'],
['王五', 'wangwu@m66.net', '2025-05-03 14:15:00'],
];
header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="report.csv"');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
$output = fopen('php://output', 'w');
foreach ($data as $row) {
fputcsv($output, $row);
}
fclose($output);
不要有多餘輸出<br> 在調用header()前,不能有任何多餘的輸出(包括空格、換行、BOM),否則會導致“Headers already sent”錯誤
編碼問題<br> 如果生成的CSV 包含中文字符,最好用UTF-8 BOM 或轉換為GBK,避免在Excel 中打開出現亂碼
動態數據<br> 上例用的是靜態數組,實際項目中往往需要從數據庫中查詢,再拼成數組