Spreadsheet + Ribbon bar
The whole Excel surface as one component, <SvSheet workbook={wb} />: a six-tab ribbon (Home, Insert, Formulas, Data, Review, View), the Name Box and fx bar, sheet tabs and the Sum / Average / Count status bar. Format cells, merge them, comment on them, validate what goes in, colour them by rule, filter the region, protect the sheet; every button is the same call as its shortcut, so Ctrl+B and the Bold button cannot drift. A two-sheet P&L with the formats travelling in the document. (requires @svgrid/enterprise)
A live, editable Svelte 5 data grid example from the SvGrid gallery (Spreadsheet). See the SvGrid documentation for the full API.
About this example
The whole Excel surface on a Svelte 5 grid as one component, <SvSheet workbook={wb} />: a six-tab ribbon (Home, Insert, Formulas, Data, Review, View), the Name Box and fx bar, sheet tabs and the Sum, Average and Count status bar, all from @svgrid/enterprise. The Budget sheet is a small P&L with formulas down every column and formats (a header band, thousands, a percent row) that travel with the document; Headcount is a second sheet. Bold, fills, number formats, Merge & Center, comments, data validation, conditional formatting, AutoFilter and Protect Sheet are all on the ribbon, and each button runs the same function as its keyboard shortcut. Enterprise, in @svgrid/enterprise.
The whole Excel surface as one component:
<SvSheet workbook={wb} />
That is the demo. The ribbon, the Name Box and fx bar, the A..I column headers over the 1..N gutter, the sheet tabs and the Sum / Average / Count status bar all come from @svgrid/enterprise rather than from this file. This demo used to carry about 1,400 lines of its own ribbon.
Ribbon buttons and keyboard shortcuts are the SAME calls. Click a bold cell and the Bold button lights up; press Ctrl+B and it goes out. Both run one function in sheet/shortcuts.ts, so they cannot drift.
Try: select B2:D4 and watch the status bar. Press Ctrl+Shift+4 or hit $ in the Number group. Ctrl+Down runs to the bottom of a block. The Formulas tab has Show Formulas (Excel's Ctrl+`).
The chrome is painted with the grid's own theme tokens, so the theme picker at the top left re-skins it along with everything else. Pick "Excel" to see it wearing Excel's palette.
Imports, features and API used
Imports: @svgrid/enterprise
Frequently asked questions
How much of this is the demo's own code?
Almost none. The file builds a workbook with createWorkbook, hands it to <SvSheet> with a formats map, and that is it; the ribbon, the formula bar, the tabs, the status bar and every dialog come from the component. The demo used to carry about 1,400 lines of its own ribbon.
Do the ribbon and the shortcuts stay in step?
Yes, by construction: a ribbon button and its shortcut run one function in the shell's shortcuts module. Click a bold cell and the Bold button lights; press Ctrl+B and it goes out.
How do the formats get there?
Through the formats prop, keyed by address (A1, or Headcount!A1 for the other sheet), the way a saved workbook carries them. They are per sheet, and getState() returns them with the rest of the document so a sheet can be saved and restored.
Related documentation
Related articles
- A Fill Handle (Drag to Fill) in SvGrid - Build a working spreadsheet-style fill handle on top of SvGrid's cell selection and editing - pointer tracking, range highlighting, series fill, and undo/redo integration all covered.
- Pivot Tables in Svelte - Summarize Data Without a Spreadsheet - Run a cross-tab pivot directly inside your Svelte app using @svgrid/enterprise createPivotModel - no Excel, no server-side aggregation, no stale exports.
- Spreadsheet-Style Cell Range Selection in SvGrid - How to enable drag-to-select cell ranges, read live selection state, and build a status-bar footer that sums and averages the selected values.
Source code (27-spreadsheet-ribbon.svelte)
<script lang="ts">
/**
* 27. Spreadsheet shell
* ----------------------
* The whole Excel surface as one component:
*
* <SvSheet workbook={wb} />
*
* That is the demo. The ribbon, the Name Box and fx bar, the A..I column
* headers over the 1..N gutter, the sheet tabs and the Sum / Average /
* Count status bar all come from @svgrid/enterprise rather than from this
* file. This demo used to carry about 1,400 lines of its own ribbon.
*
* Ribbon buttons and keyboard shortcuts are the SAME calls. Click a bold
* cell and the Bold button lights up; press Ctrl+B and it goes out. Both
* run one function in sheet/shortcuts.ts, so they cannot drift.
*
* Try: select B2:D4 and watch the status bar. Press Ctrl+Shift+4 or hit $
* in the Number group. Ctrl+Down runs to the bottom of a block. The
* Formulas tab has Show Formulas (Excel's Ctrl+`).
*
* The chrome is painted with the grid's own theme tokens, so the theme
* picker at the top left re-skins it along with everything else. Pick
* "Excel" to see it wearing Excel's palette.
*/
import { SvSheet, createWorkbook, type CellFormatEntry } from '@svgrid/enterprise'
// Formats travel with the document, the way they do in a saved workbook,
// rather than being something you re-apply every time it opens.
const BAND = { bold: true, fill: '#e2e8f0', color: '#0f172a' } as const
const TOTAL = { bold: true, numFmt: '#,##0' } as const
const MONEY = { numFmt: '#,##0' } as const
const PERCENT = { numFmt: '0.0%' } as const
// A small P&L: the kind of thing you would actually open Excel for. Row 1
// is a header band the way you would type it, not a grid header - in a
// spreadsheet the first row is just the first row.
const wb = createWorkbook([
{
name: 'Budget',
cells: [
['Line', 'Jan', 'Feb', 'Mar', 'Q1'],
['Subscriptions', '18200', '18900', '19500', '=SUM(B2:D2)'],
['Services', '4200', '3800', '5100', '=SUM(B3:D3)'],
['Support', '1200', '1250', '1310', '=SUM(B4:D4)'],
['Revenue', '=SUM(B2:B4)', '=SUM(C2:C4)', '=SUM(D2:D4)', '=SUM(E2:E4)'],
[],
['Payroll', '-9800', '-9800', '-10400', '=SUM(B7:D7)'],
['Cloud', '-940', '-1010', '-1180', '=SUM(B8:D8)'],
['Marketing', '-3200', '-2750', '-4100', '=SUM(B9:D9)'],
['Costs', '=SUM(B7:B9)', '=SUM(C7:C9)', '=SUM(D7:D9)', '=SUM(E7:E9)'],
[],
['Net', '=B5+B10', '=C5+C10', '=D5+D10', '=E5+E10'],
['Margin', '=B12/B5', '=C12/C5', '=D12/D5', '=E12/E5'],
],
},
{
name: 'Headcount',
cells: [
['Team', 'People', 'Cost each', 'Total'],
['Engineering', '6', '11000', '=B2*C2'],
['Design', '2', '9500', '=B3*C3'],
['Sales', '3', '8200', '=B4*C4'],
['', '=SUM(B2:B4)', '', '=SUM(D2:D4)'],
],
},
])
// A bare address formats the sheet that is active at mount (Budget); a
// sheet-qualified one reaches the other sheet, the way a formula would.
// Formats are per sheet, so a band on Budget's row 5 says nothing about
// Headcount's row 5.
const on = (sheet: string, cols: string, row: number, entry: CellFormatEntry) =>
Object.fromEntries([...cols].map((c) => [`${sheet}${c}${row}`, entry]))
const band = (row: number) => on('', 'ABCDE', row, BAND)
const total = (row: number) => on('', 'ABCDE', row, TOTAL)
const money = (row: number) => on('', 'BCDE', row, MONEY)
const percent = (row: number) => on('', 'BCDE', row, PERCENT)
const headcount = {
...on('Headcount!', 'ABCD', 1, BAND),
...on('Headcount!', 'CD', 2, MONEY), ...on('Headcount!', 'CD', 3, MONEY), ...on('Headcount!', 'CD', 4, MONEY),
...on('Headcount!', 'ABCD', 5, TOTAL),
}
</script>
<SvSheet
workbook={wb}
height="100%"
rows={24}
columns={9}
columnWidths={{ A: 150 }}
formats={{
...band(1),
...money(2), ...money(3), ...money(4),
...total(5),
...money(7), ...money(8), ...money(9),
...total(10),
...total(12),
...percent(13),
...headcount,
}}
/>More Spreadsheet examples
- Spreadsheet + formulas - Real formula engine inside the grid: cell refs (A1), ranges (A1:A10), SUM / AVG / IF / COUNTIF / ROUND, arithmetic, string concat, cycle detection.
- Per-cell custom borders (KPI) - Editable KPI scorecard. spreadsheetLayout paints spreadsheet-style per-edge custom borders via an absolute-positioned overlay (no border-collapse conflicts). Edit any quarter or target - the borders re-derive: green double = beat target, blue solid = hit, amber dotted = near miss, red dashed = bad miss; row champion gets a colored full frame.
- Cell merging (spreadsheet shell) - A real invoice rendered on an Excel-style shell: A / B / C / D / E column letters across the top, row numbers down the left. Brand band, bill-from / bill-to address blocks, meta block, line items, totals, notes, signatures - all assembled from MergeSpec + CellBorderSpec. Editable Qty / Rate / addresses / notes; totals recompute live.
- HyperFormula integration - Full HyperFormula engine wired into the grid as a peer-optional dep. Editable spreadsheet with A1-style cell refs, dozens of formulas across math (SUM / SUMIF), lookup (VLOOKUP / INDEX-MATCH), text (CONCAT / UPPER), date (TODAY / DATEDIF), logical (IF nests), financial (PMT / IRR / NPV), statistical (AVERAGE / MAX / RANK).
- Blank sheet - just type - An empty Excel-style sheet on a plain <SvGrid>: column-letter headers (A..Z), a built-in 1..N row gutter, a name box + formula bar with a browsable function picker, gridlines, range selection and a fill handle. A real HyperFormula engine underneath: type a literal or a formula like =SUM(B2:D2) / =IF(...) and every dependent cell recalculates live. Drag a row or column border to resize; right-click for Cut / Copy / Paste / Clear.