首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHPExcel 實戰指南:讀寫 Excel (xls/xlsx) 完整範例與中文編碼解決方案

     編輯:PHP 相關知識

前言與版本說明

PHPExcel 已於 2017 年停止維護,官方建議遷移至 PhpSpreadsheet(語法 90% 相容)。本文以 PHPExcel 為例說明核心概念,實務專案請直接使用 PhpSpreadsheet。

composer require phpoffice/phpspreadsheet

核心類別結構

  • Spreadsheet:代表整個試算表檔案
  • Worksheet:單一工作表
  • Cell:單一儲存格
  • Writer:匯出器(Xls, Xlsx, Csv, Html, Pdf)
  • Reader:讀取器

完整匯出範例:帶標題樣式、多行資料、強制下載

<?php
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls; // 或 Xlsx
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Color;

function exportExcel(array $title, array $data, string $filename = 'report') {
    $spreadsheet = new Spreadsheet();
    $sheet = $spreadsheet->getActiveSheet();

    // 1. 寫入標題列
    foreach ($title as $colIndex => $colName) {
        $cell = $sheet->getCellByColumnAndRow($colIndex + 1, 1);
        $cell->setValue($colName);
    }

    // 2. 標題樣式:粗體、置中、底色、邊框
    $lastCol = $sheet->getCellByColumnAndRow(count($title), 1)->getColumn();
    $styleRange = "A1:{$lastCol}1";
    $sheet->getStyle($styleRange)->applyFromArray([
        'font'      => ['bold' => true, 'color' => ['argb' => 'FFFFFFFF']],
        'alignment' => ['horizontal' => Alignment::HORIZONTAL_CENTER],
        'fill'      => ['fillType' => Fill::FILL_SOLID, 'startColor' => ['argb' => 'FF4472C4']],
        'borders'   => ['allBorders' => ['borderStyle' => Border::BORDER_THIN, 'color' => ['argb' => 'FF000000']]],
    ]);

    // 3. 寫入資料列(支援關聯/索引陣列)
    foreach ($data as $rowIndex => $row) {
        $colIndex = 1;
        foreach ($row as $value) {
            $sheet->setCellValueByColumnAndRow($colIndex++, $rowIndex + 2, $value);
        }
    }

    // 4. 自動欄寬
    foreach (range('A', $lastCol) as $col) {
        $sheet->getColumnDimension($col)->setAutoSize(true);
    }

    // 5. 輸出下載
    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', '供應商', '品牌', '商品名', 'URL'];
$rows = [
    [1001, '供應商A', '品牌X', '商品一', 'https://example.com/1'],
    [1002, '供應商B', '品牌Y', '商品二', 'https://example.com/2'],
];
exportExcel($titles, $rows, 'product_list');

讀取 Excel 檔案

<?php
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;

$spreadsheet = IOFactory::load('upload/product_list.xls');
$sheet = $spreadsheet->getActiveSheet();

foreach ($sheet->getRowIterator() as $row) {
    $cellIterator = $row->getCellIterator();
    $cellIterator->setIterateOnlyExistingCells(false); // 含空儲存格
    $rowData = [];
    foreach ($cellIterator as $cell) {
        $rowData[] = $cell->getCalculatedValue(); // 取得公式計算後值
    }
    print_r($rowData);
}

中文編碼問題徹底解決

現象原因解決方案
匯出中文亂碼舊版 PHPExcel 內部預設 ISO-8859-1PhpSpreadsheet 內部統一 UTF-8,直接寫入即可
讀取舊 .xls (BIFF) 中文亂碼.xls 無編碼標記,預設 CP1252Reader 設定 setReadDataOnly(true) 或指定 setInputEncoding('CP950') (繁中) / GBK (簡中)
CSV 匯入中文亂碼CSV 無編碼資訊用 fgetcsv 搭配 iconv,或 PhpSpreadsheet 的 Csv Reader 指定編碼
<?php
// 讀取 GBK 編碼的舊 .xls
$reader = IOFactory::createReader('Xls');
$reader->setInputEncoding('GBK');
$spreadsheet = $reader->load('legacy.gbk.xls');

大量資料效能優化

  • 啟用 Cell Caching:$spreadsheet->setCellCache(...) 減少記憶體。
  • 分批寫入:避免一次載入超過 5 萬列。
  • 僅寫入值:setCellValueExplicit($col, $row, $val, DataType::TYPE_STRING) 跳過格式推斷。
  • 匯出 CSV:若無樣式需求,CSV 速度快 10 倍以上。

常見坑點速查

  1. 日期儲存為數字:Excel 日期是序數。寫入用 PHPExcel_Shared_Date::PHPToExcel(time()),讀取用 getFormattedValue()。
  2. 公式不計算:讀取時需 $cell->getCalculatedValue();匯出前可 $writer->setPreCalculateFormulas(true)。
  3. 記憶體爆掉:ini_set('memory_limit', '512M') 或改用 Box/Spout 串流式寫入。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved