Laravel8使用Maatwebsite实现Excel导入部分失败场景的提示方案咨询
实现方案
步骤1:修改EmployeeImport类,新增成功行数统计
新增公共属性统计成功导入的行数,补全原有代码缺失的闭合标签:
class EmployeeImport extends DefaultValueBinder implements OnEachRow, WithStartRow, SkipsOnError, WithValidation, SkipsOnFailure { use Importable, SkipsErrors, SkipsFailures; // 新增成功行数统计属性 public $successCount = 0; public function onRow(Row $row) { $rowIndex = $row->getIndex(); if($rowIndex >= 1000) return; // 单次最多导入1000行 $row = $row->toArray(); $employee = Employee::create([ 'first_name' => $row[0], 'other_name' => $row[1] ?? '', 'last_name' => $row[2], 'email' => preg_replace('/\s+/', '', strtolower($row[3])), 'created_at' => date("Y-m-d H:i:s"), 'created_by' => Auth::user()->id, ]); // 每成功创建1条记录计数+1 $this->successCount++; } public function startRow(): int { return 2; } }
步骤2:修改Controller导入逻辑,按结果返回对应状态
导入完成后统计成功、失败行数,分场景返回对应提示和数据:
public function importEmployee(Request $request) { try { $validator = Validator::make($request->all(), [ 'document' => 'file|mimes:xls,xlsx|max:5000', ]); if ($request->hasFile('document')) { if($validator->passes()) { $import = new EmployeeImport; $file = $request->file('document'); $savePath = public_path('storage/file_imports/employee_imports'); $fileName = $file->getClientOriginalName(); $file->move($savePath, $fileName); Excel::import($import, $savePath . '/' . $fileName); $failureCount = count($import->failures()); $successCount = $import->successCount; foreach ($import->failures() as $failure) { $importerror = new ImportError(); $importerror->data_row = $failure->row(); $importerror->data_attribute = $failure->attribute(); $importerror->data_errors = $failure->errors()[0]; $importerror->data_values = json_encode($failure->values()); $importerror->created_by = Auth::user()->id; $importerror->created_at = date("Y-m-d H:i:s"); $importerror->save(); } // 分场景返回结果 if ($failureCount === 0) { // 全部成功 return $this->success('员工全部导入成功', [ 'file' => $file, 'success_count' => $successCount, 'failure_count' => 0 ]); } elseif ($successCount > 0) { // 部分成功,返回206 Partial Content状态码 return $this->coreResponse( "部分员工导入成功,共{$successCount}条有效,{$failureCount}条导入失败", [ 'file' => $file, 'success_count' => $successCount, 'failure_count' => $failureCount ], 206, true ); } else { // 全部失败 return $this->error("员工导入全部失败,共{$failureCount}条错误,请修正后重试", 422); } }else{ return $this->error($validator->errors(), 422); } } // 补充无上传文件的异常返回 return $this->error('请上传有效Excel文件', 400); } catch(\Throwable $e) { Log::error($e); return $this->error($e->getMessage(), $e->getCode() ?: 500); } }
效果说明
- 全量导入成功时返回200状态码,提示全部导入完成
- 部分成功部分失败时返回206状态码,同时返回成功、失败条数,前端可引导用户查看存储在数据库中的错误详情,修正后重新上传失败部分
- 全部导入失败时返回422状态码,提示用户全量校验失败
- 原有错误记录存储逻辑保留,无需额外调整
内容的提问来源于stack exchange,提问作者mikefolu
相关产品推荐
相关产品推荐

