How to Export CSV File using Queue in Laravel 11

Hello, laravel web developers! In this article, we'll see how to export CSV files using a queue in laravel 11. Here, we'll fastest way to export CSV files using a queue in laravel 11. Also, we'll use jQuery Ajax call to export CSV files.

In this guide, we'll create export functionalities for Product listing. On the e-commerce website, we have lots of products and data. So, in the normal we export product data it will time consuming.

But we'll use Ajax call and laravel queue to make it faster as compared to normal export functionalities in laravel 11.

Laravel 11 Export CSV file using Queue

laravel 11 export csv file

 

Step 1: Install Laravel 11 Application

In this step, we'll install the laravel 11 application using the following command.

composer create-project --prefer-dist laravel/laravel laravel-11-export-csv

 

Step 2: Configure Database

Now, we will configure the database.

.env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_11_example
DB_USERNAME=root
DB_PASSWORD=root

 

 

Step 3: Create Migration and Model

Next, we'll create migration and model using the following command.

php artisan make:model Product -m

Migration:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {        
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->integer('category_id');
            $table->string('image');
            $table->string('short_desc');
            $table->string('full_desc');
            $table->integer('status')->default('1');
            $table->integer('price');
            $table->integer('quantity');
            $table->softDeletes();
            $table->timestamps();
        });        
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('products');
    }
};

Now, run the migration using the below command.

php artisan migrate

app/Models/Product.php

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
 
class Product extends Model
{
    use HasFactory;
    protected $guarded = [];
}

 

Step 4: Define Routes

Then, we'll define the routes into the web.php file

<?php

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;

use App\Http\Controllers\ProductController;

Route::group(['middleware' => ['auth']], function () {

    Route::get('product', [ProductController::class, 'index'])->name('product.index');
    Route::post('products/export', [ProductController::class, 'export'])->name('products.export');
    Route::get('download/excel', [ProductController::class, 'downloadExcel'])->name('download.excel');

});

 

Step 5: Create Controller

Next, we'll create a Product controller using the following command.

php artisan make:controller ProductController

app/Http/Controllers/ProductController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Jobs\ProductExportJob;
use Illuminate\Support\Facades\Storage;

class ProductController extends Controller
{

   public function index()
    {
        return view('product.index');
    }

    public function export(Request $request)
    {
        if ($request->has('product_ids')) {
            $data = [
                'product_ids' => $request->input('product_ids')
            ];
            dispatch(new ProductExportJob($data));
            $url = Storage::disk('public')->url('product_export/products.xlsx');
            return response()->json(['download_url' => $url]);
        } else {
            return response()->json(['error' => 'No product IDs or category ID provided'], 400);
        }

        return response()->json();
    }

    public function downloadExcel()
    {
        $filePath = 'product_export/products.xlsx';
        if (Storage::disk('public')->exists($filePath)) {
            return Storage::disk('public')->download($filePath);
        } else {
            return response()->json(['error' => 'File not found'], 404);
        }
    }
}

Note: File stored in the storage folder

 

Step 6: Create a Job for Product Export

Then, we'll create a job using the following command.

php artisan make:job ProductExportJob

app/Jobs/ProductExportJob.php

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\ExportProducts;

class ProductExportJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;


    protected $productIds;
    /**
     * Create a new job instance.
     */
    public function __construct($productIds)
    {
        $this->productIds = $productIds;
    }

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        Excel::store(new ExportProducts($this->productIds['product_ids']), 'product_export/products.xlsx', 'public');
    }
}

 

Step 7: Create Export Class

Now, we'll create an export class and add the following code to that file.

<?php

namespace App\Exports;

use Carbon\Carbon;
use App\Models\Product;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class ExportProducts implements FromCollection, WithHeadings, WithMapping, ShouldQueue
{

    protected $productIds;

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


    /**
     * @return \Illuminate\Support\Collection
     */
    public function collection()
    {        
        return  Product::with('category')
            ->whereIn('id', $this->productIds)
            ->get();

    }

    public function headings(): array
    {
        return [
            'ID',
            'Title',
            'Category Title',
            'Short Description',
            'Full Description',
            'Status',
            'Price',
            'Quantity',
            'Created At',
        ];
    }

    public function map($product): array
    {
        $status = $product->status == 1 ? 'Activate' : 'Deactivate';
        $createdAt = Carbon::parse($product->created_at)->format('d-m-Y');

        return [
            $product->id,
            $product->title,
            $product->category->title ?? 'N/A',
            $product->short_desc,
            $product->full_desc,
            $status,
            $product->price,
            $product->quantity,
            $createdAt,
        ];
    }
}

 

 

Step 8: Create a blade file

Then, we'll create a blade file and add an Ajax call to export the CSV file.

@extends('layouts.admin_layout')
@section('content')

    <head>
