Installation
Requirements
- PHP 8.3 or newer
- Laravel 12 or 13
- Filament 4.13 or newer, or Filament 5
- A desktop browser for editing (keyboard, pointer, clipboard); on a touch screen 1.x reads, searches, filters and pages a sheet, editing by touch is planned
1. Require the package
composer require packstub/filament-spreadsheet
php artisan filament:assets
There are no migrations: the sheet reads and writes your own columns. The grid engine (Tabulator, MIT) is bundled into the package's assets, so there is nothing to install on the JavaScript side; the script and the stylesheet load only on pages that show a sheet. Run php artisan filament:assets again after every update of the package: Filament copies the assets into public/.
The config file is optional; publish it to change the defaults (rows per page, the save mode, the version column, keyboard shortcuts, date formats):
php artisan vendor:publish --tag=packstub-spreadsheet-config
Registering the plugin on a panel is optional too (the pages work without it): ->plugin(SpreadsheetPlugin::make()).
2. Add a sheet page
A sheet lives on a page. SpreadsheetResourcePage sits next to a resource's list and takes the resource's query and abilities; SpreadsheetPage is a standalone panel page with its own query(). Both ask for one method, spreadsheet(). Your first sheet walks through the resource page; A sheet outside a resource through the other.
3. Configuration
config/packstub-spreadsheet.php:
| Key | Default | What it does |
|---|---|---|
per_page |
100 |
Rows per page a sheet opens with (perPage() on a definition wins) |
max_per_page |
1000 |
The most rows the page-size control offers |
max_rows_per_save |
2000 |
The most rows (updates + creates + deletes) one Save may carry; a paste past the last row stops creating rows there |
save_mode |
all_or_nothing |
all_or_nothing or per_row (see Saving); any other value throws |
version_column |
updated_at |
The attribute compared before a row is written; null turns the check off |
confirm_leave |
true |
Ask before leaving the page with unsaved changes |
frozen_first_column |
false |
Pin the first column while scrolling sideways (Tabulator warns a pinned column beside the row numbers can misbehave with range selection) |
filters_layout |
dropdown |
Where the filters are: dropdown behind a funnel button, toolbar inline, above the grid (filtersLayout() on a definition wins) |
row_height |
32 |
Pixels |
keybindings |
[] |
Overrides: save, fill_down, undo, redo, add_row, cut as mod+s-style strings (mod is Ctrl or ⌘) |
date_format |
Y-m-d |
PHP format a date cell shows (format() on a column wins) |
datetime_format |
Y-m-d H:i |
PHP format a date-time cell shows |
decimal_separator |
null |
The decimal mark a typed or pasted number with one separator is read by (0,125): null follows app()->getLocale(), or ',' / '.' |