當前位置: 首頁> 最新文章列表> 用header() 模擬下載CSV 報表的場景

用header() 模擬下載CSV 報表的場景

M66 2025-05-18

在Web 開發中,有時我們需要通過後端動態生成一個CSV 報表,並提供給用戶下載,而不是事先生成好一個文件放在服務器上供下載。 PHP 的header()函數可以用來修改HTTP 響應頭,配合輸出內容,就能實現這種“模擬下載”的效果。

本文將帶你一步步實現這個功能。

步驟1:準備CSV 數據

首先,我們需要有一份要輸出的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'],
];

步驟2:設置HTTP 頭部

使用header()函數告訴瀏覽器這是一個文件下載響應,而不是普通的網頁輸出。特別重要的是:

  • Content-Type告訴瀏覽器這是CSV 文件;

  • Content-Disposition設置附件形式,提供下載文件的名字;

  • Cache-ControlPragma幫助避免緩存問題。

 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');

步驟3:輸出CSV 內容

可以用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);

注意事項

  1. 不要有多餘輸出<br> 在調用header()前,不能有任何多餘的輸出(包括空格、換行、BOM),否則會導致“Headers already sent”錯誤

  2. 編碼問題<br> 如果生成的CSV 包含中文字符,最好用UTF-8 BOM 或轉換為GBK,避免在Excel 中打開出現亂碼

  3. 動態數據<br> 上例用的是靜態數組,實際項目中往往需要從數據庫中查詢,再拼成數組