【问题标题】:How to skip blank rows in maatwebsite-excel 3.1 for model-way import on Laravel如何跳过 maatwebsite-excel 3.1 中的空白行以在 Laravel 上进行模型导入
【发布时间】:2019-07-26 02:16:58
【问题描述】:

我正在使用 maatwebsite-exvel 3.1 开发 laravel 项目,以从文件上传方法导入 excel 文件。这是我的StudentsImport 课程。

public function model(array $row)
{
    return new Student([
        'school_uuid' => Auth::user()->school_uuid,
        'cardid'     => $row[0],
        'prefix'    => $row[1], 
        'name'    => $row[2], 
        'lastname'    => $row[3], 
        'dob'    => $row[4], 
        'address'    => $row[5], 
        'phone'    => $row[6], 
    ]);
}

下面是控制器。

 Excel::import(new StudentsImport,  $request->file('file'));

代码工作正常。我可以将 excel 的数据导入数据库,但也可以导入空白行。我想在放入数据库之前过滤/验证以跳过这些空白。任何建议或指导将不胜感激,谢谢

【问题讨论】:

    标签: laravel maatwebsite-excel


    【解决方案1】:

    根据package documentation,支持使用 Laravel 的验证来防止插入无效行。

    要使用它,请在您的导入器类上实现WithValidation 接口并添加一个rules() 方法,该方法返回应用于确保行有效的验证规则。

    public function rules(): array
    {
        return [
            '0' => 'required|string',
            '1' => 'required|string',
            '2' => 'required|numeric',
            // so on
        ];
    }
    

    【讨论】:

      【解决方案2】:

      请注意,rules() 方法不会跳过空行,但会引发错误,导致导入失败,并且验证过的行将被回滚。

      但是我发现文档中存在此功能,您只需在导入类中实现此功能:“Maatwebsite\Excel\Concerns\SkipsOnFailure”

      例如这样:

      class UsersImport implements ToModel, WithValidation, SkipsOnFailure {
          // Your import class
      }
      

      然后在你的导入类中定义一个方法来处理错误:

      /**
       * @param Failure[] $failures
       */
      public function onFailure(Failure ...$failures)
      {
          // Handle the failures how you'd like.
      }
      

      现在rules() 方法不会再在空行上抛出错误,您可以静默处理错误,您仍然应该使用rules() 方法,因为您需要它来抛出现在可以处理的错误由您处理,也许您可​​以将它们记录到文件中,或者您可以正常执行。

      最后,您将能够收集所有错误,以下是文档中的示例:

      $import = new UsersImport();
      $import->import('users.xlsx');
      
      dd($import->errors());
      

      所以,现在您可以静默捕获错误并最终将其返回给您的请求,您甚至可以返回如下详细信息:

      foreach ($import->failures() as $failure) {
         $failure->row(); // row that went wrong
         $failure->attribute(); // either heading key (if using heading row concern) or column index
         $failure->errors(); // Actual error messages from Laravel validator
         $failure->values(); // The values of the row that has failed.
      }
      

      这不是复制粘贴材料好吧,我只是解释了如何根据文档中给出的示例访问错误,我让你来处理这些数据。

      这是我找到所有这些信息的文档的链接:https://docs.laravel-excel.com/3.1/imports/validation.html#skipping-failures

      【讨论】:

        【解决方案3】:

        尝试使用 ToCollection,然后尝试 if($row->filter()->isNotEmpty())

        public function collection(Collection $rows)
           {
              foreach($rows as $row) {
                if($row->filter()->isNotEmpty()){
                    // you logic can go here
                   }
                }   
           }
        

        不要忘记包含use Maatwebsite\Excel\Concerns\ToCollection; 它对我来说很完美

        参考可以找到here

        【讨论】:

          【解决方案4】:

          不要直接将文件直接传递给这个函数,而是创建一个函数来过滤具有如下空白字段的数据:

          function returnNotEmpty($array){
              return array_filter($array, function($i){
                  return !empty($i);
              });
          }
          

          像这样使用函数:

          Excel::import(new StudentsImport,  $this->returnNotEmpty($request->file('file'))); 
          

          【讨论】:

          • 如果数组包含空字符串的值,这将不起作用。
          【解决方案5】:

          您还可以根据您所做的验证跳过行。如果您的请求之一未涵盖,您可以在模型中放入 return null

          public function model(array $row)
          {
              if ($row[2] === null || $row[3] === null ...) {
                return null;
              }
              return new Student([
                  'school_uuid' => Auth::user()->school_uuid,
                  'cardid'     => $row[0],
                  'prefix'    => $row[1], 
                  'name'    => $row[2], 
                  'lastname'    => $row[3], 
                  'dob'    => $row[4], 
                  'address'    => $row[5], 
                  'phone'    => $row[6], 
              ]);
          }

          您还可以在必填字段的规则中添加验证规则“re​​quired_with”,如果在其他字段中存在验证将丢弃的内容,如果不存在,则跳过模型区域中返回 null 的行。

          public function rules(): array
          {
              return [
                  '0' => 'required_with:*.1,*.2,...', // here to be the others rows if they are populate to trow an validation error, 
                  '1' => 'string|nullable|required_with:*.1,*.2,...',',
                  // so on
              ];
          }

          【讨论】:

            猜你喜欢
            • 2020-07-09
            • 1970-01-01
            • 2019-04-17
            • 2015-10-24
            • 2020-04-03
            • 2020-05-20
            • 2019-06-17
            • 2019-08-08
            • 2016-11-23
            相关资源
            最近更新 更多