Maatwebsite excel to array

I am trying to convert an Excel file to an array using the latest version of Laravel-Excel (3.1.9)

The code below will download the file:

return Excel::download(new SalesOrderExport('columns'),'test.xlsx')

But I need to convert it to get an array only. I don’t want to store this Excel data in a database at this point.

I tried with the code below but it did not work as the load method is not available in version 3.

Excel::load($request->file('sampledata'), function ($reader) {
    return response()->json($reader);
});

Please share your thoughts on how to get an array from Excel.

Trevor Reid's user avatar

Trevor Reid

3,1824 gold badges27 silver badges46 bronze badges

asked Feb 27, 2019 at 10:11

Niklesh Raut's user avatar

Niklesh RautNiklesh Raut

33.5k15 gold badges72 silver badges109 bronze badges

0

I and @narayan tried hard to make requested excel file into array. Now I am able to get array properly with below code

$rows = Excel::toArray(new SalesOrderImport, $request->file('sampledata')); 

In my SalesOrderExport class I have default function only, which is required as abstract method.

namespace AppExports;

use AppSalesOrder;
use MaatwebsiteExcelConcernsFromCollection;

class SalesOrderExport implements FromCollection
{
    public function collection()
    {   
        return SalesOrder::all();
    }
}

My Controller code

public function importTest(Request $request)
{
    $rows = Excel::toArray(new SalesOrderImport, $request->file('sampledata'));
    return response()->json(["rows"=>$rows]);
}

And in HTML

<input class="" type="file" name="sampledata" id="sampledata">

I already created this export by

php artisan make:import SalesOrder

Attaching related images

enter image description hereenter image description here

answered Feb 27, 2019 at 13:23

Niklesh Raut's user avatar

Niklesh RautNiklesh Raut

33.5k15 gold badges72 silver badges109 bronze badges

1

I’m adding it on hope that someone could get another types of solution for this.
Version — "maatwebsite/excel": "^3.1"

In Controller

$data = Excel::toArray(new UsersImport(), $request->file);

In UsersImport

<?php
    namespace AppImports;
    use IlluminateSupportCollection;
    use MaatwebsiteExcelConcernsToCollection;

    class UsersImport implements ToCollection
    {
       public function collection(Collection $rows)
       {
       }
    }

Json Array Result

array:2 [▼
  0 => array:2 [▼
           0 => "+126785XXXXX"
           1 => "Jhon"
       ]
  1 => array:2 [▼
           0 => "+126784XXXXX"
           1 => "Doe"
       ]
  ]

And One Bonus,
Now suppose you just need the phone numbers, then make a custom array from that in controller-

$data = Excel::toArray(new UsersImport(), $request->file);
$phoneNumbersData= [];
foreach ($data[0] as $key => $value) {
  $phoneNumbersData[] = $value[0];
}
return $phoneNumbersData;

Hope, this will help someone.

answered Oct 6, 2020 at 21:17

Maniruzzaman Akash's user avatar

0

Here are some working examples based on importing a csv file using the usual file input element. In my case, once uploaded, the file is accessible through the request object as ‘csv_file’.

public function importCSV(Request $request)
{
    // Get the csv rows as an array
    $theArray = Excel::toArray(new stdClass(), $request->file('csv_file'));

    // Get the csv rows as a collection
    $theCollection = Excel::toCollection(collect([]), $request->file('csv_file'));

    //etc
}

answered Mar 26, 2021 at 15:56

omarjebari's user avatar

I tried something like this and it worked perfectly;
in your import file do this

use IlluminateSupportCollection;
use MaatwebsiteExcelConcernsToCollection;

public function collection(Collection $row)
{
    return $row;
}

Then in the controller, do this;

$row = Excel::toCollection(new CourseImport, request()->file('course'));

answered Apr 20, 2021 at 16:42

Davidesk's user avatar

2

Here is how I achieved this:

In my UsersImport class:
namespace AppImports;

use AppUser;
use MaatwebsiteExcelConcernsToModel;
use MaatwebsiteExcelConcernsImportable;

class UsersImport implements ToModel
{
    use Importable;

