Laravel-excel: [建议]导入项目而不直接保存

创建于 2019-01-24  ·  9评论  ·  资料来源: Maatwebsite/Laravel-Excel

先决条件

版本号

  • PHP版本:7.1.9
  • Laravel版本:5.7.19
  • 套件版本:3.0+

描述

无需直接保存就可以导入模型。 还应该有可能从导入中返回除模型以外的任何内容。

我目前无法从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方法,该方法可以返回任何类型而不是仅返回模型。

question

最有用的评论

@WouterFlorijn,您可以尝试以下方法从文件中获取数组:

$array = Excel::toArray([], 'file.xlsx');

所有9条评论

使用ToModel只是处理导入的一种方法。 这只是使每行1个模型的插入变得更容易的选项。

如果要处理不同的结构并以类似于2.1版的方式处理,则需要使用ToCollectionhttps :

如果您只想在控制器中而不是在导入对象中获得模型(这不是真正推荐的方法),那么可以使用::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函数有两个问题:

  1. 它返回一个具有单个项目的Collection,这是另一个Collection,其中每个行都包含一个Collection。
  2. 它带有一个import参数,在您只想将这些行作为Collections返回的情况下,这是没有用的。

我只是在寻找一种返回模型集合而不保存它们的方法。 我不想在控制器中处理行,我想在Import类中进行处理。 到目前为止,我还没有找到这个。

也许这些文档对您有帮助:
自己处理持久性
建筑概念

@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');
此页面是否有帮助?
0 / 5 - 0 等级

相关问题

amine8ghandi8amine picture amine8ghandi8amine  ·  3评论

kurianic picture kurianic  ·  3评论

ellej16 picture ellej16  ·  3评论

gamevnlc picture gamevnlc  ·  3评论

vandolphreyes picture vandolphreyes  ·  3评论