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

Exporter Laravel Package

santwer/exporter

Santwer Exporter is a Laravel/PHP package for exporting application data to downloadable files. It offers a simple API for defining exports and generating them from models or query results, streamlining data export workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

v0.5.0.4 is a patch on the 0.5.0.x line — no new API surface, so anything that worked on 0.5.0.3 should keep working. Treat this as a routine composer update but pin ^0.5.0 (not ^0.5) and read the compare diff if you're mid-debug, since a patch release after several quick iterations often carries small behaviour fixes rather than features.

  1. Install and publish config:
    composer require santwer/exporter:^0.5.0
    php artisan vendor:publish --tag=exporter-config
    
  2. Look first at the package's README and config/exporter.php — the config is the source of truth for default disk, file format, and column mapping. Confirm filesystems.disks has the disk you intend to write to (usually local or s3), because that mismatch is the #1 first-run failure.
  3. Build one export for a single small model before wiring anything into a UI, and run it synchronously. Verify the file lands where you expect and opens cleanly in Excel/LibreOffice (BOM + delimiter issues show up here, not in tests).
  4. First real use case: an admin "Export" button on an index page for a handful of models with a fixed column set. Get that path working end-to-end (route → export definition → file → download response) before adding user-selectable columns or filters.

Implementation Patterns

Thin export definitions, fat queries. Keep the mapping from model to output columns in a dedicated export class and keep the query building outside it (repository, scope, or a builder the caller passes in). Day-to-day you'll want the same export reused for "current filter" and "everything" — if the export class owns the where clauses you'll end up duplicating it.

Always drive large exports through the queue. A few hundred rows inline is fine; anything user-triggered against a table you don't control should be a queued job that writes to disk and then notifies (mail/database notification) with a signed temporary URL. Pattern:

  • Controller validates the request, creates a lightweight "export request" record, dispatches the job, returns 202-ish UI state.
  • Job builds the file, stores it, records path + row count + status on the record.
  • A signed route streams the file and expires.

Chunk your reads. chunkById() (not chunk(), which drifts if rows are inserted mid-run) sized to a few thousand rows, with eager-loaded relations to avoid N+1 — an export is the single easiest place to accidentally fire a query per row.

Stream instead of accumulating. If the package lets you write row-by-row to the output handle, do that; concatenating every row into an array is what turns a 200k-row export into a memory-limit fatal.

Integrate at the boundaries you already have. One artisan command (exports:prune, exports:run-scheduled) plus one scheduled entry is usually enough; avoid a bespoke admin controller per export type — a single ExportController with an exportType enum/registry keeps route and authorization logic in one place.

Test with Storage::fake(). Assert the file exists, assert the header row and a couple of known data rows by parsing the output back, and assert row count matches the filtered query count. This catches column-order and date-format regressions that no amount of manual clicking will.

Gotchas and Tips

  • Pre-1.0 versioning. 0.5.x means minor bumps may break you. Pin to ~0.5.0 in composer.json, and diff the changelog before every minor. Don't let a composer update in CI silently move you.
  • Patch release with no notes. v0.5.0.4 ships nothing but a compare link. Read the actual diff (git diff v0.5.0.3..v0.5.0.4) before assuming it's inert — quiet patches in young packages sometimes change a default or fix something your workaround depends on.
  • Queued exports and stale state. Jobs re-query at run time, so a "filtered export" must serialize the filter criteria, not the model IDs. Otherwise you export a snapshot the user never saw.
  • PHP execution limits, not Laravel's. max_execution_time, memory limit, and PHP-FPM's request_terminate_timeout all bite before any Laravel-level timeout. Set the queue worker's --timeout below retry_after or you'll get duplicated exports.
  • Excel and large integers / leading zeros. Phone numbers, IBANs, and IDs get mangled unless written as text. Force string casting in the column mapping rather than trusting the spreadsheet app.
  • Timezone drift. Carbon values serialize with the app timezone; if the spreadsheet consumer is elsewhere, convert explicitly at mapping time instead of debugging "off by one day" later.
  • Config cache. After changing config/exporter.php in production, php artisan config:cache — otherwise the old defaults persist and you'll swear the package is ignoring you.
  • Disk paths vs. URLs. Storage::url() on the local disk often fails in production because the public symlink doesn't exist. Prefer a controller route with Storage::download() over exposing the path.
  • Extension points worth knowing: custom column/value transformers (formatting, masking) and a custom storage/disk resolver. Both are the right place to add PII masking or currency formatting rather than sprinkling it in the query.
  • Cleanup is your job. Nothing prunes generated files. Add exports:prune to the scheduler on day one; the first disk-full incident is otherwise a certainty.
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.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core