準備工作
- 下載 PHPExcel:CodePlex 或
composer require phpoffice/phpexcel(已棄用,建議遷移 PhpSpreadsheet)。
- 將
Classes 目錄放入項目 module/PHPExcel/ 或 vendor/。
三步走流程
- 上傳文件 → 服務器臨時目錄
- 解析數據 → 讀取 Sheet、逐行提取字段
- 批量入庫 → 事務寫入、統計成功失敗條數
1. 封裝通用上傳方法 (Common/function.php)
<?php
function upload_file($file_id, $dir, $max_size = 5242880, $exts = ['xls','xlsx']) {
$upload = new \Think\Upload();
$upload->maxSize = $max_size;
$upload->exts = $exts;
$upload->rootPath = './uploads/';
$upload->savePath = $dir . '/';
$info = $upload->upload();
if (!$info) {
return ['status' => 0, 'msg' => $upload->getError()];
}
$file = $info[$file_id];
return [
'status' => 1,
'msg' => '上傳成功',
'path' => $file['savepath'] . $file['savename'] // 相對路徑
];
}
?>
2. 控制器導入邏輯
<?php
namespace Home\Controller;
use Think\Controller;
class ImportController extends Controller {
public function excel() {
// 1. 上傳
if (!empty($_FILES['xls']['name'])) {
$res = upload_file('xls', 'temp_xls', 5242880, ['xls','xlsx']);
if (!$res['status']) $this->error($res['msg']);
$path = $res['path'];
} else {
$this->error('請選擇文件');
}
// 2. 解析 Excel
require_once 'module/PHPExcel/Classes/PHPExcel/IOFactory.php';
$objPHPExcel = \PHPExcel_IOFactory::load("uploads/$path");
$sheet = $objPHPExcel->getSheet(0); // 第一個 Sheet
$rowCount = $sheet->getHighestRow();
$data = [];
for ($i = 2; $i <= $rowCount; $i++) { // 第1行表頭跳過
$data[] = [
'name' => $this->getCell($sheet, 'A' . $i),
'sex' => $this->getCell($sheet, 'B' . $i),
'contact' => $this->getCell($sheet, 'C' . $i),
'remark' => $this->getCell($sheet, 'D' . $i),
'addtime' => $this->getCell($sheet, 'E' . $i),
];
}
// 3. 批量入庫
$success = $error = 0;
foreach ($data as $v) {
if (M('temp_area3')->data($v)->add()) {
$success++;
} else {
$error++;
}
}
$this->success("總 {$rowCount} 條,成功 $success 條,失敗 $error 條");
}
// 輔助:安全獲取單元格值
private function getCell($sheet, $coord) {
$cell = $sheet->getCell($coord);
return $cell->getCalculatedValue(); // 支持公式計算
}
}
?>
關鍵注意點
- 內存優化:大文件(>5MB)用
PHPExcel_IOFactory::createReader('Xlsx')->setReadDataOnly(true) 只讀數據不載樣式。
- 日期處理:Excel 日期為數字,需
\PHPExcel_Shared_Date::ExcelToPHP($value) 轉換。
- 事務支持:批量寫入建議開啟事務
M()->startTrans(),失敗回滾。
- 遷移建議:PHPExcel 2017 年停止維護,新項目請用 PhpSpreadsheet,API 高度兼容,只需將命名空間
PHPExcel → PhpOffice\PhpSpreadsheet。
PhpSpreadsheet 速查
<?php
use PhpOffice\PhpSpreadsheet\IOFactory;
$spreadsheet = IOFactory::load("uploads/$path");
$sheet = $spreadsheet->getActiveSheet();
$value = $sheet->getCell('A2')->getValue();
// 其餘邏輯幾乎一致
?>