Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel excel get total number of rows before import

Straight forward question. How does one get the total number of rows in a spreadsheet with laravel-excel?

I now have a working counter of how many rows have been processed (in the CompanyImport file), but I need the total number of rows before I start adding the rows to the database.

The sheet I'm importing is almost 1M rows, so I am trying to create a progress bar.

My import:

public function model(array $row)
{
    # Counter
    ++$this->currentRow;

    # Dont create or validate on empty rows
    # Bad workaround
    # TODO: better solution
    if (!array_filter($row)) {
        return null;
    }

    # Create company
    $company = new Company;
    $company->crn = $row['crn'];
    $company->name = $row['name'];
    $company->email = $row['email'];
    $company->phone = $row['phone'];
    $company->website = (!empty($row['website'])) ? Helper::addScheme($row['website']) : '';
    $company->save();

    # Everything empty.. delete address
    if (!empty($row['country']) || !empty($row['state']) || !empty($row['postal']) || !empty($row['address']) || !empty($row['zip'])) {

        # Create address
        $address = new CompanyAddress;
        $address->company_id = $company->id;
        $address->country = $row['country'];
        $address->state = $row['state'];
        $address->postal = $row['postal'];
        $address->address = $row['address'];
        $address->zip = $row['zip'];
        $address->save();

        # Attach
        $company->addresses()->save($address);

    }

    # Update session counter
    Session::put('importCurrentRow', $this->currentRow);

    return $company;

}

My controller:

public function postImport(Import $request)
{
    # Import
    $import = new CompaniesImport;

    # Todo
    # Total number of rows in the sheet to session
    Session::put('importTotalRows');

    #
    Excel::import($import, $request->file('file')->getPathname());

    return response()->json([
        'success' => true
    ]);
}
like image 896
Kaizokupuffball Avatar asked Sep 15 '19 08:09

Kaizokupuffball


2 Answers

1.- Make file for import

php artisan make:import ImportableImport

2.- Your File Import

<?php

namespace App\Imports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\Importable;

class ImportablesImport implements ToCollection
{

    use Importable;

    /**
    * @param Collection $collection
    */
    public function collection(Collection $collection)
    {
        //
    }
}

3.- Your controller

$array = (new ImportablesImport)->toArray($file);
dd(count($array[0]));

This doc: https://docs.laravel-excel.com/3.1/imports/importables.html

like image 145
Luis Cordero Avatar answered Nov 04 '22 09:11

Luis Cordero


In Laravel Excel 3.1 you can get the total rows by implementing WithEvents and listening to beforeImport event.

<?php

namespace App\Imports;

use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\BeforeImport;

class UserImport extends ToModel, WithEvents {
    [...]

    public function registerEvents(): array
    {
        return [
            BeforeImport::class => function (BeforeImport $event) {
                $totalRows = $event->getReader()->getTotalRows();

                if (!empty($totalRows)) {
                    echo $totalRows['Worksheet'];
                }
            }
        ];
    }

    [...]
}
like image 21
glaucomorais Avatar answered Nov 04 '22 08:11

glaucomorais