ooxml.js 2.6.19 → 2.8.0

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.
@@ -1,6 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_typed_util = require("../util.cjs");
3
3
  const require_typed_xlsx_number_format = require("./number-format.cjs");
4
+ let document_schema_js = require("document-schema.js");
4
5
  //#region src/typed/xlsx/styles.ts
5
6
  const STYLES_PATH = "xl/styles.xml";
6
7
  const GENERAL_NUM_FMT_ID = 0;
@@ -17,37 +18,249 @@ function readNumberFormatCodesById(styleSheet) {
17
18
  }
18
19
  return codes;
19
20
  }
20
- function readCellFormatCodes(pkg) {
21
+ const BORDER_WIDTH_PT = {
22
+ hair: .5,
23
+ thin: .75,
24
+ medium: 1.5,
25
+ thick: 2.25
26
+ };
27
+ const XLSX_BORDER_STYLE = {
28
+ thin: {
29
+ weight: "thin",
30
+ pattern: "solid"
31
+ },
32
+ medium: {
33
+ weight: "medium",
34
+ pattern: "solid"
35
+ },
36
+ thick: {
37
+ weight: "thick",
38
+ pattern: "solid"
39
+ },
40
+ hair: {
41
+ weight: "hair",
42
+ pattern: "solid"
43
+ },
44
+ dashed: {
45
+ weight: "thin",
46
+ pattern: "dashed"
47
+ },
48
+ dotted: {
49
+ weight: "thin",
50
+ pattern: "dotted"
51
+ },
52
+ double: {
53
+ weight: "thin",
54
+ pattern: "double"
55
+ },
56
+ mediumDashed: {
57
+ weight: "medium",
58
+ pattern: "dashed"
59
+ },
60
+ dashDot: {
61
+ weight: "thin",
62
+ pattern: "dashed"
63
+ },
64
+ mediumDashDot: {
65
+ weight: "medium",
66
+ pattern: "dashed"
67
+ },
68
+ dashDotDot: {
69
+ weight: "thin",
70
+ pattern: "dashed"
71
+ },
72
+ mediumDashDotDot: {
73
+ weight: "medium",
74
+ pattern: "dashed"
75
+ },
76
+ slantDashDot: {
77
+ weight: "medium",
78
+ pattern: "dashed"
79
+ }
80
+ };
81
+ const BORDER_WEIGHT_UPPER_PT = {
82
+ hair: .625,
83
+ thin: 1.125,
84
+ medium: 1.875
85
+ };
86
+ function readColorRgb(container, colorTag) {
87
+ const colorEl = require_typed_util.childrenWithTag(container, colorTag)[0];
88
+ if (colorEl === void 0) return;
89
+ const raw = require_typed_util.attr(colorEl, "rgb");
90
+ if (raw === void 0) return;
91
+ const hex = raw.length >= 6 ? raw.slice(-6) : raw;
92
+ if (!/^[0-9a-fA-F]{6}$/.test(hex)) return;
93
+ try {
94
+ return (0, document_schema_js.rgbHexToColor)(hex);
95
+ } catch {
96
+ return;
97
+ }
98
+ }
99
+ function readFillBackground(fill) {
100
+ const patternFill = require_typed_util.childrenWithTag(fill, "patternFill")[0];
101
+ if (patternFill === void 0 || require_typed_util.attr(patternFill, "patternType") !== "solid") return;
102
+ return readColorRgb(patternFill, "fgColor") ?? readColorRgb(patternFill, "bgColor");
103
+ }
104
+ function readFills(styleSheet) {
105
+ const fillsEl = require_typed_util.childrenWithTag(styleSheet, "fills")[0];
106
+ if (fillsEl === void 0) return [];
107
+ return require_typed_util.childrenWithTag(fillsEl, "fill").map(readFillBackground);
108
+ }
109
+ function readBorderEdge(border, edge) {
110
+ const edgeEl = require_typed_util.childrenWithTag(border, edge)[0];
111
+ if (edgeEl === void 0) return;
112
+ const styleToken = require_typed_util.attr(edgeEl, "style");
113
+ if (styleToken === void 0 || styleToken === "none") return;
114
+ const resolved = XLSX_BORDER_STYLE[styleToken];
115
+ if (resolved === void 0) return;
116
+ const color = readColorRgb(edgeEl, "color");
117
+ if (color === void 0) return;
118
+ const result = {
119
+ color,
120
+ widthPt: BORDER_WIDTH_PT[resolved.weight]
121
+ };
122
+ if (resolved.pattern !== "solid") result.style = resolved.pattern;
123
+ return result;
124
+ }
125
+ function readBorders(styleSheet) {
126
+ const bordersEl = require_typed_util.childrenWithTag(styleSheet, "borders")[0];
127
+ if (bordersEl === void 0) return [];
128
+ return require_typed_util.childrenWithTag(bordersEl, "border").map((border) => {
129
+ const left = readBorderEdge(border, "left");
130
+ const right = readBorderEdge(border, "right");
131
+ const top = readBorderEdge(border, "top");
132
+ const bottom = readBorderEdge(border, "bottom");
133
+ if (left === void 0 && right === void 0 && top === void 0 && bottom === void 0) return;
134
+ const result = {};
135
+ if (left !== void 0) result.left = left;
136
+ if (right !== void 0) result.right = right;
137
+ if (top !== void 0) result.top = top;
138
+ if (bottom !== void 0) result.bottom = bottom;
139
+ return result;
140
+ });
141
+ }
142
+ function readHorizontalAlignment(alignment) {
143
+ const value = require_typed_util.attr(alignment, "horizontal");
144
+ if (value === "left" || value === "center" || value === "right" || value === "justify") return value;
145
+ }
146
+ function readVerticalAlignment(alignment) {
147
+ const value = require_typed_util.attr(alignment, "vertical");
148
+ if (value === "top") return "top";
149
+ if (value === "center") return "middle";
150
+ }
151
+ function readAlignment(xf) {
152
+ const alignment = require_typed_util.childrenWithTag(xf, "alignment")[0];
153
+ if (alignment === void 0) return {};
154
+ return {
155
+ alignment: readHorizontalAlignment(alignment),
156
+ verticalAlignment: readVerticalAlignment(alignment)
157
+ };
158
+ }
159
+ function readCellStyles(pkg) {
21
160
  const styleSheet = require_typed_util.rootElement(pkg.parts[STYLES_PATH]);
22
161
  if (styleSheet === void 0) return [];
23
162
  const cellXfsEl = require_typed_util.childrenWithTag(styleSheet, "cellXfs")[0];
24
163
  if (cellXfsEl === void 0) return [];
25
164
  const codes = readNumberFormatCodesById(styleSheet);
165
+ const fills = readFills(styleSheet);
166
+ const borders = readBorders(styleSheet);
26
167
  return require_typed_util.childrenWithTag(cellXfsEl, "xf").map((xf) => {
27
- const raw = require_typed_util.attr(xf, "numFmtId");
28
- const id = raw === void 0 ? 0 : Number.parseInt(raw, 10);
29
- return Number.isInteger(id) ? codes.get(id) : void 0;
168
+ const numFmtRaw = require_typed_util.attr(xf, "numFmtId");
169
+ const numFmtId = numFmtRaw === void 0 ? 0 : Number.parseInt(numFmtRaw, 10);
170
+ const entry = {};
171
+ if (Number.isInteger(numFmtId)) {
172
+ const code = codes.get(numFmtId);
173
+ if (code !== void 0) entry.numberFormatCode = code;
174
+ }
175
+ const fillId = parseChildIndex(require_typed_util.attr(xf, "fillId"));
176
+ if (fillId !== void 0) entry.background = fills[fillId];
177
+ const borderId = parseChildIndex(require_typed_util.attr(xf, "borderId"));
178
+ if (borderId !== void 0) entry.borders = borders[borderId];
179
+ const { alignment, verticalAlignment } = readAlignment(xf);
180
+ if (alignment !== void 0) entry.alignment = alignment;
181
+ if (verticalAlignment !== void 0) entry.verticalAlignment = verticalAlignment;
182
+ return entry;
30
183
  });
31
184
  }
185
+ function parseChildIndex(value) {
186
+ if (value === void 0) return;
187
+ const n = Number.parseInt(value, 10);
188
+ return Number.isInteger(n) ? n : void 0;
189
+ }
190
+ function readCellFormatCodes(pkg) {
191
+ return readCellStyles(pkg).map((entry) => entry.numberFormatCode);
192
+ }
32
193
  const FIRST_CUSTOM_NUM_FMT_ID = 164;
33
194
  const DEFAULT_CELL_FORMAT_INDEX = 0;
34
- function signatureOf(format) {
195
+ const NONE_FILL_INDEX = 0;
196
+ const GRAY125_FILL_INDEX = 1;
197
+ const FIRST_REAL_FILL_INDEX = 2;
198
+ const EMPTY_BORDER_INDEX = 0;
199
+ const FIRST_REAL_BORDER_INDEX = 1;
200
+ function signatureOfNumberFormat(format) {
35
201
  return format.kind === "builtin" ? `builtin:${format.id}` : `custom:${format.code}`;
36
202
  }
203
+ const EMPTY_DECORATION = {};
204
+ function signatureOfDecoration(decoration) {
205
+ let sig = "";
206
+ if (decoration.background !== void 0) sig += `|bg:${(0, document_schema_js.colorToRgbHex)(decoration.background)}`;
207
+ const borders = decoration.borders;
208
+ if (borders !== void 0) for (const edge of [
209
+ "left",
210
+ "right",
211
+ "top",
212
+ "bottom"
213
+ ]) {
214
+ const border = borders[edge];
215
+ if (border !== void 0) sig += `|${edge}:${border.style ?? "solid"}:${(0, document_schema_js.colorToRgbHex)(border.color)}:${border.widthPt.toFixed(4)}`;
216
+ }
217
+ if (decoration.alignment !== void 0) sig += `|h:${decoration.alignment}`;
218
+ if (decoration.verticalAlignment !== void 0) sig += `|v:${decoration.verticalAlignment}`;
219
+ return sig;
220
+ }
221
+ function borderToXlsxStyle(border) {
222
+ switch (border.style) {
223
+ case "double": return "double";
224
+ case "dotted": return "dotted";
225
+ case "dashed": return border.widthPt >= BORDER_WEIGHT_UPPER_PT.thin ? "mediumDashed" : "dashed";
226
+ case "solid":
227
+ case void 0:
228
+ if (border.widthPt < BORDER_WEIGHT_UPPER_PT.hair) return "hair";
229
+ if (border.widthPt < BORDER_WEIGHT_UPPER_PT.thin) return "thin";
230
+ if (border.widthPt < BORDER_WEIGHT_UPPER_PT.medium) return "medium";
231
+ return "thick";
232
+ }
233
+ }
37
234
  var CellFormatTable = class {
38
- indexBySignature = /* @__PURE__ */ new Map([[signatureOf({
235
+ indexBySignature = /* @__PURE__ */ new Map([[signatureOfNumberFormat({
39
236
  kind: "builtin",
40
237
  id: 0
41
- }), 0]]);
42
- numFmtIdByIndex = [0];
238
+ }) + signatureOfDecoration(EMPTY_DECORATION), 0]]);
239
+ records = [{
240
+ numFmtId: 0,
241
+ fillId: NONE_FILL_INDEX,
242
+ borderId: EMPTY_BORDER_INDEX
243
+ }];
43
244
  declared = [];
44
- intern(format) {
45
- const signature = signatureOf(format);
245
+ fillIndexByRgb = /* @__PURE__ */ new Map();
246
+ fills = [{ patternType: "none" }, { patternType: "gray125" }];
247
+ borderIndexBySignature = /* @__PURE__ */ new Map();
248
+ borders = [{ edges: {} }];
249
+ intern(format, decoration = EMPTY_DECORATION) {
250
+ const signature = signatureOfNumberFormat(format) + signatureOfDecoration(decoration);
46
251
  const existing = this.indexBySignature.get(signature);
47
252
  if (existing !== void 0) return existing;
48
- const numFmtId = format.kind === "builtin" ? format.id : this.declare(format.code);
49
- const index = this.numFmtIdByIndex.length;
50
- this.numFmtIdByIndex.push(numFmtId);
253
+ const record = {
254
+ numFmtId: format.kind === "builtin" ? format.id : this.declareNumberFormat(format.code),
255
+ fillId: decoration.background === void 0 ? NONE_FILL_INDEX : this.internFill(decoration.background),
256
+ borderId: decoration.borders === void 0 ? EMPTY_BORDER_INDEX : this.internBorder(decoration.borders)
257
+ };
258
+ if (decoration.alignment !== void 0 || decoration.verticalAlignment !== void 0) record.alignment = {
259
+ horizontal: decoration.alignment,
260
+ vertical: decoration.verticalAlignment
261
+ };
262
+ const index = this.records.length;
263
+ this.records.push(record);
51
264
  this.indexBySignature.set(signature, index);
52
265
  return index;
53
266
  }
@@ -55,9 +268,18 @@ var CellFormatTable = class {
55
268
  return this.declared;
56
269
  }
57
270
  cellFormats() {
58
- return this.numFmtIdByIndex;
271
+ return this.records.map((record) => record.numFmtId);
59
272
  }
60
- declare(code) {
273
+ cellFormatRecords() {
274
+ return this.records;
275
+ }
276
+ fillDeclarations() {
277
+ return this.fills;
278
+ }
279
+ borderDeclarations() {
280
+ return this.borders;
281
+ }
282
+ declareNumberFormat(code) {
61
283
  const id = FIRST_CUSTOM_NUM_FMT_ID + this.declared.length;
62
284
  this.declared.push({
63
285
  id,
@@ -65,9 +287,60 @@ var CellFormatTable = class {
65
287
  });
66
288
  return id;
67
289
  }
290
+ internFill(background) {
291
+ const rgb = (0, document_schema_js.colorToRgbHex)(background);
292
+ const existing = this.fillIndexByRgb.get(rgb);
293
+ if (existing !== void 0) return existing;
294
+ const index = this.fills.length;
295
+ this.fills.push({
296
+ patternType: "solid",
297
+ rgb
298
+ });
299
+ this.fillIndexByRgb.set(rgb, index);
300
+ return index;
301
+ }
302
+ internBorder(borders) {
303
+ const edges = {};
304
+ let signature = "";
305
+ for (const edge of [
306
+ "left",
307
+ "right",
308
+ "top",
309
+ "bottom"
310
+ ]) {
311
+ const border = borders[edge];
312
+ if (border !== void 0) {
313
+ const style = borderToXlsxStyle(border);
314
+ const rgb = (0, document_schema_js.colorToRgbHex)(border.color);
315
+ edges[edge] = {
316
+ style,
317
+ rgb
318
+ };
319
+ signature += `|${edge}:${style}:${rgb}`;
320
+ }
321
+ }
322
+ const existing = this.borderIndexBySignature.get(signature);
323
+ if (existing !== void 0) return existing;
324
+ const index = this.borders.length;
325
+ this.borders.push({ edges });
326
+ this.borderIndexBySignature.set(signature, index);
327
+ return index;
328
+ }
329
+ };
330
+ const RESERVED_FILL_INDICES = {
331
+ none: NONE_FILL_INDEX,
332
+ gray125: GRAY125_FILL_INDEX,
333
+ firstReal: FIRST_REAL_FILL_INDEX
334
+ };
335
+ const RESERVED_BORDER_INDICES = {
336
+ empty: EMPTY_BORDER_INDEX,
337
+ firstReal: FIRST_REAL_BORDER_INDEX
68
338
  };
69
339
  //#endregion
70
340
  exports.CellFormatTable = CellFormatTable;
71
341
  exports.DEFAULT_CELL_FORMAT_INDEX = DEFAULT_CELL_FORMAT_INDEX;
72
342
  exports.GENERAL_NUM_FMT_ID = GENERAL_NUM_FMT_ID;
343
+ exports.RESERVED_BORDER_INDICES = RESERVED_BORDER_INDICES;
344
+ exports.RESERVED_FILL_INDICES = RESERVED_FILL_INDICES;
73
345
  exports.readCellFormatCodes = readCellFormatCodes;
346
+ exports.readCellStyles = readCellStyles;
@@ -1,21 +1,87 @@
1
1
  import { r as Package } from "../../package-L24lkba-.cjs";
2
2
  import { CellNumberFormat } from "./number-format.cjs";
3
+ import { Alignment, Color, ContentCellBorders } from "document-schema.js";
3
4
  //#region src/typed/xlsx/styles.d.ts
4
5
  declare const GENERAL_NUM_FMT_ID = 0;
6
+ interface CellStyleEntry {
7
+ numberFormatCode?: string;
8
+ background?: Color;
9
+ borders?: ContentCellBorders;
10
+ alignment?: Alignment;
11
+ verticalAlignment?: 'top' | 'middle' | 'bottom';
12
+ }
13
+ declare function readCellStyles(pkg: Package): readonly CellStyleEntry[];
5
14
  declare function readCellFormatCodes(pkg: Package): readonly (string | undefined)[];
6
15
  declare const DEFAULT_CELL_FORMAT_INDEX = 0;
7
16
  interface DeclaredNumberFormat {
8
17
  id: number;
9
18
  code: string;
10
19
  }
20
+ interface CellFormatDecoration {
21
+ background?: Color;
22
+ borders?: ContentCellBorders;
23
+ alignment?: Alignment;
24
+ verticalAlignment?: 'top' | 'middle' | 'bottom';
25
+ }
26
+ interface DeclaredFill {
27
+ patternType: 'none' | 'gray125' | 'solid';
28
+ rgb?: string;
29
+ }
30
+ interface DeclaredBorder {
31
+ edges: {
32
+ left?: {
33
+ style: string;
34
+ rgb: string;
35
+ };
36
+ right?: {
37
+ style: string;
38
+ rgb: string;
39
+ };
40
+ top?: {
41
+ style: string;
42
+ rgb: string;
43
+ };
44
+ bottom?: {
45
+ style: string;
46
+ rgb: string;
47
+ };
48
+ };
49
+ }
50
+ interface CellFormatRecord {
51
+ numFmtId: number;
52
+ fillId: number;
53
+ borderId: number;
54
+ alignment?: {
55
+ horizontal?: Alignment;
56
+ vertical?: 'top' | 'middle' | 'bottom';
57
+ };
58
+ }
11
59
  declare class CellFormatTable {
12
60
  private readonly indexBySignature;
13
- private readonly numFmtIdByIndex;
61
+ private readonly records;
14
62
  private readonly declared;
15
- intern(format: CellNumberFormat): number;
63
+ private readonly fillIndexByRgb;
64
+ private readonly fills;
65
+ private readonly borderIndexBySignature;
66
+ private readonly borders;
67
+ intern(format: CellNumberFormat, decoration?: CellFormatDecoration): number;
16
68
  declarations(): readonly DeclaredNumberFormat[];
17
69
  cellFormats(): readonly number[];
18
- private declare;
70
+ cellFormatRecords(): readonly CellFormatRecord[];
71
+ fillDeclarations(): readonly DeclaredFill[];
72
+ borderDeclarations(): readonly DeclaredBorder[];
73
+ private declareNumberFormat;
74
+ private internFill;
75
+ private internBorder;
19
76
  }
77
+ declare const RESERVED_FILL_INDICES: {
78
+ readonly none: 0;
79
+ readonly gray125: 1;
80
+ readonly firstReal: 2;
81
+ };
82
+ declare const RESERVED_BORDER_INDICES: {
83
+ readonly empty: 0;
84
+ readonly firstReal: 1;
85
+ };
20
86
  //#endregion
21
- export { CellFormatTable, DEFAULT_CELL_FORMAT_INDEX, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, readCellFormatCodes };
87
+ export { CellFormatDecoration, CellFormatRecord, CellFormatTable, CellStyleEntry, DEFAULT_CELL_FORMAT_INDEX, DeclaredBorder, DeclaredFill, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, RESERVED_BORDER_INDICES, RESERVED_FILL_INDICES, readCellFormatCodes, readCellStyles };
@@ -1,21 +1,87 @@
1
1
  import { r as Package } from "../../package-BUojjTXf.js";
2
2
  import { CellNumberFormat } from "./number-format.js";
3
+ import { Alignment, Color, ContentCellBorders } from "document-schema.js";
3
4
  //#region src/typed/xlsx/styles.d.ts
4
5
  declare const GENERAL_NUM_FMT_ID = 0;
6
+ interface CellStyleEntry {
7
+ numberFormatCode?: string;
8
+ background?: Color;
9
+ borders?: ContentCellBorders;
10
+ alignment?: Alignment;
11
+ verticalAlignment?: 'top' | 'middle' | 'bottom';
12
+ }
13
+ declare function readCellStyles(pkg: Package): readonly CellStyleEntry[];
5
14
  declare function readCellFormatCodes(pkg: Package): readonly (string | undefined)[];
6
15
  declare const DEFAULT_CELL_FORMAT_INDEX = 0;
7
16
  interface DeclaredNumberFormat {
8
17
  id: number;
9
18
  code: string;
10
19
  }
20
+ interface CellFormatDecoration {
21
+ background?: Color;
22
+ borders?: ContentCellBorders;
23
+ alignment?: Alignment;
24
+ verticalAlignment?: 'top' | 'middle' | 'bottom';
25
+ }
26
+ interface DeclaredFill {
27
+ patternType: 'none' | 'gray125' | 'solid';
28
+ rgb?: string;
29
+ }
30
+ interface DeclaredBorder {
31
+ edges: {
32
+ left?: {
33
+ style: string;
34
+ rgb: string;
35
+ };
36
+ right?: {
37
+ style: string;
38
+ rgb: string;
39
+ };
40
+ top?: {
41
+ style: string;
42
+ rgb: string;
43
+ };
44
+ bottom?: {
45
+ style: string;
46
+ rgb: string;
47
+ };
48
+ };
49
+ }
50
+ interface CellFormatRecord {
51
+ numFmtId: number;
52
+ fillId: number;
53
+ borderId: number;
54
+ alignment?: {
55
+ horizontal?: Alignment;
56
+ vertical?: 'top' | 'middle' | 'bottom';
57
+ };
58
+ }
11
59
  declare class CellFormatTable {
12
60
  private readonly indexBySignature;
13
- private readonly numFmtIdByIndex;
61
+ private readonly records;
14
62
  private readonly declared;
15
- intern(format: CellNumberFormat): number;
63
+ private readonly fillIndexByRgb;
64
+ private readonly fills;
65
+ private readonly borderIndexBySignature;
66
+ private readonly borders;
67
+ intern(format: CellNumberFormat, decoration?: CellFormatDecoration): number;
16
68
  declarations(): readonly DeclaredNumberFormat[];
17
69
  cellFormats(): readonly number[];
18
- private declare;
70
+ cellFormatRecords(): readonly CellFormatRecord[];
71
+ fillDeclarations(): readonly DeclaredFill[];
72
+ borderDeclarations(): readonly DeclaredBorder[];
73
+ private declareNumberFormat;
74
+ private internFill;
75
+ private internBorder;
19
76
  }
77
+ declare const RESERVED_FILL_INDICES: {
78
+ readonly none: 0;
79
+ readonly gray125: 1;
80
+ readonly firstReal: 2;
81
+ };
82
+ declare const RESERVED_BORDER_INDICES: {
83
+ readonly empty: 0;
84
+ readonly firstReal: 1;
85
+ };
20
86
  //#endregion
21
- export { CellFormatTable, DEFAULT_CELL_FORMAT_INDEX, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, readCellFormatCodes };
87
+ export { CellFormatDecoration, CellFormatRecord, CellFormatTable, CellStyleEntry, DEFAULT_CELL_FORMAT_INDEX, DeclaredBorder, DeclaredFill, DeclaredNumberFormat, GENERAL_NUM_FMT_ID, RESERVED_BORDER_INDICES, RESERVED_FILL_INDICES, readCellFormatCodes, readCellStyles };