我正在使用 maatwebsite/excel 包导入 CSV。 CSV 包含超过 1 亿行,因此我使用
WithChunkReading
。我还记录了每一行插入。
protected $rowCount = 0;
public function collection(Collection $rows): bool
{
foreach ($rows as $row)
{
// Insertions here
++$this->rowCount;
Log::debug('Inserted row #'.$this->rowCount);
}
return false;
}
public function chunkSize(): int
{
return 10;
}
问题是在每个块之后,
$rowCount
重置为zero
。 laravel.log
的输出:
[2020-07-13 10:06:10] local.DEBUG:插入行#1
[2020-07-13 10:06:11] local.DEBUG:插入行#2
[2020-07-13 10:06:11] local.DEBUG:插入行#3
[2020-07-13 10:06:11] local.DEBUG:插入行#4
[2020-07-13 10:06:11] local.DEBUG:插入行#5
[2020-07-13 10:06:12] local.DEBUG:插入行#6
[2020-07-13 10:06:12] local.DEBUG:插入行#7
[2020-07-13 10:06:12] local.DEBUG:插入行#8
[2020-07-13 10:06:12] local.DEBUG:插入行#9
[2020-07-13 10:06:13] local.DEBUG:插入行#10
[2020-07-13 10:06:16] local.DEBUG:插入行#1
[2020-07-13 10:06:16] local.DEBUG:插入行#2
[2020-07-13 10:06:16] local.DEBUG:插入行#3
我还尝试在闭包中通过引用使用
$rowCount
public function collection(Collection $rows): bool
{
$rowCount = 0;
foreach ($rows as $row)
{
// Insertions here
$counter = function() use(&$rowCount){
return ++$rowCount;
};
Log::debug('Inserted row #'.$counter->call($row));
}
return false;
}
但是结果还是一样。
更新:我尝试从
collection
方法外部访问计数器 -
protected $rowCount = 0;
public function collection(Collection $rows): bool
{
foreach ($rows as $row)
{
// Insertions here
$rowCount = $this->incrementCounter();
Log::debug('Inserted row #'.$rowCount);
}
return false;
}
protected function incrementCounter(){
return ++$this->rowCount;
}
public function chunkSize(): int
{
return 10;
}
然而,这也没有帮助。计数器仍会重置。
如何保留
$rowCount
的值,以便在每个块之后它不会重置回 0
? 现在库中引入了一个名为
RemembersRowNumber
的特征,以帮助跟踪行数。
可以按如下方式使用:
namespace App\Imports;
use App\User;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\RemembersRowNumber;
use Maatwebsite\Excel\Concerns\WithChunkReading;
class UsersImport implements ToModel, WithChunkReading
{
use RemembersRowNumber;
public function model(array $row)
{
$currentRowNumber = $this->getRowNumber();
return new User([
'name' => $row[0],
]);
}
public function chunkSize(): int
{
return 1000;
}
}
请参阅此处的文档了解更多详细信息。