    public function model(array $row)
    {
        return new User([
           'id' => $row[0]
        ]);
    }
}

And in controller:

$imported_users = (new UsersImport)->toArray(request()->file('excel_file'))[0];

I hope it helps you.

answered Mar 13, 2019 at 12:34

You should try this:

$data = Excel::load($request->file('sampledata'), function ($reader) use($table) {
        $data = $reader->toArray();
        //here data has all excel data in array.
});

answered Feb 27, 2019 at 10:36

AddWeb Solution Pvt Ltd's user avatar

7

  1. Create Import File using below command.

    php artisan make:import TestImport

  2. Inside TestImport make changes like this:

    namespace AppImports;

    use AppUser;
    use IlluminateSupportCollection;
    use MaatwebsiteExcelConcernsToCollection;

    class TestImport implements ToCollection
    {
    public function collection(Collection $rows)
    {
    return $rows;
    }
    }

  3. In Controller make changes like this:

    // original code: $rows = Excel::import(new TestImport, ‘test.xlsx’);

    $rows = Excel::toCollection(new TestImport, ‘test.xlsx’);

brianlmerritt's user avatar

answered Feb 27, 2019 at 10:15

narayansharma91's user avatar

narayansharma91narayansharma91

2,2731 gold badge12 silver badges20 bronze badges

8

It seems that i succesfully wrapped my mind around the new concept of laravel excel.

My problem: I need the sheet names and header row to let the user decide which sheet ist holding a specific kind of data.

With 2.1 i did this

function getSheets($EXCELFILE_READER){
	$sheetData = array(); 
	$sheetTitle = array();
	$sheets = array();
    foreach ($EXCELFILE_READER->getAllSheets() as $sheet) {
    	$sheetTitle[] = $sheet->getTitle();
        $sheets[] = array('title' => $sheet->getTitle(), 'rows' => $sheet->toArray());
    }
    $sheetData = array(
    	'names' => $sheetTitle,
    	'data' => $sheets
   	);
	return $sheetData;
}

Now i do it like this

Import Class

<?php

namespace AppImports;

use IlluminateSupportCollection;
use MaatwebsiteExcelConcernsToCollection;
use MaatwebsiteExcelConcernsWithHeadingRow;
use MaatwebsiteExcelConcernsWithMultipleSheets;
use MaatwebsiteExcelImportsHeadingRowFormatter;
use MaatwebsiteExcelConcernsWithEvents;

use MaatwebsiteExcelEventsBeforeImport;
use MaatwebsiteExcelEventsAfterImport;
use MaatwebsiteExcelEventsBeforeSheet;
use MaatwebsiteExcelEventsAfterSheet;

// Überschriften werden genau so übernommen wie sie in der Datei angegeben wurden
HeadingRowFormatter::default('none');

class HImport1 implements ToCollection, WithHeadingRow, WithEvents
{
    public $sheetNames;
    public $sheetData;
	
    public function __construct(){
        $this->sheetNames = [];
	$this->sheetData = [];
    }
    public function collection(Collection $collection)
    {
    	$this->sheetData[] = $collection;
    }
    public function registerEvents(): array
    {
        return [
            BeforeSheet::class => function(BeforeSheet $event) {
            	$this->sheetNames[] = $event->getSheet()->getTitle();
            } 
        ];
    }

}

Controller:

$Import = new HImport1();
$ts = Excel::import($Import, $importFile);
dump($Import);

image 15

Notice that this only works by using the registerEvents method and the closures for event logic. If you try the same with RegistersEventListeners and a normal event method you cannot set the sheetname because the «beforeSheet»-method is static and «$this->sheetNames» wont be defined.

Works with «toArray» also.

<?php

namespace AppImports;

use MaatwebsiteExcelConcernsToArray;
use MaatwebsiteExcelConcernsWithHeadingRow;
use MaatwebsiteExcelConcernsWithMultipleSheets;
use MaatwebsiteExcelImportsHeadingRowFormatter;
use MaatwebsiteExcelConcernsWithEvents;
use MaatwebsiteExcelEventsBeforeSheet;

