@hewliyang/headless-spreadjs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # headless-spreadjs
2
+
3
+ Headless Excel workbook engine for Node.js — powered by [SpreadJS](https://developer.mescius.com/spreadjs) with DOM shims. No browser, no Excel, any platform including Linux.
4
+
5
+ ## Features
6
+
7
+ - **Full Excel fidelity** — 500+ formula functions, charts, pivot tables, tables, cell styling, merging, number formatting
8
+ - **XLSX I/O** — read and write `.xlsx, .xlsm` files with full roundtrip support
9
+ - **JSON serialization** — `toJSON()` / `fromJSON()` preserves everything (formulas, styles, charts, pivots)
10
+
11
+ ## System Dependencies
12
+
13
+ On Linux, install Cairo/Pango (required by the `canvas` npm package):
14
+
15
+ ```bash
16
+ sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
17
+ ```
18
+
19
+ macOS: `brew install pkg-config cairo pango libpng jpeg giflib librsvg`
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pnpm add headless-spreadjs
25
+ ```
26
+
27
+ ## Usage
28
+
29
+ ```js
30
+ import { init } from "headless-spreadjs";
31
+
32
+ // Initialize (with optional SpreadJS license key)
33
+ // If you use this for commercial purposes, please get a license from the madlads!
34
+ const { ExcelFile, GC, dispose } = await init({ licenseKey: "xxx" });
35
+
36
+ // Create a workbook from scratch
37
+ const file = new ExcelFile();
38
+ const sheet = file.workbook.getActiveSheet();
39
+ sheet.setValue(0, 0, "Name");
40
+ sheet.setValue(0, 1, "Score");
41
+ sheet.setValue(1, 0, "Alice");
42
+ sheet.setValue(1, 1, 95);
43
+ sheet.setValue(2, 0, "Bob");
44
+ sheet.setValue(2, 1, 87);
45
+ sheet.setValue(3, 0, "Average");
46
+ sheet.setFormula(3, 1, "AVERAGE(B2:B3)");
47
+ await file.save("output.xlsx");
48
+
49
+ // Open an existing workbook
50
+ const file2 = await ExcelFile.open("input.xlsx");
51
+ const val = file2.workbook.getActiveSheet().getValue(0, 0);
52
+ console.log(val);
53
+
54
+ // Access raw SpreadJS API
55
+ const workbook = file.workbook; // GC.Spread.Sheets.Workbook instance
56
+
57
+ // Clean up when done
58
+ dispose();
59
+ ```
60
+
61
+ ## API
62
+
63
+ ### `init(options?): { GC, ExcelFile, dispose }`
64
+
65
+ Initialize the headless runtime. Must be called before creating ExcelFiles.
66
+
67
+ | Option | Type | Description |
68
+ | ------------ | --------- | ------------------------------------------ |
69
+ | `licenseKey` | `string?` | SpreadJS license key. Omit for trial mode. |
70
+
71
+ ### `ExcelFile`
72
+
73
+ | Method | Description |
74
+ | ----------------------------------- | ---------------------------------------------- |
75
+ | `new ExcelFile()` | Create an empty workbook |
76
+ | `ExcelFile.open(path)` | Open an xlsx file → `Promise<ExcelFile>` |
77
+ | `ExcelFile.openFromBuffer(buf)` | Open xlsx from a Buffer → `Promise<ExcelFile>` |
78
+ | `file.save(path)` | Save to xlsx file → `Promise<void>` |
79
+ | `file.saveToBuffer()` | Save to Buffer → `Promise<Buffer>` |
80
+ | `file.toJSON()` | Serialize to SpreadJS JSON |
81
+ | `file.fromJSON(json)` | Load from SpreadJS JSON |
82
+ | `file.batch(fn)` | Suspend calc during `fn`, resume after |
83
+ | `file.workbook` | Raw `GC.Spread.Sheets.Workbook` instance |
84
+
85
+ ### `dispose()`
86
+
87
+ Close the happy-dom window to prevent memory leaks. Call when done with all workbooks.
88
+
89
+ ## Concurrency
90
+
91
+ `headless-spreadjs` installs DOM shims on `globalThis` (e.g. `window`, `document`, `navigator`), so a single Node.js process supports **one `init()` / `dispose()` lifecycle at a time**. You cannot safely run multiple workbook operations concurrently within the same process.
92
+
93
+ If you need parallelism, use separate processes (e.g. worker threads or child processes) — each gets its own global scope so the shims don't collide.
94
+
95
+ ## Docker
96
+
97
+ `headless-spreadjs` will run in an image as simple as follows
98
+
99
+ ```dockerfile
100
+ FROM node:20-slim
101
+ RUN apt-get update && apt-get install -y \
102
+ build-essential libcairo2-dev libpango1.0-dev \
103
+ libjpeg-dev libgif-dev librsvg2-dev \
104
+ && rm -rf /var/lib/apt/lists/*
105
+ ```
106
+
107
+ ## License
108
+
109
+ MIT (this package). SpreadJS requires a separate commercial license from [MESCIUS](https://developer.mescius.com/spreadjs).
@@ -0,0 +1,15 @@
1
+ import type { GCNamespace, SpreadWorkbook } from "./types.js";
2
+ export declare function setGC(gc: GCNamespace | null): void;
3
+ export declare class ExcelFile {
4
+ readonly workbook: SpreadWorkbook;
5
+ constructor(workbook?: SpreadWorkbook);
6
+ batch<T>(fn: () => T): T;
7
+ batch<T>(fn: () => Promise<T>): Promise<T>;
8
+ save(filePath: string): Promise<void>;
9
+ saveToBuffer(): Promise<Buffer>;
10
+ toJSON(): object;
11
+ fromJSON(json: object): void;
12
+ static open(filePath: string): Promise<ExcelFile>;
13
+ static openFromBuffer(buffer: Buffer): Promise<ExcelFile>;
14
+ }
15
+ //# sourceMappingURL=excel-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"excel-file.d.ts","sourceRoot":"","sources":["../src/excel-file.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA8I9D,wBAAgB,KAAK,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAElD;AAED,qBAAa,SAAS;IACpB,SAAgB,QAAQ,EAAE,cAAc,CAAC;gBAE7B,QAAQ,CAAC,EAAE,cAAc;IAKrC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IACxB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqBpC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3C,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAI/B,MAAM,IAAI,MAAM;IAIhB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;WAIf,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;WAO1C,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;CAKhE"}
@@ -0,0 +1,162 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { unzipSync, zipSync } from "fflate";
4
+ let gcRef = null;
5
+ function getGC() {
6
+ if (!gcRef) {
7
+ throw new Error("headless-spreadjs not initialized. Call init() first.");
8
+ }
9
+ return gcRef;
10
+ }
11
+ function stripEvalSheet(spread) {
12
+ for (let i = spread.getSheetCount() - 1; i >= 0; i--) {
13
+ if (spread.getSheet(i).name() === "Evaluation Version") {
14
+ spread.removeSheet(i);
15
+ }
16
+ }
17
+ }
18
+ function toArrayBuffer(buffer) {
19
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
20
+ }
21
+ function stripEvalSheetFromZip(buf) {
22
+ const zip = unzipSync(new Uint8Array(buf));
23
+ const wbXmlBytes = zip["xl/workbook.xml"];
24
+ if (!wbXmlBytes)
25
+ return buf;
26
+ const decoder = new TextDecoder();
27
+ const wbXml = decoder.decode(wbXmlBytes);
28
+ const sheetRe = /<sheet\s[^>]*name="Evaluation Version"[^>]*\/>/g;
29
+ const match = sheetRe.exec(wbXml);
30
+ if (!match)
31
+ return buf;
32
+ const ridMatch = /r:id="(rId\d+)"/.exec(match[0]);
33
+ if (!ridMatch)
34
+ return buf;
35
+ const rId = ridMatch[1];
36
+ const allSheets = [...wbXml.matchAll(/<sheet\s[^>]*\/>/g)];
37
+ const evalIndex = allSheets.findIndex((m) => m[0] === match[0]);
38
+ let newWbXml = wbXml.replace(match[0], "");
39
+ newWbXml = newWbXml.replace(/activeTab="(\d+)"/g, (_full, tabStr) => {
40
+ let tab = parseInt(tabStr, 10);
41
+ if (evalIndex >= 0 && tab >= evalIndex) {
42
+ tab = Math.max(0, tab - 1);
43
+ }
44
+ return `activeTab="${tab}"`;
45
+ });
46
+ const relsBytes = zip["xl/_rels/workbook.xml.rels"];
47
+ if (!relsBytes)
48
+ return buf;
49
+ const relsXml = decoder.decode(relsBytes);
50
+ const relRe = new RegExp(`<Relationship[^>]*Id="${rId}"[^>]*/>`, "g");
51
+ const relMatch = relRe.exec(relsXml);
52
+ let sheetPath = null;
53
+ if (relMatch) {
54
+ const targetMatch = /Target="([^"]+)"/.exec(relMatch[0]);
55
+ if (targetMatch) {
56
+ sheetPath = `xl/${targetMatch[1]}`;
57
+ }
58
+ }
59
+ const newRelsXml = relsXml.replace(relRe, "");
60
+ const ctBytes = zip["[Content_Types].xml"];
61
+ let newCtXml = null;
62
+ if (ctBytes && sheetPath) {
63
+ const ctXml = decoder.decode(ctBytes);
64
+ const partName = `/${sheetPath}`;
65
+ const overrideRe = new RegExp(`<Override[^>]*PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"[^>]*/>`, "g");
66
+ newCtXml = ctXml.replace(overrideRe, "");
67
+ }
68
+ const encoder = new TextEncoder();
69
+ const newZip = {};
70
+ for (const [name, data] of Object.entries(zip)) {
71
+ if (sheetPath && name === sheetPath)
72
+ continue;
73
+ if (name === "xl/workbook.xml") {
74
+ newZip[name] = encoder.encode(newWbXml);
75
+ }
76
+ else if (name === "xl/_rels/workbook.xml.rels") {
77
+ newZip[name] = encoder.encode(newRelsXml);
78
+ }
79
+ else if (name === "[Content_Types].xml" && newCtXml) {
80
+ newZip[name] = encoder.encode(newCtXml);
81
+ }
82
+ else {
83
+ newZip[name] = data;
84
+ }
85
+ }
86
+ return Buffer.from(zipSync(newZip));
87
+ }
88
+ function saveAsBuffer(spread, gc) {
89
+ return new Promise((resolve, reject) => {
90
+ spread.save((blob) => {
91
+ blob
92
+ .arrayBuffer()
93
+ .then((bytes) => resolve(stripEvalSheetFromZip(Buffer.from(bytes))))
94
+ .catch(reject);
95
+ }, (err) => reject(err), { fileType: gc.Spread.Sheets.FileType.excel });
96
+ });
97
+ }
98
+ function importWorkbook(bytes, gc) {
99
+ return new Promise((resolve, reject) => {
100
+ const spread = new gc.Spread.Sheets.Workbook();
101
+ spread.import(bytes, () => {
102
+ stripEvalSheet(spread);
103
+ resolve(spread);
104
+ }, (err) => reject(err), { fileType: gc.Spread.Sheets.FileType.excel });
105
+ });
106
+ }
107
+ export function setGC(gc) {
108
+ gcRef = gc;
109
+ }
110
+ export class ExcelFile {
111
+ workbook;
112
+ constructor(workbook) {
113
+ const gc = getGC();
114
+ this.workbook = workbook ?? new gc.Spread.Sheets.Workbook();
115
+ }
116
+ batch(fn) {
117
+ this.workbook.suspendCalcService(false);
118
+ try {
119
+ const result = fn();
120
+ if (result instanceof Promise) {
121
+ return result.finally(() => {
122
+ this.workbook.resumeCalcService(true);
123
+ });
124
+ }
125
+ this.workbook.resumeCalcService(true);
126
+ return result;
127
+ }
128
+ catch (error) {
129
+ this.workbook.resumeCalcService(true);
130
+ throw error;
131
+ }
132
+ }
133
+ async save(filePath) {
134
+ const bytes = await this.saveToBuffer();
135
+ const dir = path.dirname(filePath);
136
+ if (dir && dir !== ".") {
137
+ await fs.promises.mkdir(dir, { recursive: true });
138
+ }
139
+ await fs.promises.writeFile(filePath, bytes);
140
+ }
141
+ saveToBuffer() {
142
+ return saveAsBuffer(this.workbook, getGC());
143
+ }
144
+ toJSON() {
145
+ return this.workbook.toJSON();
146
+ }
147
+ fromJSON(json) {
148
+ this.workbook.fromJSON(json);
149
+ }
150
+ static async open(filePath) {
151
+ const gc = getGC();
152
+ const bytes = await fs.promises.readFile(filePath);
153
+ const spread = await importWorkbook(toArrayBuffer(bytes), gc);
154
+ return new ExcelFile(spread);
155
+ }
156
+ static async openFromBuffer(buffer) {
157
+ const gc = getGC();
158
+ const spread = await importWorkbook(toArrayBuffer(buffer), gc);
159
+ return new ExcelFile(spread);
160
+ }
161
+ }
162
+ //# sourceMappingURL=excel-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"excel-file.js","sourceRoot":"","sources":["../src/excel-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import { ExcelFile } from "./excel-file.js";
2
+ import type { GCNamespace } from "./types.js";
3
+ export { ExcelFile } from "./excel-file.js";
4
+ export type { GCNamespace, SpreadStyle, SpreadWorkbook, SpreadWorksheet, } from "./types.js";
5
+ export interface InitOptions {
6
+ licenseKey?: string;
7
+ }
8
+ export interface InitResult {
9
+ GC: GCNamespace;
10
+ ExcelFile: typeof ExcelFile;
11
+ dispose: () => void;
12
+ }
13
+ export declare function init(options?: InitOptions): Promise<InitResult>;
14
+ export declare function dispose(): void;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAS,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EACV,WAAW,EACX,WAAW,EACX,cAAc,EACd,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAoBD,wBAAsB,IAAI,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAsBrE;AAED,wBAAgB,OAAO,IAAI,IAAI,CAK9B"}
package/dist/index.js ADDED
@@ -0,0 +1,43 @@
1
+ import { ExcelFile, setGC } from "./excel-file.js";
2
+ import { disposeShims, installShims } from "./shims.js";
3
+ export { ExcelFile } from "./excel-file.js";
4
+ const optionalAddons = [
5
+ "@mescius/spread-sheets-charts",
6
+ "@mescius/spread-sheets-pivot-addon",
7
+ "@mescius/spread-sheets-shapes",
8
+ "@mescius/spread-sheets-slicers",
9
+ ];
10
+ let initialized = false;
11
+ let cachedGC = null;
12
+ async function importOptional(moduleName) {
13
+ try {
14
+ await import(moduleName);
15
+ }
16
+ catch {
17
+ // Optional addon is not installed.
18
+ }
19
+ }
20
+ export async function init(options) {
21
+ if (initialized && cachedGC) {
22
+ return { GC: cachedGC, ExcelFile, dispose };
23
+ }
24
+ installShims();
25
+ const spreadModule = await import("@mescius/spread-sheets");
26
+ const gc = (spreadModule.default ?? spreadModule);
27
+ await import("@mescius/spread-sheets-io");
28
+ await Promise.all(optionalAddons.map(importOptional));
29
+ if (options?.licenseKey) {
30
+ gc.Spread.Sheets.LicenseKey = options.licenseKey;
31
+ }
32
+ setGC(gc);
33
+ cachedGC = gc;
34
+ initialized = true;
35
+ return { GC: gc, ExcelFile, dispose };
36
+ }
37
+ export function dispose() {
38
+ disposeShims();
39
+ cachedGC = null;
40
+ initialized = false;
41
+ setGC(null);
42
+ }
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAGxD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAkB5C,MAAM,cAAc,GAAG;IACrB,+BAA+B;IAC/B,oCAAoC;IACpC,+BAA+B;IAC/B,gCAAgC;CACxB,CAAC;AAEX,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB,IAAI,QAAQ,GAAuB,IAAI,CAAC;AAExC,KAAK,UAAU,cAAc,CAAC,UAA2C;IACvE,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,mCAAmC;IACrC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAAqB;IAC9C,IAAI,WAAW,IAAI,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IAC9C,CAAC;IAED,YAAY,EAAE,CAAC;IAEf,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,wBAAwB,CAAC,CAAC;IAC5D,MAAM,EAAE,GAAG,CAAC,YAAY,CAAC,OAAO,IAAI,YAAY,CAAgB,CAAC;IAEjE,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;IAC1C,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC;IAEtD,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,QAAQ,GAAG,EAAE,CAAC;IACd,WAAW,GAAG,IAAI,CAAC;IAEnB,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,YAAY,EAAE,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAChB,WAAW,GAAG,KAAK,CAAC;IACpB,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function installShims(): void;
2
+ export declare function disposeShims(): void;
3
+ export declare function isShimInstalled(): boolean;
4
+ //# sourceMappingURL=shims.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shims.d.ts","sourceRoot":"","sources":["../src/shims.ts"],"names":[],"mappings":"AAiKA,wBAAgB,YAAY,IAAI,IAAI,CAyDnC;AAED,wBAAgB,YAAY,IAAI,IAAI,CAMnC;AAED,wBAAgB,eAAe,IAAI,OAAO,CAEzC"}
package/dist/shims.js ADDED
@@ -0,0 +1,187 @@
1
+ import canvas from "canvas";
2
+ import { Window } from "happy-dom";
3
+ let shimInstalled = false;
4
+ let windowInstance = null;
5
+ class NodeFileReader {
6
+ result = null;
7
+ error = null;
8
+ onload = null;
9
+ onerror = null;
10
+ onloadend = null;
11
+ readyState = 0;
12
+ done(result) {
13
+ this.readyState = 2;
14
+ this.result = result;
15
+ const event = { target: this };
16
+ this.onload?.(event);
17
+ this.onloadend?.(event);
18
+ }
19
+ fail(error) {
20
+ this.readyState = 2;
21
+ this.error = error;
22
+ const event = { target: this };
23
+ this.onerror?.(event);
24
+ this.onloadend?.(event);
25
+ }
26
+ readAsArrayBuffer(input) {
27
+ this.readyState = 1;
28
+ if (input instanceof ArrayBuffer) {
29
+ process.nextTick(() => this.done(input));
30
+ return;
31
+ }
32
+ if (isArrayBufferSource(input)) {
33
+ input
34
+ .arrayBuffer()
35
+ .then((bytes) => this.done(bytes))
36
+ .catch((error) => this.fail(error));
37
+ }
38
+ }
39
+ readAsBinaryString(input) {
40
+ this.readyState = 1;
41
+ if (!isArrayBufferSource(input)) {
42
+ return;
43
+ }
44
+ input
45
+ .arrayBuffer()
46
+ .then((bytes) => {
47
+ const data = new Uint8Array(bytes);
48
+ let text = "";
49
+ for (const value of data) {
50
+ text += String.fromCharCode(value);
51
+ }
52
+ this.done(text);
53
+ })
54
+ .catch((error) => this.fail(error));
55
+ }
56
+ readAsDataURL(input) {
57
+ this.readyState = 1;
58
+ if (!isArrayBufferSource(input)) {
59
+ return;
60
+ }
61
+ input
62
+ .arrayBuffer()
63
+ .then((bytes) => {
64
+ const mimeType = input.type ?? "application/octet-stream";
65
+ const base64 = Buffer.from(bytes).toString("base64");
66
+ this.done(`data:${mimeType};base64,${base64}`);
67
+ })
68
+ .catch((error) => this.fail(error));
69
+ }
70
+ readAsText(input, encoding) {
71
+ this.readyState = 1;
72
+ if (!isArrayBufferSource(input)) {
73
+ return;
74
+ }
75
+ input
76
+ .arrayBuffer()
77
+ .then((bytes) => {
78
+ const decoder = new TextDecoder(encoding ?? "utf-8");
79
+ this.done(decoder.decode(bytes));
80
+ })
81
+ .catch((error) => this.fail(error));
82
+ }
83
+ abort() { }
84
+ addEventListener(type, listener) {
85
+ if (!listener) {
86
+ return;
87
+ }
88
+ if (type === "load") {
89
+ this.onload = listener;
90
+ }
91
+ else if (type === "error") {
92
+ this.onerror = listener;
93
+ }
94
+ else {
95
+ this.onloadend = listener;
96
+ }
97
+ }
98
+ removeEventListener(type, listener) {
99
+ if (type === "load" && this.onload === listener) {
100
+ this.onload = null;
101
+ }
102
+ if (type === "error" && this.onerror === listener) {
103
+ this.onerror = null;
104
+ }
105
+ if (type === "loadend" && this.onloadend === listener) {
106
+ this.onloadend = null;
107
+ }
108
+ }
109
+ }
110
+ function isArrayBufferSource(value) {
111
+ return (typeof value === "object" &&
112
+ value !== null &&
113
+ "arrayBuffer" in value &&
114
+ typeof value.arrayBuffer === "function");
115
+ }
116
+ function setGlobal(name, value) {
117
+ try {
118
+ Object.assign(globalThis, { [name]: value });
119
+ }
120
+ catch {
121
+ Object.defineProperty(globalThis, name, {
122
+ value,
123
+ writable: true,
124
+ configurable: true,
125
+ });
126
+ }
127
+ }
128
+ export function installShims() {
129
+ if (shimInstalled) {
130
+ return;
131
+ }
132
+ const win = new Window({ url: "http://localhost" });
133
+ windowInstance = win;
134
+ setGlobal("self", globalThis);
135
+ setGlobal("window", win);
136
+ setGlobal("document", win.document);
137
+ setGlobal("navigator", win.navigator);
138
+ setGlobal("HTMLCollection", win.HTMLCollection);
139
+ setGlobal("getComputedStyle", win.getComputedStyle.bind(win));
140
+ setGlobal("customElements", win.customElements);
141
+ setGlobal("HTMLElement", win.HTMLElement);
142
+ setGlobal("HTMLDivElement", win.HTMLDivElement);
143
+ setGlobal("HTMLCanvasElement", win.HTMLCanvasElement);
144
+ setGlobal("HTMLImageElement", win.HTMLImageElement);
145
+ setGlobal("Image", win.Image);
146
+ setGlobal("Event", win.Event);
147
+ setGlobal("MouseEvent", win.MouseEvent);
148
+ setGlobal("KeyboardEvent", win.KeyboardEvent);
149
+ setGlobal("PointerEvent", win.PointerEvent || win.MouseEvent);
150
+ setGlobal("TouchEvent", win.TouchEvent || class TouchEvent {
151
+ });
152
+ setGlobal("WheelEvent", win.WheelEvent || win.Event);
153
+ setGlobal("MutationObserver", win.MutationObserver);
154
+ setGlobal("ResizeObserver", class ResizeObserver {
155
+ observe() { }
156
+ disconnect() { }
157
+ unobserve() { }
158
+ });
159
+ setGlobal("requestAnimationFrame", (callback) => setTimeout(() => callback(Date.now()), 0));
160
+ setGlobal("cancelAnimationFrame", (id) => clearTimeout(id));
161
+ setGlobal("FileReader", NodeFileReader);
162
+ setGlobal("DOMParser", win.DOMParser);
163
+ setGlobal("XMLSerializer", win.XMLSerializer);
164
+ setGlobal("canvas", canvas);
165
+ setGlobal("devicePixelRatio", 1);
166
+ setGlobal("location", win.location);
167
+ setGlobal("innerWidth", 800);
168
+ setGlobal("innerHeight", 600);
169
+ setGlobal("addEventListener", () => { });
170
+ setGlobal("removeEventListener", () => { });
171
+ setGlobal("getSelection", () => ({
172
+ removeAllRanges: () => { },
173
+ addRange: () => { },
174
+ }));
175
+ shimInstalled = true;
176
+ }
177
+ export function disposeShims() {
178
+ if (windowInstance) {
179
+ windowInstance.close();
180
+ windowInstance = null;
181
+ }
182
+ shimInstalled = false;
183
+ }
184
+ export function isShimInstalled() {
185
+ return shimInstalled;
186
+ }
187
+ //# sourceMappingURL=shims.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shims.js","sourceRoot":"","sources":["../src/shims.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type * as SpreadJS from "@mescius/spread-sheets";
2
+ export type GCNamespace = typeof SpreadJS;
3
+ export type SpreadWorkbook = SpreadJS.Spread.Sheets.Workbook;
4
+ export type SpreadWorksheet = SpreadJS.Spread.Sheets.Worksheet;
5
+ export type SpreadStyle = SpreadJS.Spread.Sheets.Style;
6
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,OAAO,QAAQ,CAAC;AAC1C,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;AAC/D,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,19 @@
1
+ import type { GCNamespace, SpreadWorkbook, SpreadWorksheet } from "./types.js";
2
+ export declare function setGC(gc: GCNamespace | null): void;
3
+ export declare class Workbook {
4
+ readonly spread: SpreadWorkbook;
5
+ constructor(spread?: SpreadWorkbook);
6
+ batch<T>(fn: () => T): T;
7
+ batch<T>(fn: () => Promise<T>): Promise<T>;
8
+ getActiveSheet(): SpreadWorksheet;
9
+ getSheet(index: number): SpreadWorksheet;
10
+ getSheetCount(): number;
11
+ addSheet(name: string, index?: number): SpreadWorksheet;
12
+ save(filePath: string): Promise<void>;
13
+ saveToBuffer(): Promise<Buffer>;
14
+ toJSON(): object;
15
+ fromJSON(json: object): void;
16
+ static open(filePath: string): Promise<Workbook>;
17
+ static openFromBuffer(buffer: Buffer): Promise<Workbook>;
18
+ }
19
+ //# sourceMappingURL=workbook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workbook.d.ts","sourceRoot":"","sources":["../src/workbook.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8I/E,wBAAgB,KAAK,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,CAElD;AAED,qBAAa,QAAQ;IACnB,SAAgB,MAAM,EAAE,cAAc,CAAC;gBAE3B,MAAM,CAAC,EAAE,cAAc;IAKnC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC;IACxB,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAqB1C,cAAc,IAAI,eAAe;IAIjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe;IAIxC,aAAa,IAAI,MAAM;IAIvB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe;IAOjD,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW3C,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAK/B,MAAM,IAAI,MAAM;IAIhB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;WAIf,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;WAOzC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;CAK/D"}
@@ -0,0 +1,177 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { unzipSync, zipSync } from "fflate";
4
+ let gcRef = null;
5
+ function getGC() {
6
+ if (!gcRef) {
7
+ throw new Error("headless-spreadjs not initialized. Call init() first.");
8
+ }
9
+ return gcRef;
10
+ }
11
+ function stripEvalSheet(spread) {
12
+ for (let i = spread.getSheetCount() - 1; i >= 0; i--) {
13
+ if (spread.getSheet(i).name() === "Evaluation Version") {
14
+ spread.removeSheet(i);
15
+ }
16
+ }
17
+ }
18
+ function toArrayBuffer(buffer) {
19
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
20
+ }
21
+ function stripEvalSheetFromZip(buf) {
22
+ const zip = unzipSync(new Uint8Array(buf));
23
+ const wbXmlBytes = zip["xl/workbook.xml"];
24
+ if (!wbXmlBytes)
25
+ return buf;
26
+ const decoder = new TextDecoder();
27
+ const wbXml = decoder.decode(wbXmlBytes);
28
+ const sheetRe = /<sheet\s[^>]*name="Evaluation Version"[^>]*\/>/g;
29
+ const match = sheetRe.exec(wbXml);
30
+ if (!match)
31
+ return buf;
32
+ const ridMatch = /r:id="(rId\d+)"/.exec(match[0]);
33
+ if (!ridMatch)
34
+ return buf;
35
+ const rId = ridMatch[1];
36
+ const allSheets = [...wbXml.matchAll(/<sheet\s[^>]*\/>/g)];
37
+ const evalIndex = allSheets.findIndex((m) => m[0] === match[0]);
38
+ let newWbXml = wbXml.replace(match[0], "");
39
+ newWbXml = newWbXml.replace(/activeTab="(\d+)"/g, (_full, tabStr) => {
40
+ let tab = parseInt(tabStr, 10);
41
+ if (evalIndex >= 0 && tab >= evalIndex) {
42
+ tab = Math.max(0, tab - 1);
43
+ }
44
+ return `activeTab="${tab}"`;
45
+ });
46
+ const relsBytes = zip["xl/_rels/workbook.xml.rels"];
47
+ if (!relsBytes)
48
+ return buf;
49
+ const relsXml = decoder.decode(relsBytes);
50
+ const relRe = new RegExp(`<Relationship[^>]*Id="${rId}"[^>]*/>`, "g");
51
+ const relMatch = relRe.exec(relsXml);
52
+ let sheetPath = null;
53
+ if (relMatch) {
54
+ const targetMatch = /Target="([^"]+)"/.exec(relMatch[0]);
55
+ if (targetMatch) {
56
+ sheetPath = "xl/" + targetMatch[1];
57
+ }
58
+ }
59
+ const newRelsXml = relsXml.replace(relRe, "");
60
+ const ctBytes = zip["[Content_Types].xml"];
61
+ let newCtXml = null;
62
+ if (ctBytes && sheetPath) {
63
+ const ctXml = decoder.decode(ctBytes);
64
+ const partName = "/" + sheetPath;
65
+ const overrideRe = new RegExp(`<Override[^>]*PartName="${partName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"[^>]*/>`, "g");
66
+ newCtXml = ctXml.replace(overrideRe, "");
67
+ }
68
+ const encoder = new TextEncoder();
69
+ const newZip = {};
70
+ for (const [name, data] of Object.entries(zip)) {
71
+ if (sheetPath && name === sheetPath)
72
+ continue;
73
+ if (name === "xl/workbook.xml") {
74
+ newZip[name] = encoder.encode(newWbXml);
75
+ }
76
+ else if (name === "xl/_rels/workbook.xml.rels") {
77
+ newZip[name] = encoder.encode(newRelsXml);
78
+ }
79
+ else if (name === "[Content_Types].xml" && newCtXml) {
80
+ newZip[name] = encoder.encode(newCtXml);
81
+ }
82
+ else {
83
+ newZip[name] = data;
84
+ }
85
+ }
86
+ return Buffer.from(zipSync(newZip));
87
+ }
88
+ function saveAsBuffer(spread, gc) {
89
+ return new Promise((resolve, reject) => {
90
+ spread.save((blob) => {
91
+ blob
92
+ .arrayBuffer()
93
+ .then((bytes) => resolve(stripEvalSheetFromZip(Buffer.from(bytes))))
94
+ .catch(reject);
95
+ }, (err) => reject(err), { fileType: gc.Spread.Sheets.FileType.excel });
96
+ });
97
+ }
98
+ function importWorkbook(bytes, gc) {
99
+ return new Promise((resolve, reject) => {
100
+ const spread = new gc.Spread.Sheets.Workbook();
101
+ spread.import(bytes, () => {
102
+ stripEvalSheet(spread);
103
+ resolve(spread);
104
+ }, (err) => reject(err), { fileType: gc.Spread.Sheets.FileType.excel });
105
+ });
106
+ }
107
+ export function setGC(gc) {
108
+ gcRef = gc;
109
+ }
110
+ export class Workbook {
111
+ spread;
112
+ constructor(spread) {
113
+ const gc = getGC();
114
+ this.spread = spread ?? new gc.Spread.Sheets.Workbook();
115
+ }
116
+ batch(fn) {
117
+ this.spread.suspendCalcService(false);
118
+ try {
119
+ const result = fn();
120
+ if (result instanceof Promise) {
121
+ return result.finally(() => {
122
+ this.spread.resumeCalcService(true);
123
+ });
124
+ }
125
+ this.spread.resumeCalcService(true);
126
+ return result;
127
+ }
128
+ catch (error) {
129
+ this.spread.resumeCalcService(true);
130
+ throw error;
131
+ }
132
+ }
133
+ getActiveSheet() {
134
+ return this.spread.getActiveSheet();
135
+ }
136
+ getSheet(index) {
137
+ return this.spread.getSheet(index);
138
+ }
139
+ getSheetCount() {
140
+ return this.spread.getSheetCount();
141
+ }
142
+ addSheet(name, index) {
143
+ const gc = getGC();
144
+ const sheet = new gc.Spread.Sheets.Worksheet(name);
145
+ this.spread.addSheet(index ?? this.spread.getSheetCount(), sheet);
146
+ return sheet;
147
+ }
148
+ async save(filePath) {
149
+ const bytes = await this.saveToBuffer();
150
+ const dir = path.dirname(filePath);
151
+ if (dir && dir !== ".") {
152
+ await fs.promises.mkdir(dir, { recursive: true });
153
+ }
154
+ await fs.promises.writeFile(filePath, bytes);
155
+ }
156
+ saveToBuffer() {
157
+ return saveAsBuffer(this.spread, getGC());
158
+ }
159
+ toJSON() {
160
+ return this.spread.toJSON();
161
+ }
162
+ fromJSON(json) {
163
+ this.spread.fromJSON(json);
164
+ }
165
+ static async open(filePath) {
166
+ const gc = getGC();
167
+ const bytes = await fs.promises.readFile(filePath);
168
+ const spread = await importWorkbook(toArrayBuffer(bytes), gc);
169
+ return new Workbook(spread);
170
+ }
171
+ static async openFromBuffer(buffer) {
172
+ const gc = getGC();
173
+ const spread = await importWorkbook(toArrayBuffer(buffer), gc);
174
+ return new Workbook(spread);
175
+ }
176
+ }
177
+ //# sourceMappingURL=workbook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workbook.js","sourceRoot":"","sources":["../src/workbook.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@hewliyang/headless-spreadjs",
3
+ "version": "0.0.1",
4
+ "description": "Headless Excel workbook engine for Node.js — powered by SpreadJS with DOM shims. No browser, no Excel, any platform.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "keywords": [
18
+ "excel",
19
+ "xlsx",
20
+ "spreadsheet",
21
+ "headless",
22
+ "spreadjs",
23
+ "node",
24
+ "charts",
25
+ "pivot-tables",
26
+ "formulas",
27
+ "shapes",
28
+ "slicers"
29
+ ],
30
+ "author": "hewliyang",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "git+https://github.com/hewliyang/headless-spreadjs.git"
35
+ },
36
+ "homepage": "https://github.com/hewliyang/headless-spreadjs#readme",
37
+ "bugs": {
38
+ "url": "https://github.com/hewliyang/headless-spreadjs/issues"
39
+ },
40
+ "dependencies": {
41
+ "@mescius/spread-sheets": ">=18.0.0",
42
+ "@mescius/spread-sheets-charts": ">=18.0.0",
43
+ "@mescius/spread-sheets-io": ">=18.0.0",
44
+ "@mescius/spread-sheets-pivot-addon": ">=18.0.0",
45
+ "@mescius/spread-sheets-shapes": ">=18.0.0",
46
+ "@mescius/spread-sheets-slicers": ">=18.0.0",
47
+ "canvas": "^3.1.0",
48
+ "fflate": "^0.8.2",
49
+ "happy-dom": "^16.0.0"
50
+ },
51
+ "devDependencies": {
52
+ "@biomejs/biome": "^2.3.15",
53
+ "@types/node": "^22.0.0",
54
+ "tsx": "^4.0.0",
55
+ "typescript": "^5.0.0",
56
+ "vitest": "^4.0.18"
57
+ },
58
+ "engines": {
59
+ "node": ">=18"
60
+ },
61
+ "scripts": {
62
+ "build": "tsc",
63
+ "typecheck": "tsc --noEmit && tsc --project examples/tsconfig.json",
64
+ "dev": "tsc --watch",
65
+ "lint": "biome check",
66
+ "fmt": "biome check --write",
67
+ "test": "vitest run --maxWorkers=1",
68
+ "test:watch": "vitest --maxWorkers=1"
69
+ }
70
+ }