Laravel-excel: [VORSCHLAG] Importieren Sie Elemente, ohne sie direkt zu speichern

Erstellt am 24. Jan. 2019  ·  9Kommentare  ·  Quelle: Maatwebsite/Laravel-Excel

Voraussetzungen

Versionen

  • PHP-Version: 7.1.9
  • Laravel-Version: 5.7.19
  • Paketversion: 3.0+

Beschreibung

Das Importieren von Modellen sollte möglich sein, ohne sie direkt zu speichern. Es sollte auch möglich sein, etwas anderes als Modelle von einem Import zurückzugeben.

Ich kann derzeit kein Upgrade von 2.1.30 auf 3.0.0 oder höher durchführen. Ich muss in der Lage sein, eine Reihe von Modellen zu importieren, ohne sie zu speichern. Ich benutze dies für Tests. Außerdem habe ich einen Test, bei dem eine Zeile Informationen enthält, um zwei verwandte Modelle (verschiedener Klassen) zu erstellen. Derzeit kann ich nur ein Modell pro Zeile haben. Eine Umstrukturierung der CSV-Datei ist hier nicht möglich.

IMO, 3.0.0+ konzentriert sich zu stark auf die ideale Situation, in der eine CSV-Datei einer Tabelle und eine Zeile einem Modell entspricht und jedes Modell sofort gespeichert werden sollte. Dies war bei 2.X nicht der Fall, und ich weiß nicht, warum es geändert wurde.

Beachten Sie, dass ich nicht auf 2.1.30 bleiben möchte, da hierfür das aufgegebene Paket phpoffice/phpexcel erforderlich ist.

Beispiel

Eine zusätzliche Methode sollte der Excel -Fassade hinzugefügt werden, die dieselbe Signatur wie import , aber Modelle zurückgibt, anstatt sie zu speichern. Beispiel:

$users = Excel::load(new UsersImport, 'users.xlsx');

Zusätzlich sollte eine item -Methode zum Importieren von Klassen hinzugefügt werden, die einen beliebigen Typ anstelle von nur Modellen zurückgeben kann.

question

Hilfreichster Kommentar

@WouterFlorijn Sie können diesen Ansatz ausprobieren, um ein Array aus Ihrer Datei zu erhalten:

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

Alle 9 Kommentare

Die Verwendung von ToModel ist nur eine Möglichkeit, mit Importen umzugehen. Dies ist nur eine Option, die das Einfügen von 1 Modell pro Zeile erleichtert.

Wenn Sie mit unterschiedlichen Strukturen und in einer Weise umgehen möchten, die Version 2.1 ähnelt, müssen Sie ToCollection : https://laravel-excel.maatwebsite.nl/3.1/imports/collection.html In Mit der Erfassungsmethode erhalten Sie eine ähnliche Sammlung von Zeilen, die Sie in 2.1 erhalten haben.

Wenn Sie die Modelle nur im Controller und nicht in Ihrem Importobjekt abrufen möchten (kein wirklich empfohlener Ansatz), gibt es die Methode ::toCollection , mit der die Rohzeile (keine Konvertierung in Modelle erfolgt) an Ihren Controller zurückgegeben wird .
(https://laravel-excel.maatwebsite.nl/3.1/imports/basics.html#importing-to-array-or-collection)

$users = Excel::toCollection(new UsersImport, 'users.xlsx');

@patrickbrouwers danke für deine Antwort. Wenn ich das richtig verstehe, gibt die Verwendung von Excel::import für einen Import, der ToCollection implementiert, eine Sammlung von Modellen zurück, ohne sie zu speichern? Wenn ja, wird dies in der Dokumentation nicht klar angegeben, da das Beispiel am Ende von https://laravel-excel.maatwebsite.nl/3.1/imports/collection.html wie folgt lautet:

public function import() 
{
    Excel::import(new UsersImport, 'users.xlsx');
}

Der Rückgabewert wird nirgendwo gespeichert, was bedeutet, dass die importierte Sammlung von Modellen direkt gespeichert wird (oder zumindest, dass die Methode Nebenwirkungen hat). Andernfalls wäre es sinnlos, import aufzurufen, ohne den Rückgabewert einer Variablen zuzuweisen, oder?

@WouterFlorijn Nein, ::import() gibt niemals Zeilen oder Modelle zurück. Nur Excel::toCollection() .

Die Verwendung des ToCollection -Anliegens ist etwas anderes als die Verwendung von Excel::toCollection() .
Bei der Implementierung von ToCollection der gesamte Import im Import-Objekt gekapselt. Wenn Sie etwas in ToCollection wird dies nicht an den Controller zurückgegeben.

@patrickbrouwers Nur um zurück zu kommen, denke ich immer noch, dass wir uns missverstehen. Was ich einfach suche, ist eine Methode, die eine Sammlung von Modellen zurückgibt, ohne sie zu speichern. Ich möchte die Zeilen in meinem Controller nicht verarbeiten, ich möchte dies in einer Importklasse tun. Bisher habe ich das nicht gefunden.

Die Idee:

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.
...

Ich habe auch zwei Probleme mit der toCollection -Funktion gefunden:

  1. Es gibt eine Sammlung mit einem einzelnen Element zurück. Dies ist eine weitere Sammlung, die eine Sammlung für jede Zeile enthält.
  2. Es wird ein Importargument benötigt, das in Fällen, in denen Sie die Zeilen nur als Sammlungen zurückgeben möchten, unbrauchbar ist.

Was ich einfach suche, ist eine Methode, die eine Sammlung von Modellen zurückgibt, ohne sie zu speichern. Ich möchte die Zeilen in meinem Controller nicht verarbeiten, ich möchte dies in einer Importklasse tun. Bisher habe ich das nicht gefunden.

Vielleicht sind diese Dokumente für Sie hilfreich:
Behalten Sie die Beharrlichkeit selbst bei
Architekturkonzepte

@WouterFlorijn Sie können diesen Ansatz ausprobieren, um ein Array aus Ihrer Datei zu erhalten:

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

@WouterFlorijn Sie können diesen Ansatz ausprobieren, um ein Array aus Ihrer Datei zu erhalten:

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

Genau das habe ich gesucht.

+1 für diese Anfrage. Ich denke nicht, dass die Methoden model () und collection () etwas retten sollten. Es sollte die Daten aus einer Excel / CSV-Datei in eine Sammlung (oder ein Array) von Modellen / Arrays zurückgeben. Persistenz sollte separat behandelt werden oder zumindest eine Wahl sein.

Mein Anwendungsfall: Ich möchte das minimale und maximale Datum aus Datensätzen in einer CSV abrufen. Wenn sich dies mit einer vorhandenen importierten CSV überschneidet, sollte nichts importiert werden, bevor der Benutzer bestätigt, dass die Überlappung korrekt ist.

Edit: Ah, ich antworte auf ein geschlossenes Problem. Wie sind Sie mit diesem @WouterFlorijn umgegangen?

Sie können dies leicht selbst erreichen, indem Sie den Status innerhalb der Importklasse beibehalten. Sie können die toModels -Methode in ein Merkmal einschließen und sie in all Ihren Exporten wiederverwenden.

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');
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen