如何在maatwebsite-excel 3.1中跳过空白行以在Laravel上进行模型方式导入

时间:2019-07-26 02:16:58

标签: laravel maatwebsite-excel

我正在使用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的数据导入数据库,但是也可以导入空白行。我想过滤/验证跳过这些空白,然后再放入数据库。任何建议或指导,将不胜感激,谢谢

5 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分: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

答案 2 :(得分:0)

  

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

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

使用如下功能:

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

答案 3 :(得分:0)

您还可以根据您所做的验证跳过行。如果您的一个请求未涵盖,您可以在模型中输入一个 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
    ];
}

答案 4 :(得分:0)

尝试使用 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找到参考。