瀏覽器根據 HTTP Header 的 Content-Type 和 Content-Disposition 決定如何處理響應。設置為 application/vnd.ms-excel 並指定文件名,瀏覽器將彈出下載對話框,用 Excel 打開 CSV 文件。
<?php
class ReportFormAction extends CommonAction {
public function index() {
if (!IS_POST) { $this->display(); return; }
// 1. 構建查詢條件
$where = ['status' => 1];
$order = 'creative_id DESC';
// ... 根據 $_POST 動態拼接 $where、$order ...
// 2. 查詢數據
$lists = M('creative')->where($where)->order($order)->select();
if (empty($lists)) { $this->error('無數據導出'); return; }
// 3. 設置 Header
$filename = date('Ymd_His') . '_creative_report.csv';
header('Content-Type: application/vnd.ms-excel; charset=UTF-8');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Pragma: no-cache');
header('Expires: 0');
// 4. 輸出 CSV 內容
$out = fopen('php://output', 'w');
// 寫入 BOM 防止 Excel 打開 UTF-8 CSV 亂碼
fwrite($out, chr(0xEF).chr(0xBB).chr(0xBF));
// 表頭
$header = ['分類','創意ID','創意類型','創意標簽','創意標題','創意描述','評論數','收藏數','投票數','提交人','作者'];
fputcsv($out, $header);
// 數據行
foreach ($lists as $v) {
$typeMap = [1=>'問題', 2=>'解決方式', 3=>'新創意'];
$row = [
$v['two_status'] ? '標准創意' : '一句話創意',
$v['creative_id'],
$v['sort_name'],
$typeMap[$v['creative_type']] ?? '',
$v['creative_name'],
$v['creative_description'],
$v['comment_num'],
$v['collect_num'],
$v['vote_num'],
$v['submitter'],
$v['author'],
];
fputcsv($out, $row);
}
fclose($out);
exit;
}
}
Excel 打開 CSV 時默認按系統編碼(中文 Windows 為 GBK)解析。輸出 UTF-8 時**必須寫入 BOM (EF BB BF)**,否則中文會亂碼。或使用 mb_convert_encoding 轉 GBK 輸出(不需 BOM)。
fputcsv 會自動處理字段中的雙引號、逗號、換行符(雙引號包裹、雙引號轉義為兩個雙引號),比手動拼接字符串安全得多。
若數據超過 10 萬行,建議:
LIMIT 分頁查詢,循環寫入輸出流。set_time_limit(0) 和 ini_set('memory_limit', '256M')。ob_end_clean() 避免內存堆積。CSV 不支持多工作表、字體顏色、合併儲存格。如需真正 Excel (.xlsx) 功能,請使用 PhpSpreadsheet:
composer require phpoffice/phpspreadsheet
// 然後用 PhpSpreadsheet 生成 .xlsx 並輸出
Content-Disposition 中文件名需 RFC 5987 編碼:filename*=UTF-8'' . rawurlencode($filename),並兼容舊瀏覽器提供 filename 參數。window.location.href = '/export?params...' 或 ``。fputcsv 自動換行轉義,確保用 Excel 打開而非文本編輯器查看。Header + fputcsv 是導出 CSV 最輕量、高效、兼容性最好的方案。注意 BOM、編碼、大數據分批、文件名編碼四個關鍵點,即可滿足 90% 的導出需求。