在報表導出、數據導入等業務中,Excel 處理是高頻需求。本文基於經典庫 PHPExcel(現已併入 PhpSpreadsheet,建議新項目直接使用後者),演示從模板讀取、數據填充、到瀏覽器下載的完整流程。
<?php
require_once 'vendor/autoload.php'; // Composer 自動加載
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$templateDir = __DIR__ . '/templates/';
$templateName = '1.xlsx';
$outputFileName = '導出報表_' . date('Ymd_His') . '.xlsx';
$fillData = '測試數據'; // 實際業務中來自數據庫查詢等
// 1. 自動識別並讀取模板(支援 .xls / .xlsx)
$reader = IOFactory::createReaderForFile($templateDir . $templateName);
$spreadsheet = $reader->load($templateDir . $templateName);
// 2. 獲取第一個工作表並寫入數據
$sheet = $spreadsheet->getActiveSheet();
// 示例:向 B13 單元格寫入數據(注意編碼轉換視模板而定)
$sheet->setCellValue('B13', $fillData);
// 更多寫入示例
// $sheet->setCellValue('A1', '標題');
// $sheet->fromArray($dataArray, null, 'A2'); // 批量寫入陣列
// 3. 設置下載響應頭
$writer = new Xlsx($spreadsheet);
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="' . urlencode($outputFileName) . '"');
header('Cache-Control: max-age=0');
header('Expires: 0');
// 4. 直接輸出到瀏覽器
$writer->save('php://output');
exit;
?>
IOFactory::createReaderForFile() 會根據文件內容自動判斷是 Xls 還是 Xlsx,無需手動切換 Reader。mb_convert_encoding($str, 'UTF-8', 'GBK')。$writer->setPreCalculateFormulas(false)、使用 ChunkReadFilter 分塊讀寫,或改用 CSV/流式輸出。$spreadsheet->disconnectWorksheets() 釋放循環引用,配合 unset($spreadsheet) 及時回收內存。PHPExcel_* → PhpOffice\PhpSpreadsheet\*composer require phpoffice/phpspreadsheetgetActiveSheet() 替代 getSheet(0))。新項目請直接使用 PhpSpreadsheet,PHPExcel 已停止維護且存在已知安全漏洞(CVE-2018-19277 等)。