[TOC] 引入擴(kuò)展包 ``` composer require phpoffice/phpspreadsheet ``` #### 1. 文件上傳驗(yàn)證器類 --- ```php <?php declare(strict_types=1); namespace app\validate; use think\Validate; class Upload extends Validate { /** * 定義驗(yàn)證規(guī)則 * 格式:'字段名' => ['規(guī)則1','規(guī)則2'...] * * @var array */ protected $rule = [ 'excel' => 'require|filesize:2097152|fileExt:xls,xlsx', ]; /** * 定義錯(cuò)誤信息 * 格式:'字段名.規(guī)則名' => '錯(cuò)誤信息' * * @var array */ protected $message = [ 'excel.require' => '沒有文件上傳', 'excel.filesize' => '圖片大小不能超出2M', 'excel.fileExt' => '只支持xls,xlsx文件', ]; } ``` #### 2. 基礎(chǔ)類庫層 --- ```php <?php namespace app\lib; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; /** * Excel表格功能封裝類 */ class Excel { /** * 讀取表格數(shù)據(jù) * * @param string $name 文件域名稱 * @param array $field 表格各列對(duì)應(yīng)的數(shù)據(jù)庫字段 * @param string $scene 驗(yàn)證場(chǎng)景 */ public static function readData(string $name, array $field, string $scene = 'excel') { try { $file = request()->file($name); if (!$file) throw new \Exception('沒有文件上傳'); // Excel文件驗(yàn)證 validate(\app\validate\Upload::class)->scene($scene)->check([$scene => $file]); // Excel 類型 Xls Excel2005 Xlsx Excel2007 $type = ucfirst($file->getOriginalExtension()); // 創(chuàng)建讀操作對(duì)象 $reader = IOFactory::createReader($type); // 忽略任何格式的信息 $reader->setReadDataOnly(true); // 打開文件、載入excel表格 $spreadsheet = $reader->load($file->getRealPath()); // 獲取活動(dòng)工作薄 $sheet = $spreadsheet->getActiveSheet(); // 返回表格數(shù)據(jù) return self::getCellData($sheet, $field); } catch (\Exception $e) { // 有異常發(fā)生 return ['code' => $e->getCode(), 'errMsg' => $e->getMessage()]; } } /** * 獲取單元格數(shù)據(jù) * * @param object $sheet * @param array $field */ private static function getCellData(object $sheet, array $field) { # 獲取最高列 返回字母 如: C $highestColumn = $sheet->getHighestColumn(); # 獲取最大行 返回?cái)?shù)字 如: 4 $highestRow = $sheet->getHighestRow(); # 列數(shù) 改為數(shù)字顯示 $highestColumnIndex = Coordinate::columnIndexFromString($highestColumn); $data = []; // 從第二行開始讀取數(shù)據(jù) for ($row = 2; $row <= $highestRow; $row++) { $build = []; // 從第一列讀取數(shù)據(jù) for ($col = 1; $col <= $highestColumnIndex; $col++) { // 'A' 對(duì)應(yīng)的ASCII碼十進(jìn)制為 64 // 將ASCII值轉(zhuǎn)為字符 $chr = chr(64 + $col); // 列轉(zhuǎn)為數(shù)據(jù)庫字段名 $key = $field[$chr] ?? $chr; // 構(gòu)建當(dāng)前行數(shù)據(jù) $build[$key] = $sheet->getCellByColumnAndRow($col, $row)->getValue(); } $data[] = $build; //當(dāng)前行數(shù)據(jù) } return $data; } } ``` #### 3. 邏輯層 --- ```php <?php namespace app\logic; use think\facade\Db; use app\lib\Excel as LibExcel; /** * Excel表格邏輯層 */ class Excel { /** * 將Excel表格中的用戶導(dǎo)入數(shù)據(jù)庫 * * @param string $name * @param array $field */ public static function import(string $name, array $field) { // 讀取數(shù)據(jù) $data = LibExcel::readData($name, $field); // 批量入庫 Db::name('user')->insertAll($data); } } ``` #### 4. 控制器調(diào)用 --- ```php public function upload() { $field = [ 'A' => 'name', 'B' => 'score', ]; Excel::import('file', $field); } ```