// Überschriften werden genau so übernommen wie sie in der Datei angegeben wurden
HeadingRowFormatter::default('none');

class HImport1 implements ToArray, WithHeadingRow, WithEvents
{
	
    public $sheetNames;
    public $sheetData;
	
    public function __construct(){
        $this->sheetNames = [];
	$this->sheetData = [];
    }
    public function array(array $array)
    {
    	$this->sheetData[] = $array;
    }
    public function registerEvents(): array
    {
        return [
            BeforeSheet::class => function(BeforeSheet $event) {
            	$this->sheetNames[] = $event->getSheet()->getTitle();
            } 
        ];
    }
    
}

In one of the following steps i need a associative array with the sheet names as key for that sheets data to use my existing code with laravel excel 3.1. I did this


<?php

namespace AppImports;

use MaatwebsiteExcelConcernsToArray;
use MaatwebsiteExcelConcernsWithHeadingRow;
use MaatwebsiteExcelConcernsWithMultipleSheets;
use MaatwebsiteExcelImportsHeadingRowFormatter;
use MaatwebsiteExcelConcernsWithEvents;
use MaatwebsiteExcelEventsBeforeSheet;
use MaatwebsiteExcelConcernsWithChunkReading;

// Überschriften werden genau so übernommen wie sie in der Datei angegeben wurden
HeadingRowFormatter::default('none');

class HImport2 implements ToArray, WithHeadingRow, WithEvents
{

    public $sheetNames;
    public $sheetData;

    public function __construct(){
        $this->sheetNames = [];
        $this->sheetData = [];
    }
    public function array(array $array)
    {
        $this->sheetData[$this->sheetNames[count($this->sheetNames)-1]] = $array;
    }
    public function registerEvents(): array
    {
        return [
            BeforeSheet::class => function(BeforeSheet $event) {
                $this->sheetNames[] = $event->getSheet()->getTitle();
            } 
        ];
    }
    public function chunkSize(): int
    {
        return 5;
    }
}

Output example
image 18

I and @narayan tried hard to make requested excel file into array. Now I am able to get array properly with below code

$rows = Excel::toArray(new SalesOrderImport, $request->file('sampledata')); 

In my SalesOrderExport class I have default function only, which is required as abstract method.

namespace AppExports;

use AppSalesOrder;
use MaatwebsiteExcelConcernsFromCollection;

class SalesOrderExport implements FromCollection
{
    public function collection()
    {   
        return SalesOrder::all();
    }
}

My Controller code

public function importTest(Request $request)
{
    $rows = Excel::toArray(new SalesOrderImport, $request->file('sampledata'));
    return response()->json(["rows"=>$rows]);
}

And in HTML

<input class="" type="file" name="sampledata" id="sampledata">

I already created this export by

php artisan make:import SalesOrder

Attaching related images

enter image description hereenter image description here

Tags:

Excel

Laravel

Laravel Excel

Maatwebsite Excel

Related

Recently popular package Laravel-Excel released a new version 3.0, which was a pretty radical change from previous versions. I needed to do a simple Excel export and noticed that their documentation covers only export from Laravel Collections but not from some custom structure. So I will show you a «workaround».

First, this is how documentation describes the basic workflow:

namespace AppExports;

use MaatwebsiteExcelConcernsFromCollection;

class InvoicesExport implements FromCollection
{
    public function collection()
    {
        return Invoice::all();
    }
}

You need to create a separate class for export (similar how Laravel Notifications work) and you can define a collection to export.

There are also other ways to export the data:

From Eloquent query:

class InvoicesExport implements FromQuery
{
    use Exportable;

    public function query()
    {
        return Invoice::query();
    }
}

Or, from View HTML table:

class InvoicesExport implements FromView
{
    public function view(): View
    {
        return view('exports.invoices', [
            'invoices' => Invoice::all()
        ]);
    }
}

But still, the problem is that all examples are based on Eloquent. What if I need Excel from some custom structure like array?

Imagine that I have this array:

