odf-kit 0.9.6 → 0.9.8

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +306 -272
  3. package/dist/index.d.ts +1 -1
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/ods/content.d.ts +0 -9
  6. package/dist/ods/content.d.ts.map +1 -1
  7. package/dist/ods/content.js +274 -97
  8. package/dist/ods/content.js.map +1 -1
  9. package/dist/ods/document.d.ts +2 -42
  10. package/dist/ods/document.d.ts.map +1 -1
  11. package/dist/ods/document.js +7 -42
  12. package/dist/ods/document.js.map +1 -1
  13. package/dist/ods/index.d.ts +1 -1
  14. package/dist/ods/index.d.ts.map +1 -1
  15. package/dist/ods/settings.d.ts +13 -0
  16. package/dist/ods/settings.d.ts.map +1 -0
  17. package/dist/ods/settings.js +67 -0
  18. package/dist/ods/settings.js.map +1 -0
  19. package/dist/ods/sheet-builder.d.ts +42 -28
  20. package/dist/ods/sheet-builder.d.ts.map +1 -1
  21. package/dist/ods/sheet-builder.js +57 -42
  22. package/dist/ods/sheet-builder.js.map +1 -1
  23. package/dist/ods/types.d.ts +68 -30
  24. package/dist/ods/types.d.ts.map +1 -1
  25. package/dist/ods-reader/html-renderer.d.ts +19 -0
  26. package/dist/ods-reader/html-renderer.d.ts.map +1 -0
  27. package/dist/ods-reader/html-renderer.js +123 -0
  28. package/dist/ods-reader/html-renderer.js.map +1 -0
  29. package/dist/ods-reader/index.d.ts +19 -0
  30. package/dist/ods-reader/index.d.ts.map +1 -0
  31. package/dist/ods-reader/index.js +22 -0
  32. package/dist/ods-reader/index.js.map +1 -0
  33. package/dist/ods-reader/parser.d.ts +24 -0
  34. package/dist/ods-reader/parser.d.ts.map +1 -0
  35. package/dist/ods-reader/parser.js +544 -0
  36. package/dist/ods-reader/parser.js.map +1 -0
  37. package/dist/ods-reader/types.d.ts +139 -0
  38. package/dist/ods-reader/types.d.ts.map +1 -0
  39. package/dist/ods-reader/types.js +7 -0
  40. package/dist/ods-reader/types.js.map +1 -0
  41. package/package.json +22 -5
@@ -12,7 +12,8 @@
12
12
  * .addRow(["February", 14200.00])
13
13
  * .addRow(["Total", { value: "=SUM(B2:B3)", type: "formula" }])
14
14
  * .setColumnWidth(0, "4cm")
15
- * .setColumnWidth(1, "5cm");
15
+ * .setColumnWidth(1, "5cm")
16
+ * .freezeRows(1);
16
17
  */
