Exports
Lists can be exported as Excel (.xlsx) or CSV. The export contains what
the user sees: search, filters, sort and the visible columns.
final class DealResource extends Resource{ protected bool $exportable = true; // adds the permission "deals.export"}The export button appears in the toolbar for users with <slug>.export.
Records a policy refuses to show are left
out of the file, as on the detail page.
Small and large exports
Section titled “Small and large exports”| Rows | What happens |
|---|---|
up to exportSyncLimit (1000) |
the file is created right away and downloaded |
| more | a queue job creates the file; the user gets a notification with the download link |
more than exportMaxRows (100 000) |
rejected, the user is asked to filter the list |
Large exports need a queue worker (codeigniter4/queue, database handler):
php spark migrate --all # queue tables, anvil_exportsphp spark queue:work anvil # e.g. as a systemd service or supervisor programThe queue name is Config\Anvil::$exportQueue (anvil); Anvil registers
its job handler with the queue itself.
The job runs on behalf of the requesting user (Anvil\Security\RunAs):
the tenant, scopeQuery() and permissions are the same as in the list,
and the export permission is checked again before the file is written.
Files and downloads
Section titled “Files and downloads”- Files are stored outside of the web root (
WRITEPATH/anvil/exports,Config\Anvil::$exportPath) under random names. - Downloads go through
/<panel>/_export/<uuid>. Only the user who requested an export can download it, in the same tenant and panel, while they still have the export permission, and forexportTtlseconds (24 hours). Downloads are sent withCache-Control: no-storeandContent-Security-Policy: sandbox, and are rate limited. - A queued export runs in the tenant of the export; if the user left the tenant meanwhile, it fails. A failed export leaves no partial file.
php spark anvil:prunedeletes expired and failed exports (and old, read notifications, old API access log entries and stored API answers); schedule it daily.
Content
Section titled “Content”- Each column contributes
Column::exportValue(): numeric, money and count columns are numbers; other columns are the text shown in the list (labels, formatted dates). Own columns can override it, see Extending. - Excel cells are always written as text or numbers, never as formulas.
In CSV files, values starting with
=,+,-,@,|,%, tab, carriage return, line feed or their full-width forms get a leading apostrophe, so spreadsheets do not run them as formulas (CSV injection). - CSV files use UTF-8 with BOM and the separator of the locale (
;with a decimal comma, otherwise,).
Every export request (export.requested, with resource, format, rows,
search and filters) and every download (export.downloaded) is written to
the audit log.