无需直接保存就可以导入模型。 还应该有可能从导入中返回除模型以外的任何内容。
我目前无法从2.1.30升级到3.0.0或更高版本。 我需要能够导入一组模型而不保存它们。 我用它来测试。 另外,我有一个测试,其中一行包含创建两个相关模型(不同类)的信息。 目前,我每行只能有一个模型。 此处无法重组CSV文件。
IMO 3.0.0+过于关注理想情况,在理想情况下,一个CSV文件对应一个表,一行对应一个模型,每个模型都应立即保存。 2.X并非如此,我也不知道为什么要更改它。
请注意,我不想停留在2.1.30上,因为它需要放弃的phpoffice/phpexcel
软件包。
应该向Excel
门面添加一个附加方法,该方法的签名与import
,但是返回模型而不是保存模型。 例子:
$users = Excel::load(new UsersImport, 'users.xlsx');
此外,应该在导入类中添加一个item
方法,该方法可以返回任何类型而不是仅返回模型。
使用ToModel
只是处理导入的一种方法。 这只是使每行1个模型的插入变得更容易的选项。
如果要处理不同的结构并以类似于2.1版的方式处理,则需要使用ToCollection
: https :
如果您只想在控制器中而不是在导入对象中获得模型(这不是真正推荐的方法),那么可以使用::toCollection
方法,该方法将原始行(不进行任何模型转换)返回给控制器。
(https://laravel-excel.maatwebsite.nl/3.1/imports/basics.html#importing-to-array-or-collection)
$users = Excel::toCollection(new UsersImport, 'users.xlsx');
@patrickbrouwers感谢您的回复。 因此,如果我正确理解,在实现ToCollection
的导入中使用Excel::import
ToCollection
会返回模型集合而不保存它们吗? 如果是这样,则在文档中没有明确说明,因为https://laravel-excel.maatwebsite.nl/3.1/imports/collection.html底部的示例如下:
public function import()
{
Excel::import(new UsersImport, 'users.xlsx');
}
返回值不会存储在任何地方,这意味着直接保存导入的模型集合(或至少表明该方法有副作用)。 否则调用import
而不将返回值赋给变量是没有用的,对吗?
@WouterFlorijn不, ::import()
永远不会返回任何行或模型。 只有Excel::toCollection()
可以。
使用ToCollection
关心与使用Excel::toCollection()
有所不同。
当实现ToCollection
,整个导入都封装在Import对象中。 以ToCollection
返回的内容不会返回给控制器。
@patrickbrouwers只是想回来,我仍然认为我们彼此误会了。 我只是在寻找一种返回模型集合而不保存它们的方法。 我不想在控制器中处理行,我想在Import类中进行处理。 到目前为止,我还没有找到这个。
这个想法:
TransactionsImport.php:
<?php
namespace App\Imports;
use App\Banks\Transaction;
use Carbon\Carbon;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
class TransactionsImport implements ToModel, WithHeadingRow
{
public function model(array $row)
{
$transaction = new Transaction;
$transaction->amount = $row['amount'];
$transaction->currency = $row['currency'];
return $transaction;
}
}
TransactionsController.php:
...
$transactions = Excel::someFunction(new TransactionsImport, 'path/to/file.csv');
// $transactions is a Collection of Transaction models that are not saved to the database yet.
...
我还发现toCollection
函数有两个问题:
@WouterFlorijn,您可以尝试以下方法从文件中获取数组:
$array = Excel::toArray([], 'file.xlsx');
@WouterFlorijn,您可以尝试以下方法从文件中获取数组:
$array = Excel::toArray([], 'file.xlsx');
那正是我想要的。
对此请求+1。 我不认为model()和collection()方法应该保存任何东西。 它应该将数据从Excel / CSV文件返回到模型/数组的集合(或数组)中。 持久性应该单独处理,或者至少是一种选择。
我的用例:我想从CSV记录中获取最小和最大日期。 如果这与现有导入的CSV重叠,则在用户确认重叠正确之前,它不应导入任何内容。
编辑:啊,我正在回应一个封闭的问题。 您如何处理@WouterFlorijn?
您可以通过将状态保留在import类中来轻松实现自己的目标,可以将toModels
方法包装在特征中并在所有导出中重复使用。
new UsersImport implements ToModel, WithHeadingRow
{
use Importable;
protected array $models;
public function model(array $row)
{
$this->models[] = new User($row);
}
public toModels(string $filename): array
{
$this->import($filename);
return $this->models;
}
}
$nonPersistedUsers = (new UsersImport)->toModels('users.xlsx');
最有用的评论
@WouterFlorijn,您可以尝试以下方法从文件中获取数组:
$array = Excel::toArray([], 'file.xlsx');