17
18
  export class OdsSheet {
18
19
  /** Internal sheet data — used by OdsDocument.save(). */
@@ -33,26 +34,20 @@ export class OdsSheet {
33
34
  * - `boolean` → boolean
34
35
  * - `string` → string (never auto-detected as formula)
35
36
  * - `null` / `undefined` → empty cell
36
- * - {@link OdsCellObject} → explicit type (required for formulas)
37
- *
38
- * Row options apply formatting defaults to every cell in the row.
39
- * Per-cell {@link OdsCellObject} options override row-level defaults.
37
+ * - {@link OdsCellObject} → explicit type (required for formulas, percentages, currencies)
40
38
  *
41
39
  * @param values - Array of cell values in column order.
42
40
  * @param options - Optional formatting defaults for all cells in this row.
43
41
  * @returns This sheet, for chaining.
44
42
  *
45
43
  * @example
46
- * // Simple auto-typed row
47
- * sheet.addRow([1.23, "Text", new Date("2026-01-15"), true]);
48
- *
49
- * @example
50
- * // Header row with formatting
51
44
  * sheet.addRow(["Month", "Revenue"], { bold: true, backgroundColor: "#DDDDDD" });
52
- *
53
- * @example
54
- * // Row with a formula cell
55
- * sheet.addRow(["Total", { value: "=SUM(B1:B10)", type: "formula" }]);
45
+ * sheet.addRow(["January", 12500.00]);
46
+ * sheet.addRow(["Total", { value: "=SUM(B2:B3)", type: "formula" }]);
47
+ * sheet.addRow([{ value: 0.1234, type: "percentage", numberFormat: "percentage:1" }]);
48
+ * sheet.addRow([{ value: 1234.56, type: "currency", numberFormat: "currency:EUR" }]);
49
+ * sheet.addRow([{ value: "Report", type: "string", colSpan: 3, bold: true }]);
50
+ * sheet.addRow([{ value: "odf-kit", type: "string", href: "https://github.com/GitHubNewbie0/odf-kit" }]);
56
51
  */
57
52
  addRow(values, options) {
58
53
  const cells = values.map((v) => toCellData(v));
@@ -62,16 +57,9 @@ export class OdsSheet {
62
57
  /**
63
58
  * Set the width of a column.
64
59
  *
65
- * May be called before or after adding rows. Uses zero-based column index.
66
- * Columns without an explicit width use the application's optimal width.
67
- *
68
60
  * @param colIndex - Zero-based column index.
69
61
  * @param width - Width with units (e.g. `"3cm"`, `"1.5in"`).
70
62
  * @returns This sheet, for chaining.
71
- *
72
- * @example
73
- * sheet.setColumnWidth(0, "4cm");
74
- * sheet.setColumnWidth(1, "8cm");
75
63
  */
76
64
  setColumnWidth(colIndex, width) {
77
65
  this.data.columns.set(colIndex, { width });
@@ -80,17 +68,9 @@ export class OdsSheet {
80
68
  /**
81
69
  * Set the height of a row.
82
70
  *
83
- * The row must already exist (added via {@link addRow}). Uses zero-based
84
- * row index. Silently ignored for out-of-range indices.
85
- * Rows without an explicit height use the application's optimal height.
86
- *
87
71
  * @param rowIndex - Zero-based row index.
88
72
  * @param height - Height with units (e.g. `"1cm"`, `"18pt"`).
89
73
  * @returns This sheet, for chaining.
90
- *
91
- * @example
92
- * sheet.addRow(["Header"]);
93
- * sheet.setRowHeight(0, "1cm");
94
74
  */
95
75
  setRowHeight(rowIndex, height) {
96
76
  const row = this.data.rows[rowIndex];
@@ -99,24 +79,65 @@ export class OdsSheet {
99
79
  }
100
80
  return this;
101
81
  }
82
+ /**
83
+ * Freeze the top N rows so they remain visible when scrolling down.
84
+ *
85
+ * Typically used to keep a header row visible. Call after adding rows.
86
+ *
87
+ * @param rows - Number of rows to freeze (default 1).
88
+ * @returns This sheet, for chaining.
89
+ *
90
+ * @example
91
+ * sheet.addRow(["Name", "Amount", "Date"], { bold: true });
92
+ * sheet.freezeRows(1);
93
+ */
94
+ freezeRows(rows = 1) {
95
+ this.data.freezeRows = rows;
96
+ return this;
97
+ }
98
+ /**
99
+ * Freeze the left N columns so they remain visible when scrolling right.
100
+ *
101
+ * @param cols - Number of columns to freeze (default 1).
102
+ * @returns This sheet, for chaining.
103
+ *
104
+ * @example
105
+ * sheet.freezeColumns(1); // freeze the first column
106
+ */
107
+ freezeColumns(cols = 1) {
108
+ this.data.freezeColumns = cols;
109
+ return this;
110
+ }
111
+ /**
112
+ * Set the sheet tab color.
113
+ *
114
+ * @param color - Hex color (`"#FF0000"`) or CSS named color (`"red"`).
115
+ * @returns This sheet, for chaining.
116
+ *
117
+ * @example
118
+ * doc.addSheet("Q1").setTabColor("#4CAF50");
119
+ * doc.addSheet("Q2").setTabColor("#2196F3");
120
+ */
121
+ setTabColor(color) {
122
+ this.data.tabColor = color;
123
+ return this;
124
+ }
102
125
  }
103
126
  // ─── Internal Helpers ─────────────────────────────────────────────────
104
- /**
105
- * Convert an OdsCellValue to internal OdsCellData with resolved type.
106
- */
107
127
  function toCellData(value) {
108
128
  if (value === null || value === undefined) {
109
129
  return { value: null, type: "empty" };
110
130
  }
111
- // OdsCellObject — has an explicit 'type' field alongside 'value'
112
131
  if (isOdsCellObject(value)) {
113
132
  return {
114
133
  value: value.value,
115
134
  type: value.type,
116
135
  options: extractCellOptions(value),
136
+ colSpan: value.colSpan,
137
+ rowSpan: value.rowSpan,
138
+ href: value.href,
117
139
  };
118
140
  }
119
- // Auto-typed primitives
120
141
  if (value instanceof Date) {
121
142
  return { value, type: "date" };
122
143
  }
@@ -126,19 +147,11 @@ function toCellData(value) {
126
147
  if (typeof value === "number") {
127
148
  return { value, type: "float" };
128
149
  }
129
- // string — never auto-detected as formula
130
150
  return { value: value, type: "string" };
131
151
  }
132
- /**
133
- * Type guard: returns true when value is an OdsCellObject.
134
- */
135
152
  function isOdsCellObject(value) {
136
153
  return typeof value === "object" && value !== null && !(value instanceof Date) && "type" in value;
137
154
  }
138
- /**
139
- * Extract OdsCellOptions fields from an OdsCellObject, excluding 'value' and 'type'.
140
- * Returns undefined when no formatting options are present.
141
- */
142
155
  function extractCellOptions(obj) {
143
156
  const opts = {};
144
157
  if (obj.bold !== undefined)
@@ -175,6 +188,8 @@ function extractCellOptions(obj) {
175
188
  opts.wrap = obj.wrap;
176
189
  if (obj.dateFormat !== undefined)
177
190
  opts.dateFormat = obj.dateFormat;
191
+ if (obj.numberFormat !== undefined)
192
+ opts.numberFormat = obj.numberFormat;
178
193
  return Object.keys(opts).length > 0 ? opts : undefined;
179
194
  }
180
195
  //# sourceMappingURL=sheet-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sheet-builder.js","sourceRoot":"","sources":["../../src/ods/sheet-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sheet-builder.js","sourceRoot":"","sources":["../../src/ods/sheet-builder.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /** Recognized cell types in ODS. */
2
- export type OdsCellType = "string" | "float" | "date" | "boolean" | "formula";
2
+ export type OdsCellType = "string" | "float" | "date" | "boolean" | "formula" | "percentage" | "currency";
3
3
  /** Built-in date display formats. */
4
4
  export type OdsDateFormat = "YYYY-MM-DD" | "DD/MM/YYYY" | "MM/DD/YYYY";
5
5
  /**
@@ -7,14 +7,6 @@ export type OdsDateFormat = "YYYY-MM-DD" | "DD/MM/YYYY" | "MM/DD/YYYY";
7
7
  *
8
8
  * Applied at the row level (as defaults for all cells) or at the cell level
9
9
  * (as overrides for a single cell via {@link OdsCellObject}).
10
- *
11
- * @example
12
- * // Row-level defaults
13
- * sheet.addRow(["Header", "Value"], { bold: true, backgroundColor: "#DDDDDD" });
14
- *
15
- * @example
16
- * // Cell-level overrides inside OdsCellObject
17
- * sheet.addRow([{ value: "Special", type: "string", color: "#FF0000" }]);
18
10
  */
19
11
  export interface OdsCellOptions {
20
12
  /** Bold text. */
@@ -28,19 +20,15 @@ export interface OdsCellOptions {
28
20
  fontSize?: number | string;
29
21
  /** Font family (e.g. `"Arial"`, `"Liberation Sans"`). */
30
22
  fontFamily?: string;
31
- /**
32
- * Text color. Accepts hex (`"#FF0000"`) or CSS named colors (`"red"`).
33
- */
23
+ /** Text color. Accepts hex (`"#FF0000"`) or CSS named colors (`"red"`). */
34
24
  color?: string;
35
25
  /** Underline the text. */
36
26
  underline?: boolean;
37
- /**
38
- * Cell background color. Accepts hex (`"#DDDDDD"`) or CSS named colors.
39
- */
27
+ /** Cell background color. Accepts hex (`"#DDDDDD"`) or CSS named colors. */
40
28
  backgroundColor?: string;
41
29
  /**
42
- * Border on all four sides. Uses CSS border shorthand:
43
- * `"<width> <style> <color>"` (e.g. `"0.5pt solid #000000"`).
30
+ * Border on all four sides. CSS shorthand: `"<width> <style> <color>"`
31
+ * (e.g. `"0.5pt solid #000000"`).
44
32
  */
45
33
  border?: string;
46
34
  /** Top border. Overrides `border` for the top side. */
@@ -64,6 +52,24 @@ export interface OdsCellOptions {
64
52
  * Overrides the document-level default set via `OdsDocument.setDateFormat()`.
65
53
  */
66
54
  dateFormat?: OdsDateFormat;
55
+ /**
56
+ * Number display format. Applies when the cell contains a numeric value.
57
+ *
58
+ * Predefined formats:
59
+ * - `"integer"` — 1,234 (no decimal places, thousands separator)
60
+ * - `"decimal:N"` — 1,234.56 (N decimal places, thousands separator)
61
+ * - `"percentage"` — 12.34% (raw value × 100, 2 decimal places)
62
+ * - `"percentage:N"` — 12.3% (N decimal places)
63
+ * - `"currency:CODE"` — €1,234.56 (ISO 4217 code, 2 decimal places)
64
+ * - `"currency:CODE:N"` — €1,234.6 (currency with N decimal places)
65
+ *
66
+ * @example
67
+ * { value: 1234567.89, type: "float", numberFormat: "decimal:2" }
68
+ * { value: 0.1234, type: "percentage", numberFormat: "percentage:1" }
69
+ * { value: 1234.56, type: "currency", numberFormat: "currency:EUR" }
70
+ * { value: 9999, type: "float", numberFormat: "integer" }
71
+ */
72
+ numberFormat?: string;
67
73
  }
68
74
  /**
69
75
  * Row-level formatting options. Applied to all cells in the row as defaults.
@@ -73,29 +79,53 @@ export type OdsRowOptions = OdsCellOptions;
73
79
  /**
74
80
  * Explicit typed cell — use when automatic type detection is insufficient.
75
81
  *
76
- * Required for formula cells. Also allows per-cell formatting that overrides
77
- * the row-level defaults set in `addRow()`.
78
- *
79
- * Extends {@link OdsCellOptions} so individual cell formatting can override
80
- * row-level defaults.
82
+ * Required for formula, percentage, and currency cells. Also allows per-cell
83
+ * formatting that overrides row-level defaults.
81
84
  *
82
85
  * @example
83
86
  * // Formula — explicit type required
84
87
  * { value: "=SUM(B1:B10)", type: "formula" }
85
88
  *
86
89
  * @example
87
- * // Date with per-cell format override
88
- * { value: new Date("2026-01-15"), type: "date", dateFormat: "DD/MM/YYYY" }
90
+ * // Percentage
91
+ * { value: 0.1234, type: "percentage", numberFormat: "percentage:1" }
89
92
  *
90
93
  * @example
91
- * // String with bold override inside a non-bold row
92
- * { value: "Total", type: "string", bold: true }
94
+ * // Currency
95
+ * { value: 1234.56, type: "currency", numberFormat: "currency:EUR" }
96
+ *
97
+ * @example
98
+ * // Merged cell spanning 3 columns
99
+ * { value: "Q1 Report", type: "string", colSpan: 3, bold: true }
100
+ *
101
+ * @example
102
+ * // Hyperlink
103
+ * { value: "odf-kit", type: "string", href: "https://github.com/GitHubNewbie0/odf-kit" }
93
104
  */
94
105
  export interface OdsCellObject extends OdsCellOptions {
95
106
  /** The cell value. */
96
107
  value: string | number | boolean | Date | null;
97
108
  /** The explicit cell type. */
98
109
  type: OdsCellType;
110
+ /**
111
+ * Span this cell across N columns (default 1).
112
+ * The spanned columns in the same row are automatically filled with
113
+ * covered cells.
114
+ */
115
+ colSpan?: number;
116
+ /**
117
+ * Span this cell across N rows (default 1).
118
+ * The spanned cells in subsequent rows at the same column position are
119
+ * automatically filled with covered cells.
120
+ */
121
+ rowSpan?: number;
122
+ /**
123
+ * Hyperlink URL. When set, the cell text becomes a clickable link.
124
+ *
125
+ * @example
126
+ * { value: "odf-kit", type: "string", href: "https://github.com/GitHubNewbie0/odf-kit" }
127
+ */
128
+ href?: string;
99
129
  }
100
130
  /**
101
131
  * A cell value — either a primitive (auto-typed) or an explicit {@link OdsCellObject}.
@@ -108,11 +138,7 @@ export interface OdsCellObject extends OdsCellOptions {
108
138
  * - `null` / `undefined` → empty cell
109
139
  *
110
140
  * @example
111
- * // Primitives — auto-typed
112
141
  * sheet.addRow(["Hello", 42, new Date("2026-01-15"), true]);
113
- *
114
- * @example
115
- * // Mix of primitives and explicit objects
116
142
  * sheet.addRow(["Total", { value: "=SUM(B1:B10)", type: "formula" }]);
117
143
  */
118
144
  export type OdsCellValue = string | number | boolean | Date | null | undefined | OdsCellObject;
@@ -124,6 +150,12 @@ export interface OdsCellData {
124
150
  type: OdsCellType | "empty";
125
151
  /** Cell-level formatting options — merged with row options at render time. */
126
152
  options?: OdsCellOptions;
153
+ /** Column span — number of columns this cell covers (default 1). */
154
+ colSpan?: number;
155
+ /** Row span — number of rows this cell covers (default 1). */
156
+ rowSpan?: number;
157
+ /** Hyperlink URL — when set, cell text is rendered as a link. */
158
+ href?: string;
127
159
  }
128
160
  /** Internal representation of a row. */
129
161
  export interface OdsRowData {
@@ -147,5 +179,11 @@ export interface OdsSheetData {
147
179
  rows: OdsRowData[];
148
180
  /** Sparse column definitions keyed by zero-based column index. */
149
181
  columns: Map<number, OdsColumnData>;
182
+ /** Number of rows to freeze at the top (0 = no freeze). */
183
+ freezeRows?: number;
184
+ /** Number of columns to freeze at the left (0 = no freeze). */
185
+ freezeColumns?: number;
186
+ /** Sheet tab color (hex e.g. `"#FF0000"` or CSS named color). */
187
+ tabColor?: string;
150
188
  }
151
189
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ods/types.ts"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9E,qCAAqC;AACrC,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAEvE;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC7B,iBAAiB;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,mBAAmB;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3B,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC,qDAAqD;IACrD,aAAa,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAE5C,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,sBAAsB;IACtB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IAE/C,8BAA8B;IAC9B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,CAAC;AAI/F,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IAE/C,8BAA8B;IAC9B,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;IAE5B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,KAAK,EAAE,WAAW,EAAE,CAAC;IAErB,uEAAuE;IACvE,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IAEb,+BAA+B;IAC/B,IAAI,EAAE,UAAU,EAAE,CAAC;IAEnB,kEAAkE;IAClE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/ods/types.ts"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,OAAO,GACP,MAAM,GACN,SAAS,GACT,SAAS,GACT,YAAY,GACZ,UAAU,CAAC;AAEf,qCAAqC;AACrC,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,iBAAiB;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf,mBAAmB;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE3B,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IAEpC,qDAAqD;IACrD,aAAa,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAE5C,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,4CAA4C;IAC5C,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,WAAW,aAAc,SAAQ,cAAc;IACnD,sBAAsB;IACtB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IAE/C,8BAA8B;IAC9B,IAAI,EAAE,WAAW,CAAC;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,aAAa,CAAC;AAI/F,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IAE/C,8BAA8B;IAC9B,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC;IAE5B,8EAA8E;IAC9E,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB,oEAAoE;IACpE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,iEAAiE;IACjE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,yCAAyC;IACzC,KAAK,EAAE,WAAW,EAAE,CAAC;IAErB,uEAAuE;IACvE,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,qDAAqD;IACrD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,sDAAsD;AACtD,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mDAAmD;AACnD,MAAM,WAAW,YAAY;IAC3B,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAC;IAEb,+BAA+B;IAC/B,IAAI,EAAE,UAAU,EAAE,CAAC;IAEnB,kEAAkE;IAClE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAEpC,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * ODS HTML renderer — converts an OdsDocumentModel to an HTML string.
3
+ *
4
+ * Each sheet is rendered as an HTML <table>. Merged cells use colspan/rowspan.
5
+ * Covered cells are omitted. Cell formatting is applied as inline styles.
6
+ */
7
+ import type { OdsDocumentModel, OdsHtmlOptions } from "./types.js";
8
+ /**
9
+ * Render an OdsDocumentModel as an HTML string.
10
+ *
11
+ * Each sheet is rendered as a `<table>`. Merged cells use `colspan`/`rowspan`.
12
+ * Covered cells are omitted. Cell formatting applied as inline styles.
13
+ *
14
+ * @param model - Parsed document model from readOds().
15
+ * @param options - Optional rendering options.
16
+ * @returns HTML string.
17
+ */
18
+ export declare function renderOdsHtml(model: OdsDocumentModel, options?: OdsHtmlOptions): string;
19
+ //# sourceMappingURL=html-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-renderer.d.ts","sourceRoot":"","sources":["../../src/ods-reader/html-renderer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAKhB,cAAc,EACf,MAAM,YAAY,CAAC;AA2GpB;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CASvF"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * ODS HTML renderer — converts an OdsDocumentModel to an HTML string.
3
+ *
4
+ * Each sheet is rendered as an HTML <table>. Merged cells use colspan/rowspan.
5
+ * Covered cells are omitted. Cell formatting is applied as inline styles.
6
+ */
7
+ // ─── Style Building ───────────────────────────────────────────────────
8
+ function buildInlineStyle(fmt) {
9
+ const parts = [];
10
+ if (fmt.bold)
11
+ parts.push("font-weight:bold");
12
+ if (fmt.italic)
13
+ parts.push("font-style:italic");
14
+ if (fmt.underline)
15
+ parts.push("text-decoration:underline");
16
+ if (fmt.fontSize)
17
+ parts.push(`font-size:${fmt.fontSize}`);
18
+ if (fmt.fontFamily)
19
+ parts.push(`font-family:${fmt.fontFamily}`);
20
+ if (fmt.color)
21
+ parts.push(`color:${fmt.color}`);
22
+ if (fmt.backgroundColor)
23
+ parts.push(`background-color:${fmt.backgroundColor}`);
24
+ if (fmt.textAlign)
25
+ parts.push(`text-align:${fmt.textAlign}`);
26
+ if (fmt.verticalAlign)
27
+ parts.push(`vertical-align:${fmt.verticalAlign}`);
28
+ return parts.join(";");
29
+ }
30
+ // ─── HTML Escaping ────────────────────────────────────────────────────
31
+ function escapeHtml(text) {
32
+ return text
33
+ .replace(/&/g, "&amp;")
34
+ .replace(/</g, "&lt;")
35
+ .replace(/>/g, "&gt;")
36
+ .replace(/"/g, "&quot;");
37
+ }
38
+ // ─── Cell Rendering ───────────────────────────────────────────────────
39
+ function renderCellValue(cell) {
40
+ // Prefer display text when available
41
+ if (cell.displayText !== undefined && cell.displayText !== "") {
42
+ return escapeHtml(cell.displayText);
43
+ }
44
+ if (cell.value === null || cell.value === undefined)
45
+ return "";
46
+ if (cell.value instanceof Date) {
47
+ return escapeHtml(cell.value.toISOString().slice(0, 10));
48
+ }
49
+ return escapeHtml(String(cell.value));
50
+ }
51
+ function renderCell(cell, includeStyles, prefix) {
52
+ const attrs = [`class="${prefix}-cell"`];
53
+ if (cell.colSpan && cell.colSpan > 1)
54
+ attrs.push(`colspan="${cell.colSpan}"`);
55
+ if (cell.rowSpan && cell.rowSpan > 1)
56
+ attrs.push(`rowspan="${cell.rowSpan}"`);
57
+ if (includeStyles && cell.formatting) {
58
+ const style = buildInlineStyle(cell.formatting);
59
+ if (style)
60
+ attrs.push(`style="${style}"`);
61
+ }
62
+ // Right-align numbers by default if no explicit alignment
63
+ if (includeStyles &&
64
+ !cell.formatting?.textAlign &&
65
+ (cell.type === "float" || cell.type === "formula")) {
66
+ const existingStyle = attrs.find((a) => a.startsWith("style="));
67
+ if (existingStyle) {
68
+ const idx = attrs.indexOf(existingStyle);
69
+ attrs[idx] = existingStyle.replace('"', '"text-align:right;');
70
+ }
71
+ else {
72
+ attrs.push(`style="text-align:right"`);
73
+ }
74
+ }
75
+ const content = renderCellValue(cell);
76
+ return `<td ${attrs.join(" ")}>${content}</td>`;
77
+ }
78
+ // ─── Row Rendering ────────────────────────────────────────────────────
79
+ function renderRow(row, includeStyles, prefix) {
80
+ const cells = row.cells
81
+ .filter((c) => c.type !== "covered")
82
+ .map((c) => renderCell(c, includeStyles, prefix))
83
+ .join("");
84
+ const style = includeStyles && row.height ? ` style="height:${row.height}"` : "";
85
+ return `<tr class="${prefix}-row"${style}>${cells}</tr>`;
86
+ }
87
+ // ─── Sheet Rendering ──────────────────────────────────────────────────
88
+ function renderSheet(sheet, includeStyles, prefix) {
89
+ if (sheet.rows.length === 0) {
90
+ return `<h2 class="${prefix}-sheet-name">${escapeHtml(sheet.name)}</h2>\n<table class="${prefix}-sheet"></table>`;
91
+ }
92
+ const rows = sheet.rows
93
+ .map((r) => renderRow(r, includeStyles, prefix))
94
+ .join("\n ");
95
+ return [
96
+ `<h2 class="${prefix}-sheet-name">${escapeHtml(sheet.name)}</h2>`,
97
+ `<table class="${prefix}-sheet">`,
98
+ ` <tbody>`,
99
+ ` ${rows}`,
100
+ ` </tbody>`,
101
+ `</table>`,
102
+ ].join("\n");
103
+ }
104
+ // ─── Public API ───────────────────────────────────────────────────────
105
+ /**
106
+ * Render an OdsDocumentModel as an HTML string.
107
+ *
108
+ * Each sheet is rendered as a `<table>`. Merged cells use `colspan`/`rowspan`.
109
+ * Covered cells are omitted. Cell formatting applied as inline styles.
110
+ *
111
+ * @param model - Parsed document model from readOds().
112
+ * @param options - Optional rendering options.
113
+ * @returns HTML string.
114
+ */
115
+ export function renderOdsHtml(model, options) {
116
+ const includeStyles = options?.includeStyles ?? true;
117
+ const prefix = options?.classPrefix ?? "ods";
118
+ const sheets = model.sheets
119
+ .map((s) => renderSheet(s, includeStyles, prefix))
120
+ .join("\n\n");
121
+ return `<div class="${prefix}-document">\n${sheets}\n</div>`;
122
+ }
123
+ //# sourceMappingURL=html-renderer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-renderer.js","sourceRoot":"","sources":["../../src/ods-reader/html-renderer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { ReadOdsOptions, OdsHtmlOptions } from "./types.js";
2
+ export { readOds } from "./parser.js";
3
+ export type { OdsDocumentModel, OdsMetadata, OdsSheetModel, OdsRowModel, OdsCellModel, OdsCellFormatting, ReadOdsOptions, OdsHtmlOptions, } from "./types.js";
4
+ /**
5
+ * Convert an ODS file directly to an HTML string.
6
+ *
7
+ * Convenience wrapper around readOds() + renderOdsHtml().
8
+ *
9
+ * @param bytes - Raw .ods file bytes.
10
+ * @param htmlOptions - Optional HTML rendering options.
11
+ * @param readOptions - Optional parsing options.
12
+ * @returns HTML string with one <table> per sheet.
13
+ *
14
+ * @example
15
+ * import { odsToHtml } from "odf-kit/ods-reader"
16
+ * const html = odsToHtml(readFileSync("data.ods"))
17
+ */
18
+ export declare function odsToHtml(bytes: Uint8Array, htmlOptions?: OdsHtmlOptions, readOptions?: ReadOdsOptions): string;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ods-reader/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CACvB,KAAK,EAAE,UAAU,EACjB,WAAW,CAAC,EAAE,cAAc,EAC5B,WAAW,CAAC,EAAE,cAAc,GAC3B,MAAM,CAGR"}
@@ -0,0 +1,22 @@
1
+ import { readOds } from "./parser.js";
2
+ import { renderOdsHtml } from "./html-renderer.js";
3
+ export { readOds } from "./parser.js";
4
+ /**
5
+ * Convert an ODS file directly to an HTML string.
6
+ *
7
+ * Convenience wrapper around readOds() + renderOdsHtml().
8
+ *
9
+ * @param bytes - Raw .ods file bytes.
10
+ * @param htmlOptions - Optional HTML rendering options.
11
+ * @param readOptions - Optional parsing options.
12
+ * @returns HTML string with one <table> per sheet.
13
+ *
14
+ * @example
15
+ * import { odsToHtml } from "odf-kit/ods-reader"
16
+ * const html = odsToHtml(readFileSync("data.ods"))
17
+ */
18
+ export function odsToHtml(bytes, htmlOptions, readOptions) {
19
+ const model = readOds(bytes, readOptions);
20
+ return renderOdsHtml(model, htmlOptions);
21
+ }
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ods-reader/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAYtC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CACvB,KAAiB,EACjB,WAA4B,EAC5B,WAA4B;IAE5B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC1C,OAAO,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * ODS parser — reads an .ods file and builds an OdsDocumentModel.
3
+ *
4
+ * Pipeline:
5
+ * 1. Unzip the .ods bytes with fflate
6
+ * 2. Parse content.xml — walk office:spreadsheet → table:table → table:table-row → table:table-cell
7
+ * 3. Resolve cell types and values from office:value-type attributes
8
+ * 4. Handle table:number-columns-repeated / table:number-rows-repeated (LibreOffice compression)
9
+ * 5. Handle merged cells — colSpan/rowSpan on primary, covered cells at correct indices
10
+ * 6. Resolve cell styles from automatic-styles → OdsCellFormatting
11
+ * 7. Parse settings.xml for freeze row/column configuration
12
+ * 8. Parse meta.xml for document metadata
13
+ * 9. Return OdsDocumentModel
14
+ */
15
+ import type { OdsDocumentModel, ReadOdsOptions } from "./types.js";
16
+ /**
17
+ * Parse an ODS file into a structured document model.
18
+ *
19
+ * @param bytes - Raw .ods file bytes (Uint8Array).
20
+ * @param options - Optional parsing options.
21
+ * @returns Structured OdsDocumentModel.
22
+ */
23
+ export declare function readOds(bytes: Uint8Array, options?: ReadOdsOptions): OdsDocumentModel;
24
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/ods-reader/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EACV,gBAAgB,EAMhB,cAAc,EACf,MAAM,YAAY,CAAC;AAsfpB;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,gBAAgB,CAwErF"}