<title>How to Export CSV File using Queue in Laravel 11 - Techsolutionstuff</title>
        {{-- JQuery  --}}
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

        {{-- datatable  --}}
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css">
        <link rel="stylesheet" href="https://cdn.datatables.net/2.0.7/css/dataTables.bootstrap5.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
        <script src="https://cdn.datatables.net/2.0.7/js/dataTables.js"></script>
        <script src="https://cdn.datatables.net/2.0.7/js/dataTables.bootstrap5.js"></script>        

        {{-- bootstrap 5  --}}
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">

        <style>
            #product_table td {
                text-align: left;
            }

            .export_btn{
                border: 1px solid #0055b0;
            }

            .export_btn:hover{
                background-color: #0055b0;
                color: #ffffff;
            }
        </style>
    </head>   

    <section class="main">
<h6>How to Export CSV File using Queue in Laravel 11 - Techsolutionstuff</h6>
        <div class="container" style="background: white;">
            <h2 class="pt-4">All Products</h2>            

            <div style="margin: 5px;" class="mt-3">
                <div class="d-flex justify-content-between">
                    <div class="d-flex">
                        <button class="btn ms-1 export_btn" id="selectedexcelBtn"><i class="fa fa-download"></i> Export Excel</button>
                        
                        <a href="{{ route('product.create') }}" class="btn ms-1" style="background: #0055b0; color:white;"> <i class="fa fa-plus"></i> Add Product</a>
                    </div>
                </div>

                <table class="table table-striped table-bordered" id="product_table" class="display">
                    <thead class="thead-dark">
                        <tr>
                            <th style="text-align: left;">
                                <input type="checkbox" id="selectAll" name="inputall" />
                            </th>
                            <th style="text-align: left;">Product Name</th>
                            <th style="text-align: left;">Image</th>
                            <th style="text-align: left;">Category Name</th>
                            <th style="text-align: left;">Status</th>
                            <th style="text-align: left;">Price</th>
                            <th style="text-align: left;">Quantity</th>
                            <th style="text-align: left;">Action</th>
                        </tr>
                    </thead>
                    <tbody id="product_body">
                        {{-- ajax will be display here  --}}
                    </tbody>
                </table>
            </div>

        </div>
    </section>

    <script>
        $(document).ready(function() {
                       
            var dataTable = $('#product_table').DataTable({
                stateSave: true,
                processing: true,
                serverSide: true,
                searching: true,
                ordering: true,
                ajax: {
                    url: '{{ route('product.filter') }}',
                    type: 'GET',
                    data: function(d) {
                        return {
                            _token: '{{ csrf_token() }}',                            
                            start: d.start,
                            length: d.length,
                            searchValue: $('input[type="search"]').val(),
                        };
                    },
                    error: function(xhr, error, thrown) {
                        console.log('Error fetching data: ', error);
                        console.log('Response text: ', xhr.responseText);
                    }
                },
                columns: [{
                        data: "checkbox",
                        name: "checkbox",
                        orderable: false,
                        searchable: false
                    },
                    {
                        data: "title",
                        name: "title",
                        searchable: true,
                        orderable: true
                    },
                    {
                        data: "image",
                        name: "imageee",
                        orderable: true
                    },
                    {
                        data: "category_id",
                        name: "category Name",
                        orderable: true
                    },
                    {
                        data: "status",
                        name: "status",
                        width: "50px",
                        orderable: true
                    },
                    {
                        data: "price",
                        name: "price",
                        orderable: true
                    },
                    {
                        data: "quantity",
                        name: "quantity",
                        orderable: true
                    },
                    {
                        data: "action",
                        name: "action",
                        orderable: false,
                        searchable: false,
                        class: "text-white-space text-center"
                    }
                ],
                columnDefs: [{
                    targets: [0, 7],
                    orderable: false
                }]
            });


            // check box  
            $('#selectAll').on('change', function() {
                var isChecked = $(this).is(':checked');
                $('.productCheckbox').prop('checked', isChecked);                
            });

            $(document).on('change', '.productCheckbox', function() {
                var totalCheckboxes = $('.productCheckbox').length;
                var checkedCheckboxes = $('.productCheckbox:checked').length;                

                if (checkedCheckboxes === totalCheckboxes) {
                    $('#selectAll').prop('checked', true);
                } else {
                    $('#selectAll').prop('checked', false);
                }
            });

            // export excel 
            $('#selectedexcelBtn').click(function() {
                var selectedProductIds = [];

                $('.productCheckbox:checked').each(function() {
                    selectedProductIds.push($(this).data('id'));
                });

                var requestData = {
                    _token: '{{ csrf_token() }}',
                };

                if (selectedProductIds.length > 0) {
                    requestData['product_ids'] = selectedProductIds;
                }


                $.ajax({
                    url: '{{ route('admin.products.export') }}',
                    type: 'POST',
                    data: requestData,
                    success: function(response) {
                        if (response.download_url) {
                            window.location.href = '{{ route('download.excel') }}';
                        } else {
                            console.error('Download URL not found.');
                        }
                        dataTable.ajax.reload();
                    },
                    error: function(xhr, status, error) {
                        console.error('Error exporting products:', error);
                    }
                });

            });
            
        });
    </script>
@endsection

 

Step 9: Run Laravel 11 Application

 Then, run the laravel 11  application to export a large CSV file using the following command.

php artisan serve

 


You might also like:

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS