npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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

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-sheet

Univer, 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