[
  [
    'name' => 'Povilas',
    'surname' => 'Korop',
    'email' => 'povilas@laraveldaily.com',
    'twitter' => '@povilaskorop'
  ],
  [
    'name' => 'Taylor',
    'surname' => 'Otwell',
    'email' => 'taylor@laravel.com',
    'twitter' => '@taylorotwell'
  ]
]

How do I export that into Excel, so that keys would be columns, and values would be rows?

There are two ways.

Option 1. Turn your Array into a Collection and add Headings

This is how the Export class would look:

namespace AppExports;

use MaatwebsiteExcelConcernsFromCollection;
use MaatwebsiteExcelConcernsExportable;
use MaatwebsiteExcelConcernsWithHeadings;

class CollectionExport implements FromCollection, WithHeadings
{
    use Exportable;

    public function collection()
    {
        return collect([
            [
                'name' => 'Povilas',
                'surname' => 'Korop',
                'email' => 'povilas@laraveldaily.com',
                'twitter' => '@povilaskorop'
            ],
            [
                'name' => 'Taylor',
                'surname' => 'Otwell',
                'email' => 'taylor@laravel.com',
                'twitter' => '@taylorotwell'
            ]
        ]);
    }

    public function headings(): array
    {
        return [
            'Name',
            'Surname',
            'Email',
            'Twitter',
        ];
    }

}

You need to implement collection() method by using Laravel’s collect() method and passing array to it. Also, you need to implement headings() to add a header row.

Finally, in Controller you will have this row at the end of the method:

return Excel::download(new CollectionExport(), 'export.xlsx');

Then you would have this as downloaded result:

laravel excel 3.0 export


Option 2. Pass Array into View

Alternatively, you can build this resources/views/exports/xml.blade.php:

<table>
    <thead>
    <tr>
        @foreach($data[0] as $key => $value)
        <th>{{ ucfirst($key) }}</th>
        @endforeach
        </tr>
    </thead>
    <tbody>
    @foreach($data as $row)
        <tr>
        @foreach ($row as $value)
            <td>{{ $value }}</td>
        @endforeach
    </tr>
    @endforeach
    </tbody>
</table>

And then have this in your Export class:

namespace AppExports;

use IlluminateContractsViewView;
use MaatwebsiteExcelConcernsFromView;

class BladeExport implements FromView
{

    public function view(): View
    {
        return view('exports.xml', [
            'data' => [
              [
                'name' => 'Povilas',
                'surname' => 'Korop',
                'email' => 'povilas@laraveldaily.com',
                'twitter' => '@povilaskorop'
              ],
              [
                'name' => 'Taylor',
                'surname' => 'Otwell',
                'email' => 'taylor@laravel.com',
                'twitter' => '@taylorotwell'
              ]
            ]
        ]);
    }
}

Controller stays the same, just different class name:

return Excel::download(new BladeExport(), 'export.xlsx');

Wait, but how to pass data into Export class?

Both of our examples have one flaw — the data is formed in the class itself. Actually, it shouldn’t even know about the data, it should accept it as a parameter. But how do we do that, if view() or collection() methods have no parameters?

We will pass it through __construct() method into a private variable. You could call it a dependency injection, although there are much better examples of dependency injection, look it up on Google.

class BladeExport implements FromView
{

    private $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function view(): View
    {
        return view('exports.xml', [
            'data' => $this->data
        ]);
    }
}

So we’re accepting $data as a parameter now. Then, in our Controller we can have this:

$data = [
    [
        'name' => 'Povilas',
        'surname' => 'Korop',
        'email' => 'povilas@laraveldaily.com',
        'twitter' => '@povilaskorop'
    ],
    [
        'name' => 'Taylor',
        'surname' => 'Otwell',
        'email' => 'taylor@laravel.com',
        'twitter' => '@taylorotwell'
    ]
];

return Excel::download(new BladeExport($data), 'export.xlsx');

I hope that’s helpful. Check out other examples in official documentation of the package.

Понравилась статья? Поделить с друзьями:
  • Make a sentence with the word science
  • Make a sentence with the word saw
  • Maatwebsite excel facades excel
  • Make a sentence with the word safety
  • Maadai kara excel 7