@ricsam/excel-to-formula-engine 0.0.0 → 0.1.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.
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Reads the OPC (zip) container of an .xlsx file and exposes its parts as
3
+ * parsed XML.
4
+ */
5
+ export type XmlNode = Record<string, unknown>;
6
+ export interface XlsxPackage {
7
+ /** Raw part bytes keyed by zip path, e.g. `"xl/worksheets/sheet1.xml"`. */
8
+ readonly files: Map<string, Uint8Array>;
9
+ /** Parse a part as XML, or undefined when the part is absent. */
10
+ xml(path: string): XmlNode | undefined;
11
+ text(path: string): string | undefined;
12
+ has(path: string): boolean;
13
+ /** Every part path beginning with the given prefix. */
14
+ list(prefix: string): string[];
15
+ }
16
+ export declare function readXlsxPackage(source: Blob | ArrayBuffer | Uint8Array): Promise<XlsxPackage>;
17
+ /**
18
+ * fast-xml-parser gives a single child as an object and repeated children as an
19
+ * array. Parts we do not force into arrays go through this.
20
+ */
21
+ export declare function asArray<T>(value: T | T[] | undefined): T[];
22
+ export declare function attr(node: unknown, name: string): string | undefined;
23
+ export declare function numAttr(node: unknown, name: string): number | undefined;
24
+ export declare function boolAttr(node: unknown, name: string, fallback?: boolean): boolean;
25
+ /** Text content of an element parsed by fast-xml-parser. */
26
+ export declare function textOf(node: unknown): string;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Parses xl/styles.xml into the subset of formatting the engine can express.
3
+ *
4
+ * Excel's style model is indirect: a cell carries an index into `cellXfs`, and
5
+ * each `xf` points at a font, fill, border and number format. This flattens
6
+ * that into one record per `xf`.
7
+ */
8
+ import type { CellStyle } from "@ricsam/formula-engine";
9
+ import { type XlsxPackage } from "./package";
10
+ export interface ExcelFormat {
11
+ style: CellStyle;
12
+ /** Number format code, e.g. `"0.00%"` or `"yyyy-mm-dd"`. */
13
+ numberFormat?: string;
14
+ /** True when the number format renders a date or a time. */
15
+ isDateFormat: boolean;
16
+ }
17
+ export interface StyleTable {
18
+ formats: ExcelFormat[];
19
+ /** Differential formats, referenced by conditional formatting rules. */
20
+ differentialFormats: CellStyle[];
21
+ }
22
+ export declare function parseStyles(pkg: XlsxPackage): StyleTable;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Parses the workbook-level parts: the sheet list, defined names, the shared
3
+ * string table, and table definitions.
4
+ */
5
+ import { type XlsxPackage } from "./package";
6
+ export interface SheetEntry {
7
+ name: string;
8
+ /** Zip path of the worksheet part. */
9
+ partPath: string;
10
+ /** `visible`, `hidden` or `veryHidden`. */
11
+ state: string;
12
+ }
13
+ export interface DefinedName {
14
+ name: string;
15
+ /** Formula text as stored, e.g. `"Sheet1!$A$1:$B$5"`. */
16
+ formula: string;
17
+ /**
18
+ * Index of the sheet this name is scoped to, or undefined for a
19
+ * workbook-scoped name.
20
+ */
21
+ localSheetId?: number;
22
+ hidden: boolean;
23
+ }
24
+ export interface RawTable {
25
+ name: string;
26
+ displayName: string;
27
+ /** Range in A1 notation, including the header and totals rows. */
28
+ ref: string;
29
+ headerRowCount: number;
30
+ totalsRowCount: number;
31
+ columnNames: string[];
32
+ }
33
+ /** Read the shared string table, flattening rich text to plain text. */
34
+ export declare function parseSharedStrings(pkg: XlsxPackage): string[];
35
+ export declare function parseWorkbook(pkg: XlsxPackage): {
36
+ sheets: SheetEntry[];
37
+ definedNames: DefinedName[];
38
+ /** True when the file uses the 1904 date system rather than 1900. */
39
+ date1904: boolean;
40
+ };
41
+ /** Table parts referenced by one worksheet. */
42
+ export declare function parseTables(pkg: XlsxPackage, worksheetPartPath: string): RawTable[];
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Parses one xl/worksheets/sheetN.xml part.
3
+ *
4
+ * Cell values in Excel are typed by the `t` attribute and stored in `<v>`, with
5
+ * formulas alongside in `<f>`. Shared formulas are stored once on the group's
6
+ * master cell and re-derived here for every other member.
7
+ */
8
+ import { type XlsxPackage } from "./package";
9
+ export type CellKind = "number" | "string" | "boolean" | "error" | "date" | "empty";
10
+ export interface RawCell {
11
+ reference: string;
12
+ colIndex: number;
13
+ rowIndex: number;
14
+ kind: CellKind;
15
+ /** Literal value, before date conversion. */
16
+ value: string | number | boolean | undefined;
17
+ /** Excel formula text without the leading `=`, when the cell has one. */
18
+ formula?: string;
19
+ /**
20
+ * How far this cell sits from the master cell of its shared-formula group.
21
+ * The formula's relative references are shifted by this much at translation
22
+ * time. Absent or zero for an ordinary formula.
23
+ */
24
+ formulaOffset?: {
25
+ cols: number;
26
+ rows: number;
27
+ };
28
+ /** Index into the style table's `formats`. */
29
+ styleIndex?: number;
30
+ }
31
+ export interface RawConditionalFormat {
32
+ /** Ranges the rule applies to, as written in the file (`"A1:B10 D1:D5"`). */
33
+ ranges: string[];
34
+ type: string;
35
+ operator?: string;
36
+ /** Rule formulas, in the order Excel stores them. */
37
+ formulas: string[];
38
+ text?: string;
39
+ /** Index into the style table's `differentialFormats`. */
40
+ dxfId?: number;
41
+ priority: number;
42
+ /** Colour-scale stops, for `colorScale` rules. */
43
+ colorScale?: {
44
+ cfvo: {
45
+ type: string;
46
+ val?: string;
47
+ }[];
48
+ colors: (string | undefined)[];
49
+ };
50
+ /** Present for `top10` rules. */
51
+ rank?: number;
52
+ bottom?: boolean;
53
+ percent?: boolean;
54
+ stopIfTrue?: boolean;
55
+ }
56
+ export interface RawWorksheet {
57
+ cells: RawCell[];
58
+ merges: string[];
59
+ columnWidths: Record<number, number>;
60
+ rowHeights: Record<number, number>;
61
+ frozen?: {
62
+ rows: number;
63
+ cols: number;
64
+ };
65
+ conditionalFormats: RawConditionalFormat[];
66
+ /** Hyperlink targets keyed by A1 reference. */
67
+ hyperlinks: Record<string, string>;
68
+ }
69
+ export declare function parseWorksheet(pkg: XlsxPackage, partPath: string, sharedStrings: string[]): RawWorksheet;
70
+ /** Flatten a rich-text run container into plain text. */
71
+ export declare function readRichText(node: unknown): string;
72
+ export declare function readRelationships(pkg: XlsxPackage, partPath: string): Map<string, string>;
package/package.json CHANGED
@@ -1,10 +1,62 @@
1
1
  {
2
2
  "name": "@ricsam/excel-to-formula-engine",
3
- "version": "0.0.0",
4
- "description": "OIDC trusted publishing setup package for @ricsam/excel-to-formula-engine",
3
+ "version": "0.1.1",
4
+ "description": "Convert an Excel .xlsx file into FormulaEngine WorkbookData, in the browser",
5
+ "type": "module",
6
+ "module": "./dist/index.mjs",
7
+ "main": "./dist/index.cjs",
8
+ "types": "./dist/types/index.d.ts",
9
+ "scripts": {
10
+ "test": "bun run fixtures && bun test",
11
+ "agent:test": "CLAUDECODE=1 bun run fixtures && CLAUDECODE=1 bun test",
12
+ "typecheck": "tsc --noEmit",
13
+ "fixtures": "bun tests/fixtures/build-fixtures.ts",
14
+ "demo": "bun build demo/demo.ts --target=browser --outfile=demo/demo.js",
15
+ "demo:serve": "bun run demo && bun demo/serve.ts",
16
+ "build": "bun build.ts"
17
+ },
5
18
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
19
+ "excel",
20
+ "xlsx",
21
+ "spreadsheet",
22
+ "formula-engine",
23
+ "browser"
24
+ ],
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/ricsam/excel-to-formula-engine.git"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/ricsam/excel-to-formula-engine/issues"
31
+ },
32
+ "homepage": "https://github.com/ricsam/excel-to-formula-engine#readme",
33
+ "author": "",
34
+ "license": "ISC",
35
+ "dependencies": {
36
+ "fast-xml-parser": "^5.11.1",
37
+ "fflate": "^0.8.3"
38
+ },
39
+ "devDependencies": {
40
+ "@changesets/cli": "^3.0.2",
41
+ "@types/bun": "^1.4.2",
42
+ "exceljs": "^4.4.0",
43
+ "typescript": "^5.9.2"
44
+ },
45
+ "peerDependencies": {
46
+ "@ricsam/formula-engine": "0.3.0"
47
+ },
48
+ "files": [
49
+ "dist"
50
+ ],
51
+ "exports": {
52
+ ".": {
53
+ "types": "./dist/types/index.d.ts",
54
+ "import": "./dist/index.mjs",
55
+ "require": "./dist/index.cjs"
56
+ }
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "sideEffects": false
10
62
  }