Skip to main content
The HasExport trait provides automatic CSV export functionality that works seamlessly with your table’s columns, filters, and search.

Auto Export

The simplest way to add CSV export is as a bulk action:
public function bulkActions(): array
{
    return [
        'exportCsvAuto' => 'Export CSV',
    ];
}
No additional code needed! The export automatically uses your table’s configuration.

What Gets Exported

The exportCsvAuto() method:
  • Uses visible column labels as CSV headers
  • Resolves cell values via each column’s resolveValue() method
  • Excludes blade, action, and image column types
  • Respects active search, filters, and sort
  • When bulk selection is active, exports only selected rows
  • Streams the download for memory efficiency

Configuration

Customize export behavior in your configure() method:
public function configure(): void
{
    $this->setExportFilename('users');     // Default: 'export'
    $this->setExportChunkSize(1000);       // Default: 500
}
The filename is automatically suffixed with the current date: users-2024-12-15.csv

Chunk Size

The exportChunkSize determines how many rows are loaded into memory at once. Larger values are faster but use more memory:
$this->setExportChunkSize(500);  // Default

Direct Usage

Call exportCsvAuto() from any method, not just bulk actions:
public function downloadReport(): StreamedResponse
{
    return $this->exportCsvAuto();
}
Wire this to a button in your view:
<button wire:click="downloadReport">Download Full Report</button>

Export Selected Only

When rows are bulk-selected, exportCsvAuto() exports only those rows:
// In your table component
public function bulkActions(): array
{
    return [
        'exportCsvAuto' => 'Export Selected', // Only exports selected rows
    ];
}
If no rows are selected, the export includes the full filtered/searched query results.

buildExportQuery() Helper

The buildExportQuery() method returns a query builder with your table’s pipeline applied:
protected function buildExportQuery(): Builder
{
    $columns = $this->resolveColumns();
    $filters = $this->filters();
    $state = new State(search: $this->search, filters: $this->tableFilters);

    $query = $this->query();
    $query = (new SearchStep($columns))->apply($query, $state);
    $query = (new FilterStep($filters))->apply($query, $state);
    $query = (new SortStep($columns))->apply($query, $state);

    // If bulk selection is active, filter to selected IDs
    if ($this->selectAllPages || count($this->selectedIds) > 0) {
        $ids = $this->getSelectedIds();
        if (count($ids) > 0) {
            $keyName = $query->getModel()->getKeyName();
            $query->whereIn($keyName, $ids);
        }
    }

    return $query;
}
This is useful when building custom export logic.

Custom Export Methods

For full control over the export format and content, create your own export method:
use SymfonyComponentHttpFoundationStreamedResponse;

public function exportCustom(): StreamedResponse
{
    $query = $this->buildExportQuery();

    return response()->streamDownload(function () use ($query) {
        $out = fopen('php://output', 'w');
        fputcsv($out, ['ID', 'Name', 'Email']);

        $query->chunk(500, function ($rows) use ($out) {
            foreach ($rows as $row) {
                fputcsv($out, [$row->id, $row->name, $row->email]);
            }
        });

        fclose($out);
    }, 'custom-export.csv', ['Content-Type' => 'text/csv']);
}

Custom Primary Keys and UUIDs

The export system uses getKeyName() to determine the model’s primary key:
$keyName = $query->getModel()->getKeyName();
$query->whereIn($keyName, $ids);
UUIDs and custom primary keys work automatically without any configuration.

Available Methods

MethodDescription
exportCsvAuto()Auto-generate and stream CSV download
buildExportQuery()Get the query with pipeline + selection applied
setExportFilename(string)Set the export file name (no extension)
setExportChunkSize(int)Set the chunk size for streaming

Export from Blade Template

Add an export button directly in your view:
<div>
    @if($this->hasBulkActions())
        <button wire:click="exportCsvAuto">
            Download CSV
        </button>
    @endif
    
    <livewire:your-table />
</div>
For large datasets, consider adding a loading indicator during export generation.

Build docs developers (and LLMs) love