Skip to main content
Tutorial Free

Laravel-Excel 3.0: Export Custom Array into Excel

June 05, 2018
4 min read

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 App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;

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' => '[email protected]',
    'twitter' => '@povilaskorop'
  ],
  [
    'name' => 'Taylor',
    'surname' => 'Otwell',
    'email' => '[email protected]',
    '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 App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithHeadings;

class CollectionExport implements FromCollection, WithHeadings
{
    use Exportable;

    public function collection()
    {
        return collect([
            [
                'name' => 'Povilas',
                'surname' => 'Korop',
                'email' => '[email protected]',
                'twitter' => '@povilaskorop'
            ],
            [
                'name' => 'Taylor',
                'surname' => 'Otwell',
                'email' => '[email protected]',
                '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 App\Exports;

use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;

class BladeExport implements FromView
{

    public function view(): View
    {
        return view('exports.xml', [
            'data' => [
              [
                'name' => 'Povilas',
                'surname' => 'Korop',
                'email' => '[email protected]',
                'twitter' => '@povilaskorop'
              ],
              [
                'name' => 'Taylor',
                'surname' => 'Otwell',
                'email' => '[email protected]',
                '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' => '[email protected]',
        'twitter' => '@povilaskorop'
    ],
    [
        'name' => 'Taylor',
        'surname' => 'Otwell',
        'email' => '[email protected]',
        '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.

Enjoyed This Tutorial?

Get access to all premium tutorials, video and text courses, and exclusive Laravel resources. Join our community of 10,000+ developers.

Comments & Discussion

No comments yet…

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.