Multi-Sheet Workbook
Since v1.3.0 a ReoGrid instance is a workbook of N worksheets with one active sheet. The core renders a sheet tab bar (add, rename, drag-to-reorder, hide, tab color), each sheet keeps its own data, selection, scroll, frozen panes, and undo history, and formulas can reference cells on other sheets with =Sheet1!A1.
Multi-sheet works in both Lite and Pro. Tier guards and row/column limits apply per sheet.
Upgrading from single-sheet? Existing code is unchanged — a fresh grid still starts with one sheet. The only visible difference is a ~28 px sheet tab bar at the bottom. Pass
createReogrid({ showSheetTabs: false })to hide it.
Creating a workbook
The instance exposes a workbook coordinator. The first sheet is created for you; add more with addSheet.
import { createReogrid } from '@reogrid/lite'
const grid = createReogrid({
workspace: '#app',
initialSheetName: 'Sales', // optional — defaults to 'Sheet1'
})
// Add more sheets
const expenses = grid.workbook.addSheet('Expenses').worksheet
const summary = grid.workbook.addSheet('Summary').worksheet
// The active sheet is always available as grid.worksheet
grid.worksheet.cell('A1').setValue('Q1 report')
addSheet(name?, index?) returns a WorkbookSheet — { worksheet, actionManager }. Use .worksheet to read and write its cells, exactly like a single-sheet grid.
Workbook options
| Option | Type | Default | Description |
|---|---|---|---|
showSheetTabs | boolean | true | Show the sheet tab bar at the bottom of the grid. |
initialSheetName | string | 'Sheet1' | Name of the sheet created on init. |
The workbook coordinator
grid.workbook manages the set of sheets and the active selection.
const wb = grid.workbook
wb.addSheet('Data') // append a sheet (optionally at an index)
wb.renameSheet(1, 'Archive') // names are sanitized and de-duplicated
wb.moveSheet(2, 0) // reorder (active sheet stays stable)
wb.setActiveSheet(0) // switch the active sheet
wb.removeSheet(1) // refuses to remove the last remaining sheet
wb.getSheets() // WorkbookSheet[] in tab order
wb.getWorksheets() // the Worksheet objects
wb.getSheetNames() // ['Sales', 'Archive', ...]
| Method | Description |
|---|---|
addSheet(name?, index?) | Add a sheet; returns the new WorkbookSheet. |
removeSheet(index) | Remove a sheet (never the last one). |
renameSheet(index, name) | Rename; referencing formulas on every sheet are rewritten. |
moveSheet(from, to) | Reorder tabs. |
setActiveSheet(index) | Make a sheet active. |
getSheets() / getWorksheets() / getSheetNames() | Query the workbook. |
setSheetHidden(index, hidden) | Hide / unhide a sheet. |
setSheetTabColor(index, color) | Set or clear a tab color (CSS color string). |
Whole-workbook I/O
I/O methods on the instance operate on all sheets. (The per-worksheet worksheet.loadXlsx() loads only into the active sheet.)
// Export the whole workbook to .xlsx (triggers a download)
grid.saveAsXlsx({ filename: 'report.xlsx' })
// Load every sheet from a File / URL / ArrayBuffer
await grid.loadFromFile(file)
await grid.loadFromUrl('/data/book.xlsx')
await grid.loadXlsx(arrayBuffer)
// JSON serialization (round-trips all sheets + view state)
const doc = grid.toJson()
grid.loadJson(doc)
Workbook view state round-trips through xlsx: the active sheet, per-sheet hidden state, and tab colors are written on export and restored on load (ReoGrid-JSON also preserves each sheet’s showGridlines).
Reacting to sheet changes
grid.workbook.onActiveSheetChange((index) => {
console.log('active sheet is now', index)
})
grid.workbook.onSheetsChange(() => {
// fires on add / remove / rename / move / metadata change
console.log('tabs:', grid.workbook.getSheetNames())
})
Each subscribe call returns an unsubscribe function.
Instance-level events follow the active sheet
Subscribe once on the instance and the listener automatically re-points to whichever sheet is active — no re-binding when the user switches tabs.
grid.onSelectionChange((range) => { /* active sheet's selection */ })
grid.onCellValueChange(({ row, column, value }) => { /* ... */ })
Available: onSelectionChange, onCellValueChange, onBulkCellsChange, onScrollChange, onViewportSizeChange, onStructureChange, onContextMenu. See Selection & Events for payload shapes.
Cross-sheet formulas
Formulas can reference cells on other sheets — =Sheet1!A1, ='My Sheet'!A1:B2, even non-ASCII names like =シート1!A1. Renaming a sheet rewrites referencing formulas; deleting one turns references into #REF!. Full details and lifecycle rules are in the Formula Engine — Cross-sheet references section.
// On the Summary sheet, consolidate three branch sheets:
summary.cell('B2').value = "='Tokyo'!E6"
summary.cell('B3').value = "='Osaka'!E6"
summary.cell('B4').value = "='Nagoya'!E6"
summary.cell('B5').value = '=SUM(B2:B4)'
React & Vue
Both wrappers expose the workbook through the instance and emit sheet events.
// React
<Reogrid
onReady={(grid) => grid.workbook.addSheet('Data')}
onActiveSheetChange={(index) => console.log('active', index)}
onSheetsChange={() => console.log('sheets changed')}
/>
<!-- Vue -->
<Reogrid
@ready="grid => grid.workbook.addSheet('Data')"
@active-sheet-change="index => console.log('active', index)"
@sheets-change="() => console.log('sheets changed')"
/>
Live demo
See the Multi-Sheet Workbook demo — three branch sheets plus a Summary sheet built entirely from cross-sheet formulas. Edit any branch and watch the totals recalculate across sheets.