Laravel-excel: [PROPOSAL] Impor item tanpa menyimpan secara langsung

Dibuat pada 24 Jan 2019  ·  9Komentar  ·  Sumber: Maatwebsite/Laravel-Excel

Prasyarat

Versi

  • Versi PHP: 7.1.9
  • Versi Laravel: 5.7.19
  • Versi paket: 3.0+

Deskripsi

Model impor harus dapat dilakukan tanpa menyimpannya secara langsung. Ini juga harus memungkinkan untuk mengembalikan apa pun selain model dari impor.

Saat ini saya tidak dapat meningkatkan dari 2.1.30 ke 3.0.0 atau lebih tinggi. Saya harus dapat mengimpor sekumpulan model tanpa menyimpannya. Saya menggunakan ini untuk tes. Juga, saya memiliki tes di mana baris berisi informasi untuk membuat dua model terkait (dari kelas yang berbeda). Saat ini, saya hanya dapat memiliki satu model per baris. Restrukturisasi file CSV tidak dimungkinkan di sini.

IMO, 3.0.0+ terlalu terfokus pada situasi ideal di mana satu file CSV sesuai dengan satu tabel, dan satu baris sesuai dengan satu model, dan setiap model harus disimpan secara instan. Ini bukan kasus 2.X, dan saya tidak tahu mengapa itu diubah.

Perhatikan bahwa saya tidak ingin tetap menggunakan 2.1.30, karena memerlukan paket phpoffice/phpexcel ditinggalkan.

Contoh

Metode tambahan harus ditambahkan ke fasad Excel , yang memiliki tanda tangan yang sama dengan import , tetapi mengembalikan model daripada menyimpannya. Contoh:

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

Selain itu, metode item harus ditambahkan ke kelas impor, yang dapat mengembalikan tipe apa pun alih-alih hanya model.

question

Komentar yang paling membantu

@WouterFlorijn Anda dapat mencoba pendekatan ini untuk mendapatkan array dari file Anda:

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

Semua 9 komentar

Menggunakan ToModel hanyalah salah satu cara untuk menangani impor. Ini hanyalah opsi yang membuat penyisipan 1 model per baris lebih mudah.

Jika Anda ingin menangani struktur yang berbeda dan dengan cara yang mirip dengan versi 2.1, maka Anda perlu menggunakan ToCollection : https://laravel-excel.maatwebsite.nl/3.1/imports/collection.html Di metode pengumpulan Anda mendapatkan koleksi baris serupa yang Anda dapatkan di 2.1.

Jika Anda ingin mendapatkan model hanya di pengontrol dan bukan di objek impor Anda (sebenarnya bukan pendekatan yang disarankan) daripada ada metode ::toCollection , yang mengembalikan baris mentah (tidak ada konversi ke model yang dilakukan) ke pengontrol Anda .
(https://laravel-excel.maatwebsite.nl/3.1/imports/basics.html#importing-to-array-or-collection)

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

@patrickbrouwers terima kasih atas balasan Anda. Jadi jika saya mengerti dengan benar, menggunakan Excel::import pada impor yang mengimplementasikan ToCollection akan mengembalikan koleksi model tanpa menyimpannya? Jika demikian, ini tidak dinyatakan dengan jelas dalam dokumentasi, karena contoh di bagian bawah https://laravel-excel.maatwebsite.nl/3.1/imports/collection.html adalah sebagai berikut:

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

Nilai yang dikembalikan tidak disimpan di mana pun, menyiratkan bahwa koleksi model yang diimpor disimpan secara langsung (atau setidaknya metode tersebut memiliki efek samping). Jika tidak, akan sia-sia memanggil import tanpa menetapkan nilai kembali ke variabel kan?

@WouterFlorijn Tidak, ::import() tidak akan pernah mengembalikan baris atau model apa pun. Hanya Excel::toCollection() melakukannya.

Menggunakan perhatian ToCollection adalah sesuatu yang berbeda dari menggunakan Excel::toCollection() .
Saat menerapkan ToCollection seluruh impor dikemas dalam objek Impor. Mengembalikan sesuatu di ToCollection tidak akan dikembalikan ke controller.

@patrickbrouwers Sekadar untuk kembali, saya masih berpikir kita salah paham satu sama lain. Apa yang saya cari adalah metode yang mengembalikan Koleksi Model, tanpa menyimpannya. Saya tidak ingin memproses baris di pengontrol saya, saya ingin melakukannya di kelas Impor. Sejauh ini saya belum menemukan ini.

Ide:

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

Saya juga menemukan dua masalah dengan fungsi toCollection :

  1. Ini mengembalikan Koleksi dengan satu item, yang merupakan Koleksi lain yang berisi Koleksi untuk setiap baris.
  2. Dibutuhkan argumen impor, yang tidak berguna dalam kasus di mana Anda hanya ingin mengembalikan baris sebagai Koleksi.

Apa yang saya cari adalah metode yang mengembalikan Koleksi Model, tanpa menyimpannya. Saya tidak ingin memproses baris di pengontrol saya, saya ingin melakukannya di kelas Impor. Sejauh ini saya belum menemukan ini.

Mungkin dokumen ini berguna untuk Anda:
Menangani kegigihan Anda sendiri
Konsep Arsitektur

@WouterFlorijn Anda dapat mencoba pendekatan ini untuk mendapatkan array dari file Anda:

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

@WouterFlorijn Anda dapat mencoba pendekatan ini untuk mendapatkan array dari file Anda:

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

Itulah yang saya cari.

1 untuk permintaan ini. Saya tidak berpikir metode model () dan collection () harus menyimpan apa pun. Ini harus mengembalikan data dari file Excel / CSV ke dalam Koleksi (atau Array) Model / Array. Kegigihan harus ditangani secara terpisah, atau setidaknya menjadi pilihan.

Kasus penggunaan saya: Saya ingin mendapatkan tanggal minimum dan maksimum dari catatan di CSV. Jika ini tumpang tindih dengan CSV yang diimpor yang sudah ada, itu tidak boleh mengimpor apa pun sebelum pengguna mengonfirmasi bahwa tumpang tindih sudah benar.

Edit: Ah, saya menanggapi masalah tertutup. Bagaimana Anda menangani @WouterFlorijn ini?

Anda dapat dengan mudah mencapai ini sendiri dengan mempertahankan status di dalam kelas impor, Anda dapat membungkus metode toModels di dalam sebuah sifat dan menggunakannya kembali di semua ekspor Anda.

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');
Apakah halaman ini membantu?
0 / 5 - 0 peringkat