I have the following laravel excel export:
namespace App\Admin\Exports\Items;
use App\Flare\Models\Item;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
class ItemsExport implements FromQuery, ShouldQueue {
use Exportable;
public function query() {
return Item::all();
}
}
Which is called in this controller action:
public function export() {
(new ItemsExport)->queue('items.xlsx')->chain([
new ExportItemsEmail(auth()->user()),
]);
return redirect()->back()->with('success', 'File will be emailed to you once done.');
}
There over 5k records for this table
Horizon pushes the job properly but one of them fails:
Maatwebsite\Excel\Jobs\AppendQueryToSheet
ArgumentCountError: Too few arguments to function Illuminate\Support\Collection::get(), 0 passed > in /home/person/Documents/flare/vendor/maatwebsite/excel/src/Jobs/AppendQueryToSheet.php on line 96 and at least 1 expected in /home/person/Documents/flare/vendor/laravel/framework/src/Illuminate/Collections/Collection.php:407
Is this not how you would queue up a large export that should chunk the results of the query?
I have to append a job so I can't just store it. Am I doing something wrong?
My Answer:
It looks like the issue is with the way the query is being handled in the export. Instead of using `Item::all()` which retrieves all records at once, you should use `Item::query()` and then chunk the results to avoid memory issues when exporting a large number of records.
Here's an updated version of your `ItemsExport` class:
php
namespace App\Admin\Exports\Items;
use App\Flare\Models\Item;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
class ItemsExport implements FromQuery, ShouldQueue {
use Exportable;
public function query() {
return Item::query();
}
}
And in your controller action, you can chunk the results before queuing the export:
php
public function export() {
Item::query()->chunk(1000, function ($items) {
$data = [];
foreach ($items as $item) {
$data[] = $item->toArray();
}
(new ItemsExport($data))->queue('items.xlsx');
});
return redirect()->back()->with('success', 'File will be emailed to you once done.');
}
This way, the export will process the records in chunks of 1000 at a time, which should prevent memory issues when exporting a large number of records.
Rate this post
4 of 5 based on 2159 votesComments