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

PHP 讀取 Excel (xls/xlsx) 並匯入 MySQL:PHPExcelReader 完整實戰教學

     編輯:PHP 綜合知識

工具選擇:PHPExcelReader (Spreadsheet_Excel_Reader)

支援 **BIFF 7/8 (xls)** 及 **Office Open XML (xlsx)** 格式,純 PHP 實作,無需 COM 元件或 LibreOffice,適合 Linux 伺服器部署。專案地址:sourceforge.net/projects/phpexcelreader

環境需求

  • PHP 5.3+ / 7.x / 8.x
  • 啟用 iconv 或 mbstring 擴展(編碼轉換)
  • MySQL 資料庫建議使用 utf8mb4 字元集

目錄結構

project/
├── test.php              # 主程式
├── includes/
│   ├── reader.php        # 核心解析類
│   └── OLERead.php       # OLE 容器解析
└── data.xls              # 待匯入 Excel 檔

核心程式 test.php

<?php
require_once './includes/reader.php';

// 1. 實例化並設定輸出編碼
$data = new Spreadsheet_Excel_Reader();
$data->setOutputEncoding('utf-8'); // 內部轉為 UTF-8

// 2. 讀取 Excel 檔
$file = 'data.xls'; // 或 data.xlsx
if (!$data->read($file)) {
    die("讀取失敗:檔案不存在或格式錯誤");
}

// 3. 連線資料庫 (PDO 推薦)
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8mb4", "root", "1234");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

// 4. 遍歷第一個工作表 (sheets[0])
$sheet = $data->sheets[0];
$rows = $sheet['numRows'];
$cols = $sheet['numCols'];

echo "偵測到 $rows 列 x $cols 欄,開始匯入...<br>";

$stmt = $pdo->prepare("INSERT INTO `import_table` (col1, col2, col3) VALUES (?, ?, ?)");
$success = 0;

for ($i = 1; $i <= $rows; $i++) { // Excel 列索引從 1 開始
    // 讀取儲存格值 (欄索引從 1 開始)
    $val1 = $sheet['cells'][$i][1] ?? '';
    $val2 = $sheet['cells'][$i][2] ?? '';
    $val3 = $sheet['cells'][$i][3] ?? '';

    // 跳過空白列
    if (trim("$val1$val2$val3") === '') continue;

    try {
        $stmt->execute([$val1, $val2, $val3]);
        $success++;
    } catch (PDOException $e) {
        echo "第 $i 列寫入失敗: " . $e->getMessage() . "<br>";
    }
}

echo "匯入完成:成功 $success 筆<br>";

關鍵類別原始碼說明

OLERead.php - OLE 容器解析

負責解析 `.xls` 的 OLE 復合文件結構:

  • 讀取 FAT (File Allocation Table) 定位資料流
  • 解析目錄項目找到 Workbook 資料流
  • 支援大區塊/小區塊鏈、擴展區塊
  • 核心方法:read($filename)、getWorkBook()

reader.php - BIFF 格式解析

解析 Excel 內部二進位記錄:

  • _parse():解析全域記錄 (SST 共享字串表、Format 格式、XF 樣式、BoundSheet 工作表資訊)
  • _parsesheet():解析工作表記錄 (ROW、NUMBER、LABEL、FORMULA、RK、MULRK、BOOLERR 等)
  • 日期/數值/公式/合併儲存格完整支援
  • 編碼轉換:_encodeUTF16() 使用 iconv 或 mb_convert_encoding 將 UTF-16LE 轉目標編碼

常見問題與解決

問題原因與解決
中文亂碼確認 setOutputEncoding('utf-8')、資料庫 charset=utf8mb4、PHP 檔案儲存為 UTF-8 without BOM
xlsx 讀取失敗舊版僅支援 xls。新版已支援 xlsx,請更新至最新版或改用 PhpSpreadsheet
日期變成數字Excel 日期儲存為序數。庫會自動偵測 XF 格式轉換,若失敗可手動:date('Y-m-d', ($val - 25569) * 86400)
大檔案記憶體不足Reader 會將整檔載入記憶體。超過 10MB 建議改用 PhpSpreadsheet 的 ChunkReadFilter 分塊讀取
合併儲存格值為空僅主儲存格有值,合併區域其他儲存格為空。需根據 mergedCells 資訊自行填補

現代替代方案:PhpSpreadsheet (強烈推薦)

PHPExcelReader 為舊專案,已停止維護。新專案請使用 **PhpSpreadsheet**(PHPExcel 繼任者):

composer require phpoffice/phpspreadsheet
<?php
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;

$reader = new Xlsx();
$reader->setReadDataOnly(true); // 僅讀資料,不載入樣式,省記憶體
$spreadsheet = $reader->load("data.xlsx");
$sheet = $spreadsheet->getActiveSheet();

foreach ($sheet->getRowIterator() as $row) {
    $cells = [];
    foreach ($row->getCellIterator() as $cell) {
        $cells[] = $cell->getValue();
    }
    // 寫入 DB...
}

優勢:支援 .xls/.xlsx/.ods/.csv、記憶體優化、活躍維護、Composer 安裝、命名空間、PHP 8 相容。

結語

PHPExcelReader 為快速導入舊版 .xls 提供了零依賴的純 PHP 方案。但面對 .xlsx、大檔案、複雜格式,**PhpSpreadsheet 是現代標準選擇**。匯入流程核心:讀取 → 驗證/清洗 → 批次預處理寫入 → 記錄錯誤日誌,建議封裝為可複用的 Import Service 類別。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved