philiprehberger/laravel-export

Registry-based data export system for Laravel with pluggable format support. Ships with CSV and JSON exporters.

Maintainers

Package info

github.com/philiprehberger/laravel-export

pkg:composer/philiprehberger/laravel-export

Statistics

Installs: 16

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.4 2026-03-17 21:36 UTC

This package is auto-updated.

Last update: 2026-03-17 21:38:43 UTC


README

Tests Latest Version on Packagist License

Registry-based data export system for Laravel with pluggable format support. Ships with CSV and JSON exporters out of the box. Extend with your own formats by implementing a single interface.

Requirements

  • PHP 8.2+
  • Laravel 11 or 12

Installation

composer require philiprehberger/laravel-export

The service provider is auto-discovered via Laravel's package discovery.

Optionally publish the config file:

php artisan vendor:publish --tag=laravel-export-config

Basic Usage

Export a Collection to CSV

use PhilipRehberger\Export\Facades\Export;
use Illuminate\Support\Collection;

$data = collect([
    ['name' => 'Alice', 'email' => 'alice@example.com', 'plan' => 'pro'],
    ['name' => 'Bob',   'email' => 'bob@example.com',   'plan' => 'free'],
]);

$columns = [
    'name'  => 'Name',
    'email' => 'Email Address',
    'plan'  => 'Plan',
];

$csvString = Export::export($data, $columns, 'csv');

Export a Collection to JSON

$jsonString = Export::export($data, $columns, 'json');

Download Response (CSV)

Return a download response directly from a controller:

public function download(Request $request): Response
{
    $users = User::all();

    $data = $users->map(fn ($u) => [
        'name'       => $u->name,
        'email'      => $u->email,
        'created_at' => $u->created_at,
    ]);

    $columns = [
        'name'       => 'Name',
        'email'      => 'Email',
        'created_at' => 'Registered',
    ];

    return Export::download($data, $columns, 'csv', 'users');
    // Sends users.csv with Content-Disposition: attachment
}

Stream Response (for large datasets)

return Export::stream($data, $columns, 'csv', 'users');
// Returns a StreamedResponse

Note: Filenames passed to download() and stream() are automatically sanitized — control characters, quotes, backslashes, and forward slashes are stripped. Empty filenames fall back to "export".

ExportableInterface on Models

Implement ExportableInterface on your Eloquent model to let the service derive columns and filename automatically:

use PhilipRehberger\Export\Contracts\ExportableInterface;

class User extends Model implements ExportableInterface
{
    public function toExportArray(): array
    {
        return [
            'name'       => $this->name,
            'email'      => $this->email,
            'plan'       => $this->plan,           // enums are auto-unwrapped
            'created_at' => $this->created_at,     // Carbon dates are auto-formatted
        ];
    }

    public static function getExportColumns(): array
    {
        return [
            'name'       => 'Name',
            'email'      => 'Email Address',
            'plan'       => 'Plan',
            'created_at' => 'Registered',
        ];
    }

    public static function getExportFilename(): string
    {
        return 'users-export';
    }
}

Then export a collection of models:

$users = User::where('active', true)->get();

// Returns the CSV string
$csv = Export::exportModels($users, 'csv');

// Returns a download Response, filename derived from model
return Export::downloadModels($users, 'csv');

// Override filename
return Export::downloadModels($users, 'csv', 'active-users');

Automatic Value Transformations

AbstractExportFormat handles these transformations automatically inside toExportArray or when using raw collections:

Type Transformation
BackedEnum ->value
Carbon\Carbon ->toDateTimeString() (Y-m-d H:i:s)
array / object json_encode()

Creating a Custom Format Exporter

Implement ExportFormatInterface (or extend the provided AbstractExportFormat base class):

use Illuminate\Support\Collection;
use PhilipRehberger\Export\Formats\AbstractExportFormat;

class XmlExporter extends AbstractExportFormat
{
    public function export(Collection $data, array $columns, array $options = []): string
    {
        $rows = $this->transformData($data, $columns);

        $xml = new SimpleXMLElement('<export/>');
        foreach ($rows as $row) {
            $item = $xml->addChild('item');
            foreach ($row as $key => $value) {
                $item->addChild(preg_replace('/\s+/', '_', $key), htmlspecialchars((string) $value));
            }
        }

        return $xml->asXML();
    }

    public function getContentType(): string { return 'application/xml'; }
    public function getFileExtension(): string { return 'xml'; }
    public function getFormatName(): string { return 'xml'; }
}

Register it in a service provider:

use PhilipRehberger\Export\ExportFormatRegistry;

public function boot(ExportFormatRegistry $registry): void
{
    $registry->register(new XmlExporter);
}

Then use it exactly like the built-in formats:

Export::download($data, $columns, 'xml', 'report');

Checking Available Formats

Export::supportsFormat('csv');       // true
Export::supportsFormat('excel');     // false (not registered)
Export::getAvailableFormats();       // ['csv', 'json']
Export::getFormatMetadata();         // [['name'=>'csv', 'extension'=>'csv', 'contentType'=>'text/csv; charset=UTF-8'], ...]

Configuration Reference

Published at config/laravel-export.php:

return [
    'csv' => [
        'delimiter'       => ',',
        'enclosure'       => '"',
        'include_bom'     => true,   // UTF-8 BOM for Excel compatibility
        'include_headers' => true,
    ],

    'json' => [
        'pretty_print'      => true,
        'include_metadata'  => false, // wraps output in {metadata:{}, data:[]}
    ],
];

Option Reference

Option Format Default Description
delimiter CSV , Field separator
enclosure CSV " String enclosure character
include_bom CSV true Prepend UTF-8 BOM (improves Excel compatibility)
include_headers CSV true Write column headers as the first row
pretty_print JSON true Human-readable indented output
include_metadata JSON false Wrap array in {metadata, data} envelope

Options can be passed per-call to override the config defaults:

Export::export($data, $columns, 'csv', [
    'delimiter'   => ';',
    'include_bom' => false,
]);

API

Export Facade / Service

Method Description
Export::export(Collection $data, array $columns, string $format, array $options = []): string Export data to a string in the given format
Export::download(Collection $data, array $columns, string $format, string $filename = 'export', array $options = []): Response Return a download response
Export::stream(Collection $data, array $columns, string $format, string $filename = 'export', array $options = []): StreamedResponse Return a streamed download response
Export::exportModels(Collection $models, string $format, array $options = []): string Export a collection of ExportableInterface models
Export::downloadModels(Collection $models, string $format, ?string $filename = null, array $options = []): Response Download a collection of ExportableInterface models
Export::supportsFormat(string $format): bool Check whether a format is registered
Export::getAvailableFormats(): array List all registered format names
Export::getFormatMetadata(): array List format name, extension, and content type for each format

ExportableInterface

Method Description
toExportArray(): array Return the model as an associative array for export
getExportColumns(): array Return column key → label mapping
getExportFilename(): string Return the default export filename (without extension)

Development

composer install
vendor/bin/phpunit
vendor/bin/pint --test
vendor/bin/phpstan analyse

License

MIT