Reader Stacks

Exporting Data to Excel or CSV in Laravel

maatwebsite/excel wraps PhpSpreadsheet with a clean export-class API — one class, backed by any Eloquent query, downloadable as either xlsx or csv.

maatwebsite/excel (built on top of PhpSpreadsheet) is the standard package for generating Excel and CSV exports in Laravel — it wraps the underlying spreadsheet library in a clean, Laravel-idiomatic API built around export classes.

1. Install

composer require maatwebsite/excel

2. Create an export class

php artisan make:export OrdersExport --model=Order
class OrdersExport implements FromQuery, WithHeadings
{
    public function query()
    {
        return Order::query()->where('status', 'completed');
    }

    public function headings(): array
    {
        return ['ID', 'Customer', 'Total', 'Date'];
    }
}

Implementing FromQuery instead of FromCollection matters for large exports — it streams results from the database in chunks rather than loading the entire result set into memory at once.

3. Trigger the download

use Maatwebsite\Excel\Facades\Excel;

public function export()
{
    return Excel::download(new OrdersExport, 'orders.xlsx');
}

Changing the file extension in the second argument (orders.csv instead of orders.xlsx) is enough to switch formats — the export class itself doesn't need to change.

Formatting specific columns

class OrdersExport implements FromQuery, WithHeadings, WithMapping
{
    public function map($order): array
    {
        return [
            $order->id,
            $order->customer->name,
            number_format($order->total, 2),
            $order->created_at->format('Y-m-d'),
        ];
    }
}

WithMapping is where you control exactly what each row looks like — formatting dates, resolving relationships to a display name, and rounding numbers, rather than dumping raw database values into the spreadsheet.

Large exports and queued exports

For genuinely large datasets, implementing ShouldQueue on the export class lets it run in the background and notify the user when ready (via a stored file and a notification), instead of holding an HTTP request open for a slow synchronous export.

Topics: Developer Productivity