skip to Main Content

I am trying to get queued exports to work with the Laravel Excel package, but can’t figure out what I’m missing. I followed the docs on how to queue exports, but when I test it the export completes after the first batch is exported, so after the first 1000 rows. I setup my application to use the database driver in .env and generated/ran the migrations.

I’m using Laravel 5.8, Laravel Excel 3.1, PHP 7.2, Postgresql 10. Here’s a basic version of what I have so far:

Controller

public function export(Request $request){
    $name = 'test.csv';
    (new ExcelExport($client, $year))->queue('public/exports/' . $name)->chain([
        new NotifyUserOfExport($request->user(), $name),
    ]);

    return back()->with('message', 'This export will take some time. You will receive an email when it is ready to download.');
}

Export Class

class ExcelExport implements FromQuery, WithHeadings, WithMapping, WithStrictNullComparison
{
    use Exportable;

    public function __construct($client, $year)
    {
        $this->year = $year;
        $this->client = $client;
    }

    public function query()
    {
        $query = $this->getQuery();

        return $query;
    }

    public function headings(): array
    {
        //...
    }

    public function map($row): array
    {
        //....
    }

    private function getQuery()
    {
        return DB::table('mytable')
                  ->where('year', $this->year)
                  ->where('client', $this->client)
                  ->orderBy('created_at')
                  ->groupBy('column');
    }

My queue.php

return [
    'default' => env('QUEUE_CONNECTION', 'sync'),
    'connections' => [
        'sync' => [
            'driver' => 'sync',
        ],
        'database' => [
            'driver' => 'database',
            'table' => 'jobs', // also tried 'myschema.jobs'
            'queue' => 'default',
            'retry_after' => 90,
        ],
        //.....
    ],

My .env

QUEUE_CONNECTION=database

I don’t think there’s any other code that’s relevant. I get the notification that’s supposed to send after all the jobs are finished, but like I mentioned earlier, it’s sent after the first batch is completed. There are no jobs inserted into the jobs table in the database either, so there’s the problem. I just can’t figure out what I’m missing.

I should mention that I don’t want to use the Implicit Export queueing, since this same export is used in another part of the application that only requires a few rows to be exported, so I don’t need to queue it.

Any help would be appreciated.

2

Answers


  1. Chosen as BEST ANSWER

    It turns out that because my query had a groupBy clause, I needed to implement a custom query size on the export class. I don't understand why that's an issue, but after I added that, the jobs were added to the queue and processed fine. So I added:

        use MaatwebsiteExcelConcernsWithCustomQuerySize;
    
        class ExcelExport implements ...., WithCustomQuerySize
    
        //......
    
        public function querySize(): int
        {
            $query = //......
    
            $size = $query->count();
            return $size;
        }
    

    I hope this helps someone so they don't have to go through the headache I did.


  2. Queued exportables are processed in chunks; each chunk being a job pushed to the queue by the QueuedWriter. In case of exportables that implement the FromQuery concern, the number of jobs is calculated by dividing the $query->count() by the chunk size.

    #When to use

    Depending on the implementation of the query() method (e.g. when using a groupBy clause), the calculation mentioned before might not be correct.

    If this is the case, you should use the WithCustomQuerySize concern to provide a custom calculation of the query size.

    Read more about here https://docs.laravel-excel.com/3.1/exports/queued.html#when-to-use

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search