Spreadsheet
A spreadsheet viewer that shows .xlsx workbooks the way Excel does. Column widths, row heights, text fitting, number formats, border precedence, the gridlines and the selection are measured from Excel itself — thousands of samples captured on a real Excel — not approximated. The workbook is read in the browser by a dependency-free reader; macros are kept and never run.
The same engine — @oge-ui/spreadsheet-engine, framework-free — runs the Angular <oge-spreadsheet> and the React <OgeSpreadsheet>, with the same markup and stylesheet: a workbook looks and works the same in both.
@oge-ui/spreadsheet is a commercial package — free for evaluation and development, with no notice on development hosts; production use needs a license key. See licensing for the terms.
Getting started
Point source at a workbook. Arrows, Ctrl+arrows, Shift to extend, Ctrl+A, Ctrl+F, Ctrl+C, Ctrl+Page Down and Ctrl+wheel work as in Excel; the status bar sums the selection.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeSpreadsheet } from '@oge-ui/spreadsheet';
@Component({
selector: 'demo-root',
imports: [OgeSpreadsheet],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- One element shows an .xlsx file the way Excel does: its fonts,
number formats, borders, fills, conditional formats, frozen panes,
merges, notes, links and pictures. [source] takes a URL, the file's
bytes or a File; reading happens in the browser, with no dependency. -->
<oge-spreadsheet
source="/demo/spreadsheet/structure.xlsx"
style="height: 520px"
/>
`,
})
export class Demo {}Open your own file
Pick any workbook — it is read in your browser and never uploaded. (loaded) lists what could not be shown as Excel shows it.
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { OgeSpreadsheet } from '@oge-ui/spreadsheet';
@Component({
selector: 'demo-root',
imports: [OgeSpreadsheet],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- Pick or drop any workbook: nothing leaves the browser. What the
reader could not show as Excel does arrives in (loaded)'s issues. -->
<input type="file" accept=".xlsx,.xlsm" (change)="pick($event)" />
<oge-spreadsheet
[source]="file()"
(loaded)="issues.set($event.issues.length)"
style="height: 520px"
/>
<p>{{ issues() }} things shown differently from Excel</p>
`,
})
export class Demo {
protected readonly file = signal<File | null>(null);
protected readonly issues = signal(0);
protected pick(event: Event): void {
this.file.set((event.target as HTMLInputElement).files?.[0] ?? null);
}
}