Laravel导入Excel时如何匹配数据库sub_category_id与Excel的SubCategory
问题描述
我需要将Excel数据导入Laravel数据库,数据库中sub_category_id字段关联sub_categories表,类型为整数;但Excel模板中对应字段名为SubCategory,内容是字符串(如"Acer Nitro 5"),请问如何实现两者的匹配?
现有导入文件代码
public function model(array $row) { $qrCode = $this->generateQrCode($row); return new FixedAsset([ 'sub_category_id' => $row[1], 'specific_location_id' => $row[2], 'procurement_id' => $row[3], 'unit_id' => $row[4], 'user_id' => $row[5], 'tahun_perolehan' => $row[6], 'kode_bmn' => $row[7], 'kode_sn' => $row[8], 'kondisi' => $row[9], 'image' => $row[10], 'harga' => $row[11], 'keterangan' => $row[12], ]); }
现有控制器导入函数代码
public function import(Request $request) { $file = $request->file('file'); $namaFile = $file->getClientOriginalName(); $path = public_path('/storage/AssetExcel/' . $namaFile); $file->move('storage/AssetExcel', $namaFile); try { Excel::import(new AssetImport(), $path); return redirect()->back()->with( 'success', 'Data berhasil diimpor.' ); } catch (\Exception $e) { return redirect()->back()->with( 'error', 'Terjadi kesalahan saat mengimpor data: ' . $e->getMessage() ); } }
Excel模板示例
| No | SubCategory | Lokasi | Mitra | Satuan | Pj | tahun_perolehan | kode_bmn | kode_sn | kondisi | image | harga | keterangan |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | Acer Nitro 5 | TIK | XL | Unit | Bill | 111111111 | SN123456789 | Baik | tes.png | 2000000 | Baik |
解决方案
核心逻辑是通过Excel中的SubCategory字符串,在sub_categories表中查询对应记录的ID,再将ID赋值给sub_category_id字段,以下是具体实现方式:
1. 基础匹配实现
修改导入文件的model方法,在创建FixedAsset模型前完成字符串到ID的匹配:
use App\Models\SubCategory; // 确保引入SubCategory模型 public function model(array $row) { $qrCode = $this->generateQrCode($row); // 根据SubCategory名称查询对应ID $subCategory = SubCategory::where('name', $row[1])->first(); // 处理名称不存在的情况,避免导入失败 $subCategoryId = $subCategory ? $subCategory->id : null; return new FixedAsset([ 'sub_category_id' => $subCategoryId, 'specific_location_id' => $row[2], 'procurement_id' => $row[3], 'unit_id' => $row[4], 'user_id' => $row[5], 'tahun_perolehan' => $row[6], 'kode_bmn' => $row[7], 'kode_sn' => $row[8], 'kondisi' => $row[9], 'image' => $row[10], 'harga' => $row[11], 'keterangan' => $row[12], ]); }
2. 批量导入性能优化
如果导入数据量较大,循环查询数据库会拖慢速度,可在导入前预加载所有子分类到数组,直接匹配:
use App\Models\SubCategory; private $subCategories = []; public function beforeImport() { // 预加载所有子分类,以名称为键、ID为值存入数组 $this->subCategories = SubCategory::pluck('id', 'name')->toArray(); } public function model(array $row) { $qrCode = $this->generateQrCode($row); // 直接从预加载数组中获取ID $subCategoryId = $this->subCategories[$row[1]] ?? null; return new FixedAsset([ 'sub_category_id' => $subCategoryId, 'specific_location_id' => $row[2], 'procurement_id' => $row[3], 'unit_id' => $row[4], 'user_id' => $row[5], 'tahun_perolehan' => $row[6], 'kode_bmn' => $row[7], 'kode_sn' => $row[8], 'kondisi' => $row[9], 'image' => $row[10], 'harga' => $row[11], 'keterangan' => $row[12], ]); }
3. 异常情况处理
可添加日志记录或异常抛出,处理SubCategory名称不存在的场景:
// 在model方法中添加判断 if (!isset($this->subCategories[$row[1]])) { // 记录日志便于排查 \Log::warning('导入数据中存在未匹配的子分类:'.$row[1]); // 若需终止导入可抛出异常 // throw new \Exception('子分类「'.$row[1].'」不存在,导入终止'); }
内容的提问来源于stack exchange,提问作者Ahmad Ilham
相关产品推荐
相关产品推荐

