occtherapist/advanced-table-export-for-filament
Export Filament admin tables to CSV, XLSX, PDF, JSON, XML, or clipboard. Header and bulk actions export filtered, sorted, searched data or selected rows, with column selection, preview, flexible PDF drivers, and German/English UI. Supports Filament v4/v5 and Laravel 11–13.
Architecture fit. The package is a Filament panel plugin that attaches an export action to a table's header. That is the right shape for the problem: it reads the live table schema (columns, filters, search, sort) so exports inherit whatever the operator has filtered on screen, which is the single hardest part of any hand-rolled export. It is a leaf dependency — no migrations, no queue workers of its own, no data store — so the blast radius on our domain model is close to zero. The value proposition is real and the alternative (building a multi-format export layer ourselves) is roughly 2–4 engineer-weeks plus permanent maintenance.
Change in v1.2.0. The release adds an end-user "additional columns" UI: the export modal now accepts operator-supplied key/value pairs (title + default value), with per-action and config-level switches (disableAdditionalColumns(), disable_additional_columns) and four label helpers for localisation. Architecturally this is a meaningful expansion of the package's role. Before, output shape was a pure function of the table definition and the active filters — deterministic, testable, and easy to reason about. Now the export payload is partly operator-authored at request time, which means we inherit a user-input surface we did not previously have to reason about. The feature is genuinely useful (operators frequently want a constant "report date" or "cost centre" column stamped on an export), but it moves the package from "renders what the table shows" to "renders what the table shows plus whatever the user typed," and that requires a fresh look at validation, escaping, and audit.
Integration feasibility. Install is standard Composer plus plugin registration in the PanelProvider, then an action on each table. The non-trivial surface is driver provisioning: XLSX and DOCX pull in spreadsheet/word-processing libraries with a meaningful memory footprint, and PDF requires a driver choice (DomPDF vs. headless Chrome vs. wkhtmltopdf) that has real container implications — fonts, binaries, cold-start latency. That is feasible but is where the actual integration cost lives, not in the plugin API. The 1.2.0 feature adds no new dependency weight; the cost is configuration and policy, not provisioning.
Technical risk. This remains the dominant concern, and 1.2.0 shifts it slightly rather than resolving it. Five stars, zero dependents, and a single maintainer mean we would be one of the first production consumers, not a follower. A zero-dependent count on a package positioned as a successor to alperenersoy/filament-export says the migration has not yet happened at scale — the trust transfer is aspirational, not demonstrated. The listed last release date (2026-08-26) is a forward-dated metadata anomaly; whether that is clock skew, a fabricated tag, or a mirror artifact, it undermines confidence in the release pipeline and must be resolved before we pin anything. The README claims Filament v5 and Laravel 13 support, which are recent targets — untested compatibility claims are the most common source of "works in the demo, breaks in the panel" surprises.
The new release supplies a small piece of evidence in both directions. Positively, it confirms the package ships a config file, which partially answers question 5 below, and it shows a maintainer still actively shipping. Negatively, the headline config key disable_additional_columns "was documented but unused" until this release — meaning a documented, user-visible configuration option was a no-op in production for at least one version, with nothing catching it. That is the same class of defect as the untested compatibility claims and the anomalous release date: the project's stated behaviour is not reliably backed by verification. For us the practical reading is that every documented option must be smoke-tested ourselves, not trusted from the README.
Two new risk vectors arrive with the feature itself. First, CSV/formula injection: operator-supplied titles and default values are written into CSV and XLSX cells, and a value beginning with =, +, -, or @ is interpreted as a formula by Excel and by most CSV consumers. If the package does not neutralise leading formula characters, an operator can produce a file that executes on a colleague's machine — low likelihood internally, but it is a recognised finding in any security review of an export feature, and it is now reachable without a code change. Second, precedence ambiguity: there is both a per-action disableAdditionalColumns() and a global disable_additional_columns config key, and the release notes do not state which wins. If the config key is meant as an administrative kill switch, it must override the action; if it is a default, it must not. That must be verified, because we will likely want the global switch set to "disabled" at rollout.
Key questions for the maintainer / spike.
canViewColumn() / policies and Filament's authorization callbacks?=, +, -, @ neutralised in CSV and XLSX output?disableAdditionalColumns() and disable_additional_columns — is the config key an administrative override or just a default?Stack fit. Clean if we are on Laravel 11+ and Filament v4+. If any panel is still on Filament v3 or Laravel 10, this is blocked and we should either upgrade first or evaluate the predecessor package for that panel. Confirm the PHP constraint against our runtime images before any further analysis — a mismatch ends the conversation cheaply. 1.2.0 does not change the constraint picture, so any answer we already have stands.
Migration path. Treat alperenersoy/filament-export as the incumbent. Inventory every table currently exposing export, record the format set and column config for each, then port import-for-import into the new action. Run both behind a per-panel feature flag for one sprint and diff the outputs on a representative table — column order, formatting, date/timezone handling, and null representation are where successor packages typically diverge. Retire the old package only after parity sign-off, and keep the old action's configuration in version control as the reference. The additional-columns UI has no counterpart in the predecessor, so it is additive scope rather than a parity concern — but decide explicitly whether it is on or off at each migration step, so the diff stays interpretable.
Compatibility. Check for conflicts with other Filament plugins that inject table header actions or wrap the table query — those collisions surface at runtime, not at install. Pin the package to an exact version, not a caret range; a single-maintainer package with a fast release cadence is not one to float. Note that the release notes' own upgrade instruction — composer require occtherapist/advanced-table-export-for-filament:^1.2 — floats the minor, which is exactly the practice we are avoiding. Translate it to an exact 1.2.0 pin in our composer.json and rely on the lockfile. The release is additive and non-breaking, so upgrading from a hypothetical 1.1.x carries no migration work; from nothing, it is a fresh install either way.
Sequencing.
1.2.0, wire one real table, export 10k rows in all six formats, capture memory, wall-clock, and output fidelity. Exercise the additional-columns modal at least once, including a value beginning with =, and inspect the resulting CSV/XLSX in a real spreadsheet application. This single exercise answers most of the risk.disable_additional_columns enabled (feature off) and turn it on deliberately once step 2's injection check passes, so the pilot isolates schema-derived export from operator-supplied export.Maintenance. We own a dependency with no downstream community to absorb breakage. Budget a recurring quarterly review of upstream activity and manual per-release review — no automated dependency-bot merges here. 1.2.0 sharpens the case for manual review: a dead config key survived a release cycle unnoticed, which is precisely the kind of defect an automated bump would have carried into our environment silently. Every documented option in a new release should be exercised once on the pilot table before the pin moves. If the maintainer goes quiet, our options are fork-and-maintain or rebuild the thin layer over our own spreadsheet library; the fork path is viable precisely because the package is a leaf, which is its strongest operational argument.
Support. No commercial backing, no SLA, no evident security policy. That is acceptable for an internal admin convenience feature and unacceptable for anything customer-facing or compliance-scoped. Name an internal owner. 1.2.0 adds a user-facing modal, which converts a silent background capability into a feature operators will ask questions about — expect a small but real trickle of "how do I add a column" tickets and route them to that owner.
Scaling. Default execution is synchronous inside a web request, so PHP memory_limit and max_execution_time are the hard ceiling. XLSX and PDF are the expensive paths; CSV and clipboard are cheap. The additional-columns feature does not change the cost curve materially — a handful of extra scalar columns is noise against the row count — so the sizing analysis from the previous assessment stands. If the package lacks queued exports, we wrap the action so anything above a row threshold dispatches a job, writes to object storage, and notifies the operator. That wrapper is worth building early — retrofitting it after operators have formed the habit of exporting everything is disruptive.
Failure modes and mitigations.
disable_additional_columns or wrap the export to sanitise leading =/+/-/@.Ramp-up. Low for anyone already fluent in Filament — an afternoon to first working export. The additional-columns UI adds no engineering ramp-up, though it does add a short operator-communication task: a one-paragraph note in the admin guide on what the fields do and when to leave them blank. The real effort remains configuration, container/driver provisioning, and authorization design. Plan accordingly: the plugin is easy, the surrounding guarantees are not.
Recommendation. Proceed to the timeboxed spike, not a commitment, with the spike scope extended by half a day to cover the 1.2.0 additional-columns path and its escaping behaviour. The functional fit is genuinely good and the build-vs-buy math favours buying; the adoption risk is the deciding variable, and it is cheap to measure. Gate production rollout on the spike passing explicit memory, fidelity, authorization, and injection criteria, enable the new modal only after that gate clears, and pin to 1.2.0 exactly until the package has dependents and a stable release history behind it.
How can I help you explore Laravel packages today?