在企業級應用中,將 Excel 試算表資料批次匯入資料庫是極常見的需求。本文以 ThinkPHP 3.1 為例,詳細說明從環境佈署、前端上傳、後端解析到資料寫入的完整流程,並針對常見坑點(如副檔名不符、路徑錯誤)提供解決方案。
Extend/Vendor/ 下建立 PHPExcel 資料夾,將 Classes 目錄完整複製進入。php.ini 已啟用 php_zip、php_xml、php_gd2 等擴充套件。<form action="<?php echo U('Jdb/import'); ?>" method="post" enctype="multipart/form-data">
<input type="file" name="import" accept=".xls,.xlsx" />
<input type="hidden" name="table" value="target_table" />
<button type="submit">匯入資料庫</button>
</form>
public function import() {
if (empty($_FILES)) { $this->error('請選擇檔案'); return; }
// 1. 處理檔案上傳
import('@.ORG.UploadFile');
$config = [
'allowExts' => ['xls','xlsx'],
'savePath' => './Public/Upload/',
'saveRule' => 'time',
];
$upload = new UploadFile($config);
if (!$upload->upload()) { $this->error($upload->getErrorMsg()); }
$info = $upload->getUploadFileInfo();
$filePath = $info[0]['savepath'] . $info[0]['savename'];
// 2. 載入 PHPExcel
vendor('PHPExcel.PHPExcel');
$reader = PHPExcel_IOFactory::createReader('Excel5'); // .xls
// 若為 .xlsx 應用 'Excel2007'
$objPHPExcel = $reader->load($filePath, 'utf-8');
$sheet = $objPHPExcel->getSheet(0);
// 3. 逐列讀取並寫入資料庫
$highestRow = $sheet->getHighestRow();
for ($row = 2; $row <= $highestRow; $row++) { // 第1列假設為標題
$data = [
'lianjieid' => $sheet->getCell("A{$row}")->getValue(),
'yaoqingma' => $sheet->getCell("B{$row}")->getValue(),
'dlmima' => $sheet->getCell("C{$row}")->getValue(),
'ljdizhi' => $sheet->getCell("D{$row}")->getValue(),
];
M('jdb')->add($data);
}
$this->success('匯入成功!共 '.($highestRow-1).' 筆資料');
}
| 問題現象 | 根本原因 | 解決辦法 |
|---|---|---|
PHPExcel_Reader_Exception: The filename ... is not recognised | 上傳 .xlsx 卻用 Excel5 讀取器 | 依副檔名動態選擇 createReader('Excel2007') 或 Excel5 |
| 中文欄位亂碼 | 編碼不一致 | 統一專案、資料庫、PHPExcel 皆使用 UTF-8;必要時 iconv() 轉碼 |
| 大檔案記憶體爆掉 | PHPExcel 全量載入至記憶體 | 改用 PhpSpreadsheet 的 ChunkReadFilter 分塊讀取,或要求使用者轉 CSV |
| 日期欄位變成數字 | Excel 內部以序數儲存日期 | 用 PHPExcel_Shared_Date::ExcelToPHP() 轉換 |
遵循上述規範,即可在 ThinkPHP 3.1 專案中穩健實現 Excel 匯入功能,為後續遷移至 ThinkPHP 5/6 或 Laravel 打下良好基礎。