[TOC] 引入扩展包 ``` composer require phpoffice/phpspreadsheet ``` #### 1. 文件上传验证器类 --- ```php <?php declare(strict_types=1); namespace app\validate; use think\Validate; class Upload extends Validate { /** * 定义验证规则 * 格式:'字段名' => ['规则1','规则2'...] * * @var array */ protected $rule = [ 'excel' => 'require|filesize:2097152|fileExt:xls,xlsx', ]; /** * 定义错误信息 * 格式:'字段名.规则名' => '错误信息' * * @var array */ protected $message = [ 'excel.require' => '没有文件上传', 'excel.filesize' => '图片大小不能超出2M', 'excel.fileExt' => '只支持xls,xlsx文件', ]; } ``` #### 2. 基础类库层 --- ```php <?php namespace app\lib; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; /** * Excel表格功能封装类 */ class Excel { /** * 读取表格数据 * * @param string $name 文件域名称 * @param array $field 表格各列对应的数据库字段 * @param string $scene 验证场景 */ public static function readData(string $name, array $field, string $scene = 'excel') { try { $file = request()->file($name); if (!$file) throw new \Exception('没有文件上传'); // Excel文件验证 validate(\app\validate\Upload::class)->scene($scene)->check([$scene => $file]); // Excel 类型 Xls Excel2005 Xlsx Excel2007 $type = ucfirst($file->getOriginalExtension()); // 创建读操作对象 $reader = IOFactory::createReader($type); // 忽略任何格式的信息 $reader->setReadDataOnly(true); // 打开文件、载入excel表格 $spreadsheet = $reader->load($file->getRealPath()); // 获取活动工作薄 $sheet = $spreadsheet->getActiveSheet(); // 返回表格数据 return self::getCellData($sheet, $field); } catch (\Exception $e) { // 有异常发生 return ['code' => $e->getCode(), 'errMsg' => $e->getMessage()]; } } /** * 获取单元格数据 * * @param object $sheet * @param array $field */ private static function getCellData(object $sheet, array $field) { # 获取最高列 返回字母 如: C $highestColumn = $sheet->getHighestColumn(); # 获取最大行 返回数字 如: 4 $highestRow = $sheet->getHighestRow(); # 列数 改为数字显示 $highestColumnIndex = Coordinate::columnIndexFromString($highestColumn); $data = []; // 从第二行开始读取数据 for ($row = 2; $row <= $highestRow; $row++) { $build = []; // 从第一列读取数据 for ($col = 1; $col <= $highestColumnIndex; $col++) { // 'A' 对应的ASCII码十进制为 64 // 将ASCII值转为字符 $chr = chr(64 + $col); // 列转为数据库字段名 $key = $field[$chr] ?? $chr; // 构建当前行数据 $build[$key] = $sheet->getCellByColumnAndRow($col, $row)->getValue(); } $data[] = $build; //当前行数据 } return $data; } } ``` #### 3. 逻辑层 --- ```php <?php namespace app\logic; use think\facade\Db; use app\lib\Excel as LibExcel; /** * Excel表格逻辑层 */ class Excel { /** * 将Excel表格中的用户导入数据库 * * @param string $name * @param array $field */ public static function import(string $name, array $field) { // 读取数据 $data = LibExcel::readData($name, $field); // 批量入库 Db::name('user')->insertAll($data); } } ``` #### 4. 控制器调用 --- ```php public function upload() { $field = [ 'A' => 'name', 'B' => 'score', ]; Excel::import('file', $field); } ```