vue-canvas-sheet
๐ Vue Canvas Sheet
A high-performance, Canvas-rendered Vue 3 spreadsheet component with a shared JS formula engine and optional Rust + WASM acceleration for verified numeric formulas. Built for million-cell workloads with an Excel-grade UX on the web.
ไธญๆๆๆกฃ ยท Usage Guide ยท Live Demo
โจ Highlights
- โก Canvas Cluster Rendering โ Pure Canvas 2D pipeline, 60 FPS scrolling at 100k+ rows with zero DOM overhead.
- ๐ฆ Rust + WASM Engine โ Accelerates the verified numeric-arithmetic subset; references, functions, strings, booleans, comparisons, and unsupported syntax use the shared JS RPN engine.
- ๐งต Worker + SharedArrayBuffer โ Calculation lives off the UI thread; the interface stays responsive under heavy load.
- ๐พ IndexedDB Persistence โ Diff-based incremental save with instant "cold start" reload via
enable-persistence. - ๐งฉ Headless-Friendly Core โ
Workbookruns standalone in Node.js or Web Workers; UI and core are fully decoupled. - ๐ค Realtime Collaboration โ Built-in plugin for shared cursors, selection sync, and per-cell edit locks over WebSocket.
- ๐ฅ Import / Export โ
.xlsx / .xls / .csv / .tsv / .jsonround-trip via dedicated plugins (Excel export runs in a worker). - ๐ Excel-Grade Features โ 100+ formulas, merged cells, frozen panes, conditional formatting, formula bar, undo/redo, find & replace.
๐ Benchmarks
| Workload (50,000 rows / 200,000 cells) | Time | Notes |
|---|---|---|
Initial load (setData) |
~200 ms | Includes parsing 50k dynamic formulas |
| First paint | ~16 ms | Hardware-accelerated Canvas, 60 FPS scroll |
๐ฆ Install
npm install vue-canvas-sheet
# or
pnpm add vue-canvas-sheet
# or
yarn add vue-canvas-sheet
The Rust/WASM engine is pre-built and shipped with the package โ no extra toolchain required.
Peer dependency: vue ^3.5.0.
๐ Quick Start
<template>
<div style="height: 600px; width: 100%;">
<TableDesigner
ref="table"
:initial-data="initialData"
enable-persistence
sheet-id="my-demo-sheet"
/>
</div>
</template>
<script setup>
import { TableDesigner } from 'vue-canvas-sheet';
import 'vue-canvas-sheet/style.css';
const initialData = [
['Name', 'Price', 'Qty', 'Total'],
['Product A', 10, 5, { f: '=B2*C2' }],
['Product B', 20, 3, { f: '=B3*C3' }],
['Total', { f: '=SUM(B2:B3)' }, { f: '=SUM(C2:C3)' }, { f: '=SUM(D2:D3)' }],
];
</script>
TableDesignerfills its parent โ make sure the parent has an explicit height.
๐งฉ Plugins
All plugins are factory functions exported from the package root.
import {
TableDesigner,
createSelectionHistoryPlugin,
createAutoSavePlugin,
createExportPlugin,
createImportPlugin,
createCollaborativeCursorPlugin,
createRealtimeCollaborationPlugin,
} from 'vue-canvas-sheet';
| Plugin | Purpose |
|---|---|
SelectionHistoryPlugin |
Forward/back navigation across selection history |
AutoSavePlugin |
Event-driven or interval autosave to IndexedDB / localStorage |
ExportPlugin |
Export to .xlsx (worker-backed), .csv, .json |
ImportPlugin |
Import .xlsx / .xls / .csv / .tsv / .json |
CollaborativeCursorPlugin |
Render remote users' cursors and selections |
RealtimeCollaborationPlugin |
Sync edits, selections, and per-cell locks via WebSocket |
CSV export prefixes formula-like text with a single quote by default. Use exportCSV({ allowFormulas: true }) only for trusted data that must retain spreadsheet formula semantics.
<TableDesigner :plugins="[historyPlugin, exportPlugin]" :initial-data="data" />
A reference WebSocket server is included โ run npm run collab:server to try collaboration locally.
๐ Workbook API (excerpt)
Grab the underlying Workbook from the component ref:
const wb = tableRef.value.workbook;
// Cells
wb.setCell(0, 0, { v: 100 });
wb.setCell(0, 1, { f: '=A1*2' });
const cell = wb.getCell(0, 1);
const value = wb.getCellValue(0, 1);
// Selection & styling
wb.setSelection(0, 0, 5, 5);
wb.setStyle(range, { bold: true, color: '#f00' });
wb.setBorder(range, 'all', '#000', 'solid');
// Structure
wb.mergeCells(range);
wb.setFreeze(1, 1);
wb.undo(); wb.redo();
// Engine
wb.registerFunction('DOUBLE', value => value * 2);
wb.setCell(0, 2, { f: '=DOUBLE(A1)' });
wb.enableWorker();
wb.recalcAll({ useWorker: true });
wb.getSystemReport();
// Events
const off = wb.on('cell-change', (changes) => { /* ... */ });
off();
See the documentation hub for the complete reference (usage, API, plugins, formulas).
โก Performance Tips
Large dataset, main-thread vectorized mode โ skip worker serialization overhead:
table.value.workbook.recalcAll({ useWorker: false });
Lazy loading for 50k+ rows:
<TableDesigner
:initial-data="data"
:lazy-load="{ enabled: true, pageSize: 100, maxCachedPages: 10, preloadPages: 1 }"
/>
Enable SharedArrayBuffer in production by serving these headers (required for multi-threaded WASM):
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
The engine gracefully falls back to main-thread execution when COOP/COEP is absent โ call wb.getSystemReport() to inspect the current state.
๐ Package Exports
import { TableDesigner, Workbook, SvgIcon } from 'vue-canvas-sheet';
import { Workbook as CoreWorkbook } from 'vue-canvas-sheet/core';
import { OffscreenRenderer } from 'vue-canvas-sheet/render';
๐งช Development
npm install
npm run dev # dev server (vite)
npm run demo # run samples/basic-usage
npm run test # unit tests (vitest)
npm run benchmark # performance benchmarks
npm run build # build WASM + JS bundle
npm run collab:server # reference collaboration server
๐ License
Apache License 2.0 โ Copyright ยฉ 2026-Present, Lee & Vue-Canvas-Sheet Team.
Related Packages
ๅบไบ Canvas + Vue 3 ็ๅจ็บฟ Excel ่กจๆ ผ็ปไปถ๏ผๅๅ ๆ ผๅๅนถใ่ก้ซๅๅฎฝๆๆฝใๅ ฌๅผๅผๆใ...
Blazing fast Excel (.xlsx) parser powered by Rust + WebAssembly. Lightweight, wo...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.0.0 | ^3.5.0 | Apache-2.0 |