@worksheet-js/react
v1.4.0
Published
Official React component for Worksheet.js, providing a seamless spreadsheet experience in React apps.
Downloads
897
Readme
@worksheet-js/react
Industrial-grade spreadsheet UI engine for React.
@worksheet-js/react provides a seamless integration of the Worksheet.js engine into React applications. It wraps the high-performance canvas renderer in a declarative component while giving you full imperative control via ref and the useWorksheet hook.
Table of Contents
- Installation
- License Initialization
- Quick Start
- Advanced Usage
- Component API
- Options Reference
- TypeScript
- Next.js / SSR
- License
Installation
npm install @worksheet-js/core @worksheet-js/react chart.js
# or
pnpm add @worksheet-js/core @worksheet-js/react chart.js
# or
yarn add @worksheet-js/core @worksheet-js/react chart.jsPeer dependencies:
| Package | Required Version |
| :---------- | :--------------- |
| react | >= 16.8.0 |
| react-dom | >= 16.8.0 |
| chart.js | >= 4.0.0 |
License Initialization
@worksheet-js/core is proprietary software. Call initializeLicense() once at application startup, before any spreadsheet is rendered.
// main.tsx — application entry point
import React from 'react';
import ReactDOM from 'react-dom/client';
import { initializeLicense } from '@worksheet-js/core';
import App from './App';
initializeLicense('YOUR-LICENSE-KEY');
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
);To obtain a license key, contact [email protected].
Quick Start
import React from 'react';
import { Worksheet } from '@worksheet-js/react';
// initializeLicense() called in main.tsx
export function App() {
return (
<div style={{ width: '100vw', height: '100vh' }}>
<Worksheet
options={{
worksheets: [{ worksheetName: 'Sheet1' }],
toolbar: true,
formulaBar: true,
}}
/>
</div>
);
}Advanced Usage
Using useWorksheet
useWorksheet() returns a typed ref that you attach to the component. Once mounted, ref.current exposes the full @worksheet-js/core instance API.
import React, { useEffect } from 'react';
import { Worksheet, useWorksheet } from '@worksheet-js/react';
export function Dashboard() {
const ref = useWorksheet();
useEffect(() => {
const ws = ref.current;
if (!ws) return;
// Populate headers
ws.setValue('A1', 'Product');
ws.setValue('B1', 'Q1');
ws.setValue('C1', 'Q2');
ws.setValue('D1', 'Total');
// Style headers
['A1', 'B1', 'C1', 'D1'].forEach((addr) => {
ws.setStyle(addr, { bold: true, backgroundColor: '#1a1a2e', color: '#ffffff' });
});
// Data with formula
ws.setValue('A2', 'Widget A');
ws.setValue('B2', '15000');
ws.setValue('C2', '18000');
ws.setValue('D2', '=SUM(B2:C2)');
// Listen for value changes
ws.on('onchange', (_sheet, _cell, x, y, value) => {
console.log(`[${x},${y}] → ${value}`);
});
}, [ref]);
return (
<div style={{ height: '600px' }}>
<Worksheet ref={ref} options={{ worksheets: [{ worksheetName: 'Dashboard' }] }} />
</div>
);
}Loading XLSX Files
import React, { useCallback } from 'react';
import { Worksheet, useWorksheet } from '@worksheet-js/react';
export function FileLoader() {
const ref = useWorksheet();
const handleFile = useCallback(
async (e: React.ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
if (!file || !ref.current) return;
await ref.current.importFromFile(file);
},
[ref]
);
return (
<div>
<input type="file" accept=".xlsx,.csv" onChange={handleFile} />
<div style={{ height: '500px' }}>
<Worksheet ref={ref} options={{ worksheets: [{ worksheetName: 'Import' }] }} />
</div>
</div>
);
}Listening to Events
import React, { useEffect, useState } from 'react';
import { Worksheet, useWorksheet } from '@worksheet-js/react';
export function TrackedSheet() {
const ref = useWorksheet();
const [selection, setSelection] = useState('—');
useEffect(() => {
const ws = ref.current;
if (!ws) return;
ws.on('onselection', (_sheet, x1, y1, x2, y2) => {
setSelection(`[${x1},${y1}] → [${x2},${y2}]`);
});
// Cleanup on unmount
return () => ws.destroy();
}, [ref]);
return (
<div>
<p>
Current selection: <strong>{selection}</strong>
</p>
<div style={{ height: '400px' }}>
<Worksheet ref={ref} options={{ worksheets: [{ worksheetName: 'Data' }] }} />
</div>
</div>
);
}Performance Monitoring
import React, { useEffect } from 'react';
import { Worksheet, useWorksheet } from '@worksheet-js/react';
export function MonitoredSheet() {
const ref = useWorksheet();
useEffect(() => {
const ws = ref.current;
if (!ws) return;
const id = setInterval(() => {
const snap = ws.getPerfSnapshot();
console.table({
'Render P95 (ms)': snap.renderMs.p95,
'Paint P95 (ms)': snap.paintMs.p95,
'Scroll FPS (mean)': snap.scrollFps.mean,
'Formula P95 (ms)': snap.formulaMs.p95,
'Cell Memory (KB)': snap.estimatedCellMemoryKB.mean,
});
}, 5000);
return () => clearInterval(id);
}, [ref]);
return (
<div style={{ height: '500px' }}>
<Worksheet ref={ref} options={{ worksheets: [{ worksheetName: 'Monitor' }] }} />
</div>
);
}Component API
<Worksheet> Props
| Prop | Type | Default | Description |
| :---------- | :--------------------- | :------ | :--------------------------------------------------------------------------------------------------------------------- |
| options | WorksheetOptions | — | Required. Configuration passed to @worksheet-js/core. Do not include container — it is managed internally. |
| ref | React.Ref<Worksheet> | — | Attach a useWorksheet() ref to access the full core instance. |
| className | string | '' | CSS class name applied to the wrapper <div>. |
| style | React.CSSProperties | {} | Inline styles applied to the wrapper <div>. |
Ref Methods (via useWorksheet())
When a ref is attached, ref.current exposes the full Worksheet instance from @worksheet-js/core:
const ref = useWorksheet();
// Data
ref.current.getValue('A1');
ref.current.setValue('A1', 'Hello');
ref.current.setStyle('A1', { bold: true });
// I/O
ref.current.importFromFile(file);
ref.current.exportXlsx('report.xlsx');
// Sheet management
ref.current.addWorksheet({ worksheetName: 'Sheet2' });
ref.current.deleteWorksheet(1);
ref.current.renameWorksheet(0, 'Summary');
// Navigation
ref.current.goto(0, 0);
ref.current.setZoom(125);
// Performance
ref.current.getPerfSnapshot();
// Events
ref.current.on('onchange', handler);
ref.current.off('onchange', handler);
// Cleanup
ref.current.destroy();See the @worksheet-js/core documentation for the complete API reference.
Options Reference
Pass all configuration via the options prop. The container property is managed by the component and must not be set.
| Option | Type | Default | Description |
| :----------------- | :----------------------------- | :-------: | :--------------------------------------------------- |
| worksheets | Partial<SheetMeta>[] | [{}] | Initial sheet tabs (name, dimensions, frozen panes). |
| toolbar | boolean | true | Show the ribbon toolbar. |
| formulaBar | boolean | true | Show the formula input bar. |
| theme | 'light' \| 'dark' | 'light' | Color theme. |
| defaultColWidth | number | 100 | Default column width in pixels. |
| defaultRowHeight | number | 24 | Default row height in pixels. |
| frozenRows | number | 0 | Rows frozen at the top. |
| frozenCols | number | 0 | Columns frozen at the left. |
| licenseKey | string | — | License key (alternative to initializeLicense()). |
| onSave | (data: any) => Promise<void> | — | Callback for Ctrl+S / save button. |
TypeScript
All exports are fully typed. Import types from @worksheet-js/core:
import type {
WorksheetOptions,
CellStyle,
SelectionRange,
SheetMeta,
CellAddress,
} from '@worksheet-js/core';
import { Worksheet, useWorksheet } from '@worksheet-js/react';
const options: WorksheetOptions = {
worksheets: [{ worksheetName: 'Typed Sheet' }],
toolbar: true,
theme: 'dark',
};
function App() {
const ref = useWorksheet(); // React.RefObject<Worksheet>
return <Worksheet ref={ref} options={options} />;
}Next.js / SSR
Because Worksheet.js uses canvas and Web Workers, it must run in a browser environment. In Next.js, use dynamic imports with ssr: false:
// components/SpreadsheetWrapper.tsx
'use client'; // App Router
import dynamic from 'next/dynamic';
const Worksheet = dynamic(() => import('@worksheet-js/react').then((m) => m.Worksheet), {
ssr: false,
});
export function SpreadsheetWrapper() {
return (
<div style={{ height: '600px' }}>
<Worksheet options={{ worksheets: [{ worksheetName: 'Sheet1' }] }} />
</div>
);
}Call initializeLicense() inside a useEffect or in a client-only entry file when using SSR frameworks.
License
@worksheet-js/react is open-source software released under the MIT License.
The underlying engine (@worksheet-js/core) is proprietary software subject to the EULA. A valid license key is required to use it.
Copyright © 2024-present Worksheet Systems.
