Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Csv Exporter Laravel Package

steadfastcollective/statamic-csv-exporter

Export Statamic entries to CSV with configurable columns and filters. A small addon for content teams needing quick spreadsheet-friendly exports from the control panel.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and wire it up

composer require steadfastcollective/statamic-csv-exporter

Statamic addons auto-discover their service provider, so there is usually no manual registration step. Immediately after install, open vendor/steadfastcollective/statamic-csv-exporter/src/ServiceProvider.php — for a package this small, that file is the documentation. Read its boot() and register() methods and note three things:

  1. What it registers — a control-panel action (bulk export from a listing), a utility page, an Artisan command, or some combination. That determines your integration surface.
  2. What it publishes — look for $this->publishes([...], 'csv-exporter-config') or similar tags, then publish with php artisan vendor:publish --provider="SteadfastCollective\CsvExporter\ServiceProvider".
  3. Config defaults — a config/csv-exporter.php (or config/statamic/csv-exporter.php) will tell you which collections/fields are exported out of the box and whether output is streamed or written to disk.

First use case

Start with the lowest-risk, highest-value workflow: a one-off export of a single collection for a client handoff or a content audit. In the Control Panel, go to Collections → {your collection} → Entries, select a handful of entries, open the Actions dropdown, and look for an export entry. If the action isn't there, check config/statamic/actions.php (Statamic only surfaces registered actions) and confirm the addon's action class extends Statamic\Actions\Action.

Do the first export against a collection with plain text fields only. You want to confirm the mechanics (headers, encoding, file download) before you introduce Bard, Grid, or relationship fields, which are where CSV exports usually get messy.

Implementation Patterns

CP-driven bulk export (the daily driver). The realistic workflow is: editor selects entries in a listing → runs the action → downloads a CSV. That's fine for tens of entries. For anything larger, treat the CP action as a smoke test rather than a production export path, because PHP execution time and memory will bite you before the CSV gets large.

Config-defined export schemas. If the package supports per-collection field maps, lean on it rather than editing PHP. A typical shape:

// config/csv-exporter.php
'collections' => [
    'products' => [
        'columns' => [
            'title'        => 'Product Name',
            'sku'          => 'SKU',
            'price'        => 'Price',
            'categories'   => 'Categories', // taxonomy -> join with |
        ],
    ],
],

Keeping labels here means non-developers can request header changes without a deploy.

Programmatic export from your own code. When you need a filtered or scheduled export, bypass the CP entirely. The pattern is the same regardless of the addon's internals:

use Illuminate\Support\Facades\DB;

$entries = \Statamic\Facades\Entry::query()
    ->where('collection', 'products')
    ->where('status', 'published')
    ->lazy(); // stream, don't ->get()

return response()->streamDownload(function () use ($entries) {
    $out = fopen('php://output', 'w');
    fputcsv($out, ['Product Name', 'SKU', 'Price', 'Categories']);

    foreach ($entries as $entry) {
        fputcsv($out, [
            $entry->get('title'),
            $entry->get('sku'),
            $entry->get('price'),
            collect($entry->get('categories'))->implode('|'),
        ]);
    }

    fclose($out);
}, 'products-' . now()->format('Y-m-d') . '.csv');

If the addon ships an exporter class, prefer injecting it over hand-rolling — it will already handle the header row, delimiter, and encoding consistently with the CP action.

Scheduled exports. Register an Artisan command in app/Console/Kernel.php (or routes/console.php on Laravel 11+) that writes to storage/app/exports/, then let your client pull the file from wherever you sync it. This is the sane path for full-catalogue exports — no HTTP timeout, no browser tab dying at 60 seconds.

Multi-site. Statamic stores entries per site. If the addon doesn't expose a site selector, filter explicitly with ->where('site', 'en') in your own query, or you'll silently export the default site only and wonder where the translations went.

Gotchas and Tips

CSV injection is a real vulnerability, not a nicety. Any field starting with =, +, -, or @ will be interpreted as a formula when the client opens the file in Excel. Prefix those cells with a single quote or a tab. If the package doesn't do this (small addons frequently don't), wrap your values before they hit fputcsv.

Field values are not all strings. Assets, entries, terms, and users come back as objects/arrays. Decide deliberately:

  • Assets: $asset->url() (public link) vs $asset->path() (relative) vs $asset->id(). Pick one and document it.
  • Relationships: join with | or ; — never a comma, since that's your delimiter.
  • Bard/Replicator/Grid: there is no clean CSV representation. Either serialise to JSON (a single quoted cell) or flatten to plain text via strip_tags. Don't try to make it look pretty.

Augmented vs raw values. $entry->get('field') returns the stored value; $entry->augmentedValue('field')->value() returns what the template would render (resolved URLs, formatted dates, Markdown converted to HTML). For round-trip-able exports use raw; for human-readable exports use augmented. Mixing the two in one file is the most common source of "why does this column look different" tickets.

Excel and UTF-8. Without a BOM, Excel on Windows will mangle accented characters and emoji. Prepend "\xEF\xBB\xBF" to the stream if your audience is Excel-based; skip it if they're importing into a system that chokes on a BOM.

Memory blows up on ->get(). Always use ->lazy() or ->chunk(). A 20k-entry export built in memory will exhaust the default 128M limit. Streaming with php://output keeps memory flat.

Nulls vs empty strings. fputcsv writes an empty cell for null, which downstream tools read as "column missing" or "column empty" depending on the parser. If distinction matters, coerce with ?? '' and be consistent.

Permissions. Statamic actions expose visibleTo() / authorize(). If the export button appears for roles that shouldn't see unpublished drafts, that's a policy gap in the addon — verify by logging in as a low-privilege role before shipping to a client.

Evaluate maintainability honestly. This is a 4-star package with zero dependents and a single recent release. Treat it as a thin convenience wrapper, not infrastructure: pin the exact version in composer.json, read the source before relying on undocumented behaviour, and be prepared to vendor the exporter class into app/ if Statamic ships a breaking major (Statamic's action and query APIs have shifted between v3, v4, and v5). A 200-line export class is cheap to own outright, and that option should be on the table from day one.

Debugging tip. If the CP action silently does nothing, check storage/logs/laravel.log first, then confirm the action class is present in the resolved actions list with php artisan tinker → \Statamic\Facades\Action::all(). Half of all "the addon is broken" reports for Statamic addons are actually a cache issue — run php artisan statamic:stache:clear && php artisan config:clear.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource