ngx-sheet-cloud
v1.0.0
Published
Cloudoffis Angular spreadsheet component powered by Cloudoffis — Excel/JSON I/O, formulas, filters, and parent-app cell linking.
Downloads
152
Maintainers
Readme
ngx-univer-sheet
Angular spreadsheet component built on Univer Sheets.
It provides an Excel-like grid plus a small Angular wrapper API for:
- loading
IWorkbookData - importing
.xlsx/.xls - exporting workbook data
- syncing editable cells with a parent app
- toggling between edit mode and view mode
Full usage guide: see docs/LIBRARY_GUIDE.md
(install, parameters, parent vs library, tested max file size ~47 MB, max rows ~1,00,000).
Supported Angular versions
| Angular | Support | |---------|---------| | 17.3+ | Supported (minimum) | | 18.x | Supported | | 19.x | Supported (primary / CI demo app) | | 20.x | Supported |
Why 17.3 minimum? The wrapper uses signal input() / output() and @if control flow, which require Angular 17.3+. Angular 17.0–17.2 are not supported.
This monorepo builds and runs the demo on Angular 19. Peer ranges allow 17.3 / 18 / 19 / 20 so the same published package can be installed in those apps. Validate import/export and edit/view mode in your target app after upgrading.
Install
npm install ngx-univer-sheetUniver, ExcelJS, and React are library dependencies — npm installs them automatically. Sheet CSS is injected by the component, so you do not need to edit angular.json styles.
If Angular warns about CommonJS, allow:
"allowedCommonJsDependencies": ["xlsx", "exceljs", "jszip"]Basic usage
import { Component, ViewChild, signal } from '@angular/core';
import type { IWorkbookData } from '@univerjs/core';
import { LinkedCellRow, UniverSheetComponent } from 'ngx-univer-sheet';
@Component({
standalone: true,
imports: [UniverSheetComponent],
template: `
<header class="app-toolbar">
<span>Excel Spreadsheet</span>
<label>
Import Excel
<input type="file" accept=".xlsx,.xls" (change)="onImport($event)" />
</label>
<button type="button" (click)="sheet.exportExcel()">Export Excel</button>
</header>
<ngx-univer-sheet
#sheet
[workbook]="workbook"
[readonly]="viewMode"
[showToolbar]="false"
(linkedCellsChange)="rows.set($event)"
(highlightChange)="highlight.set($event)"
(statusChange)="status.set($event)"
(initError)="error.set($event)"
/>
`,
})
export class AppComponent {
@ViewChild('sheet') sheet!: UniverSheetComponent;
workbook = {} as IWorkbookData;
viewMode = false;
rows = signal<LinkedCellRow[]>([]);
highlight = signal<string | null>(null);
status = signal<string | null>(null);
error = signal<string | null>(null);
onImport(event: Event): void {
const input = event.target as HTMLInputElement;
const file = input.files?.[0];
input.value = '';
if (file) {
void this.sheet.importExcel(file);
}
}
}Keep Import / Export / side panels in the parent app. The library focuses on the Excel grid and APIs.
Modes
The component supports both modes using the readonly input:
readonly = false:- grid is editable
- linked-cell updates are allowed
- import/export methods are allowed
readonly = true:- direct cell editing is blocked
- linked-cell updates are blocked
- import/export mutations are blocked
- selection and navigation still work
Formulas in view mode:
[recalculateOnLoad]="true"— recalculate once after first paint- omit /
false— show Excel cached values (faster for large files)
Excel import parses in a bundled Web Worker (works from published npm), caches the converted workbook by reference, opens the first ~1500 rows quickly, then fills the rest in the background. Use getLastImportedWorkbook() if the parent wants to persist the converted data. Await the HTTP blob before importExcel.
Data format
- Workbook input/output: Univer
IWorkbookData - Excel import:
excelFileToWorkbookData()uses ExcelJS-based parsing for.xls/.xlsx - Excel export:
workbookDataToXlsxBlob()uses ExcelJS and preserves formulas, fills, fonts, number formats, merges, column/row sizes, and floating images/logos from the current workbook snapshot - JSON import/export: use
loadWorkbook()/getWorkbookData()
Public API
Component inputs
| Input | Type | Default | Description |
|-------|------|---------|-------------|
| workbook | IWorkbookData \| null | null | Initial or updated workbook |
| showToolbar | boolean | false | Optional built-in toolbar (prefer parent-owned Import/Export UI) |
| readonly | boolean | false | Enables view mode when true |
| selectedSheet | string \| null | null | Optional sheet to open on load (e.g. Summary). If omitted, first/default sheet stays active |
| selectedCell | string \| null | null | Optional cell to select on load (e.g. E9). If omitted, only the sheet opens. Legacy Summary!E9 still works |
| toolbarTitle | string | 'Excel Spreadsheet' | Label when built-in toolbar is enabled |
| fileName | string \| null | null | Optional display name override |
| showFileName | boolean | false | Shows the current file name in the built-in toolbar |
| showLoader | boolean | false | Shows the built-in loading overlay during import/export when true |
| recalculateOnLoad | boolean | false | Recalculates formulas once after first paint when true. Omit or false to use Excel cached values (faster for large files) |
Component outputs
| Output | Description |
|--------|-------------|
| linkedCellsChange | Editable non-formula cells for parent-side forms/tables |
| highlightChange | A1 address of the currently highlighted linked cell |
| selectionContextChange | Current file name, active sheet name, and selected cell address |
| statusChange | Import/export status message or error text |
| initError | Initialization or workbook-load error |
Component methods
| Method | Description |
|--------|-------------|
| selectLinkedCell(address) | Focus a cell from a parent table/form |
| selectCell(address) | Select/highlight a cell (E9 or Sales!E9) |
| activateSelection({ sheetName, cell }) | Open sheet and/or select cell independently |
| importExcel(file) | Import .xlsx / .xls (also works in view mode) |
| exportExcel(fileName?) | Download current workbook as .xlsx (also works in view mode) |
| getExcelBlob() | Return current workbook as an .xlsx Blob without downloading |
| getLastImportedWorkbook() | Cloned IWorkbookData from the last import/load (for parent reopen cache) |
| setLinkedCellValue(address, value) | Push a parent edit into the sheet |
Optional built-in toolbar actions (only when [showToolbar]="true") can still be projected with:
<ngx-univer-sheet [showToolbar]="true" ...>
<button sheetToolbarActions type="button" (click)="sheet.exportExcel()">
Export Excel
</button>
</ngx-univer-sheet>| refreshLinkedCells() | Re-scan editable linked cells |
| getWorkbookData() | Return current IWorkbookData |
| loadWorkbook(data) | Replace the active workbook |
| onExportExcel() | Export current workbook as .xlsx |
| onExportJson() | Export current workbook as .json |
Exported helpers
import {
downloadBlob,
excelFileToWorkbookData,
workbookDataToXlsxBlob,
xlsFileToWorkbookData,
xlsxFileToWorkbookData,
type ExcelFileExtension,
} from 'ngx-univer-sheet';Known limitations
- Excel export preserves formulas, styles, merges, and sizes from the current Univer workbook snapshot. Some advanced Excel features (drawings/images, full CF rule objects, pivot tables) may not round-trip perfectly.
- The wrapper depends on many Univer peer packages, so consumer setup is heavier than a small Angular-only component.
Build and publish
From the monorepo root:
npm run build:lib
cd dist/ngx-univer-sheet
npm publish