導讀:數據統計導出、批量導入是後台管理常見需求。CSV 格式通用性強、無 Excel 專有格式依賴。本文系統講解 PHP 讀取、寫入 CSV 核心函數
fgetcsv/fputcsv用法,並實現瀏覽器直接下載 CSV/Excel 功能。
| 函數 | 用途 | 關鍵參數 |
|---|---|---|
fgetcsv($handle, $length, $delimiter, $enclosure, $escape) | 按行讀取 CSV 並解析為陣列 | 分隔符 (預設 `,`)、包裹字符 (預設 `"`)、轉義字符 (預設 `\`) |
fputcsv($handle, $fields, $delimiter, $enclosure, $escape) | 將陣列格式化為 CSV 行寫入 | 同上,自動處理包含分隔符/換行的字段 |
<?php
$file = fopen('data/products.csv', 'r');
if (!$file) die('文件打開失敗');
$header = fgetcsv($file); // 讀取標題行
$products = [];
while (($row = fgetcsv($file)) !== false) {
// 結合標題生成關聯陣列
$product = array_combine($header, $row);
// 數據驗證、類型轉換...
$products[] = $product;
}
fclose($file);
// 處理業務邏輯
foreach ($products as $p) {
// Product::create($p);
}
echo "成功導入 " . count($products) . " 條記錄";
<?php
$fp = fopen('exports/report_' . date('Ymd') . '.csv', 'w');
// 寫入 BOM 防止 Excel 打開中文亂碼
fwrite($fp, chr(0xEF).chr(0xBB).chr(0xBF));
// 標題行
fputcsv($fp, ['訂單號', '用戶', '金額', '下單時間', '狀態']);
// 數據行 (模擬循環)
$orders = [
['202401001', '張三', 299.00, '2024-01-15 10:30', '已付款'],
['202401002', '李四', 599.50, '2024-01-15 11:00', '待發貨'],
];
foreach ($orders as $order) {
fputcsv($fp, $order);
}
fclose($fp);
echo "報表生成完成";
<?php
// 設置響應頭
header('Content-Type: text/csv; charset=UTF-8');
header('Content-Disposition: attachment; filename="users_' . date('Ymd_His') . '.csv"');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
header('Pragma: public');
// 直接輸出到輸出緩衝區
$out = fopen('php://output', 'w');
// UTF-8 BOM
fwrite($out, chr(0xEF).chr(0xBB).chr(0xBF));
// 標題
fputcsv($out, ['ID', '用戶名', '郵箱', '註冊時間']);
// 模擬數據庫查詢分批輸出 (避免大數據集佔用記憶體)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
$stmt = $pdo->query('SELECT id, username, email, created_at FROM users');
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
fputcsv($out, $row);
}
fclose($out);
exit;
舊版 Excel 對 CSV 支援有限,常用 Tab 分隔 + `.xls` 後綴欺騙瀏覽器。
<?php
header('Content-Type: application/vnd.ms-excel; charset=UTF-8');
header('Content-Disposition: attachment; filename="report_' . date('Ymd') . '.xls"');
$out = fopen('php://output', 'w');
fwrite($out, chr(0xEF).chr(0xBB).chr(0xBF));
// 使用 \t 作為分隔符
fputcsv($out, ['ID', '姓名', '部門'], "\t");
fputcsv($out, [1, '張三', '技術部'], "\t");
fputcsv($out, [2, '李四', '市場部'], "\t");
fclose($out);
EF BB BF),否則中文亂碼。或轉為 GBK/UTF-16LE。php://output 流式輸出 + 分批查詢 (LIMIT/OFFSET 或游標)。fputcsv 會自動用包裹字符 (預設 `"`) 包裹並轉義內部引號,讀取時 fgetcsv 自動逆向解析。