注意: PHPExcel 專案已於 2017 年停止維護,官方建議遷移至 PhpSpreadsheet。本文保留 PHPExcel 範例供維護舊專案參考,新專案請直接採用 PhpSpreadsheet,API 高度相容。
php_zip, php_xml, php_gd2(圖片處理)composer require phpoffice/phpspreadsheet(新專案)<?php
require 'vendor/autoload.php'; // Composer 自動載入
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Color;
function export_xls(array $data, array $title, string $filename = 'report') {
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
// 寫入標題列
foreach ($title as $colIndex => $colName) {
$sheet->setCellValueByColumnAndRow($colIndex + 1, 1, $colName);
}
// 標題樣式:粗體、置中、底色漸層、邊框
$lastCol = $sheet->getHighestColumn();
$styleRange = 'A1:' . $lastCol . '1';
$sheet->getStyle($styleRange)->applyFromArray([
'font' => ['bold' => true],
'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
'borders' => [
'bottom' => ['borderStyle' => Border::BORDER_THIN]
],
'fill' => [
'fillType' => Fill::FILL_GRADIENT_LINEAR,
'rotation' => 90,
'startColor' => ['argb' => 'FFA0A0A0'],
'endColor' => ['argb' => 'FFFFFFFF'],
],
]);
// 寫入資料列
foreach ($data as $rowIndex => $row) {
foreach ($row as $colIndex => $value) {
$sheet->setCellValueByColumnAndRow($colIndex + 1, $rowIndex + 2, $value);
}
}
// 自動欄寬
foreach (range('A', $lastCol) as $col) {
$sheet->getColumnDimension($col)->setAutoSize(true);
}
// 輸出下載
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="' . $filename . '.xls"');
header('Cache-Control: max-age=0');
$writer = new Xls($spreadsheet);
$writer->save('php://output');
exit;
}
// 範例資料
$titles = ['商品ID', '供應商', '品牌', '商品名', '連結'];
$rows = [
[1111, '名稱A', '品牌X', '商品一', 'https://example.com/1'],
[2222, '名稱B', '品牌Y', '商品二', 'https://example.com/2'],
];
export_xls($rows, $titles, 'product_report');
?>
<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
function import_xls(string $filePath): array {
$spreadsheet = IOFactory::load($filePath);
$sheet = $spreadsheet->getActiveSheet();
$data = [];
foreach ($sheet->getRowIterator() as $row) {
$cellIterator = $row->getCellIterator();
$cellIterator->setIterateOnlyExistingCells(false); // 保留空儲存格
$rowData = [];
foreach ($cellIterator as $cell) {
$rowData[] = $cell->getValue();
}
$data[] = $rowData;
}
return $data;
}
// 使用範例
$imported = import_xls('uploads/product_report.xls');
// $imported[0] 為標題列,後續為資料
print_r($imported);
?>
| 問題 | 原因 | 解決 |
|---|---|---|
| 中文亂碼 | 舊版 PHPExcel 內部編碼處理不一 | 確保 PHP 檔案儲存為 UTF-8 無 BOM;資料庫連線設 SET NAMES utf8mb4;PhpSpreadsheet 內部已全面支援 UTF-8 |
| 大檔案記憶體耗盡 | 一次載入整份試算表至記憶體 | 啟用 ReadFilter 分塊讀取,或改用 CSV 流式處理 |
| 日期欄位變成數字 | Excel 日期儲存為序數 | 使用 \PhpOffice\PhpSpreadsheet\Shared\Date::excelToDateTimeObject($val) 轉換 |
| 公式未計算 | 讀取時不自動計算公式 | $spreadsheet->getActiveSheet()->calculateFormula() 或寫入時預先計算 |
PHPExcel → PhpOffice\PhpSpreadsheetPHPExcel_ → PhpOffice\PhpSpreadsheet\use 陳述式。PHPExcel / PhpSpreadsheet 是 PHP 處理 Excel 最成熟的方案。新專案請直接使用 PhpSpreadsheet,享受持續更新、PSR-4 自動載入、嚴格型別提示與更佳效能。本文提供的寫入/讀取範例可直接套用於報表匯出、資料匯入等常見場景。