ooxml.js 6.1.0 → 6.3.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.
@@ -0,0 +1,516 @@
1
+ import { parseXml } from "../../xml/parse.js";
2
+ import { buildXml } from "../../xml/build.js";
3
+ import { el, txt } from "../../xml/fragment.js";
4
+ import { encodeXmlText } from "../../xml/entities.js";
5
+ import { attr, childrenWithTag, decodeEntities, textContent } from "../util.js";
6
+ import { readXmlBool, writeXmlBool } from "./util.js";
7
+ import { colorFromElement, readColorRgb } from "./styles.js";
8
+ import { captureResidualAttributes, residualAttributesFor } from "./rule-residue.js";
9
+ import { formatSqref, parseSqref } from "./sqref.js";
10
+ import { colorToRgbHex } from "document-schema.js";
11
+ //#region src/typed/xlsx/conditional-format.ts
12
+ const CF_RULE_MANAGED_ATTRIBUTES = /* @__PURE__ */ new Set([
13
+ "type",
14
+ "dxfId",
15
+ "priority",
16
+ "stopIfTrue",
17
+ "operator",
18
+ "text",
19
+ "rank",
20
+ "percent",
21
+ "bottom",
22
+ "aboveAverage",
23
+ "equalAverage",
24
+ "stdDev",
25
+ "timePeriod",
26
+ "iconSet",
27
+ "reverse",
28
+ "showValue"
29
+ ]);
30
+ function readConditionalFormats(worksheet, dxfs) {
31
+ const formats = [];
32
+ const residueElements = [];
33
+ for (const wrapper of childrenWithTag(worksheet, "conditionalFormatting")) {
34
+ const ranges = parseSqref(attr(wrapper, "sqref"));
35
+ for (const cfRule of childrenWithTag(wrapper, "cfRule")) {
36
+ const promoted = ranges.length === 0 ? void 0 : readCfRule(cfRule, ranges, dxfs);
37
+ if (promoted === void 0) {
38
+ residueElements.push({
39
+ type: "element",
40
+ tag: "conditionalFormatting",
41
+ attributes: wrapper.attributes,
42
+ children: [cfRule]
43
+ });
44
+ continue;
45
+ }
46
+ formats.push(promoted);
47
+ }
48
+ }
49
+ return {
50
+ formats,
51
+ residueElements
52
+ };
53
+ }
54
+ function readCommonFields(cfRule, ranges) {
55
+ const result = { ranges: [...ranges] };
56
+ const priorityRaw = attr(cfRule, "priority");
57
+ if (priorityRaw !== void 0) {
58
+ const priority = Number.parseInt(priorityRaw, 10);
59
+ if (Number.isInteger(priority)) result.priority = priority;
60
+ }
61
+ if (readXmlBool(attr(cfRule, "stopIfTrue"))) result.stopIfTrue = true;
62
+ const source = captureResidualAttributes(cfRule, CF_RULE_MANAGED_ATTRIBUTES);
63
+ if (source !== void 0) result.source = source;
64
+ return result;
65
+ }
66
+ function readFormula(cfRule, index) {
67
+ const formulaEl = childrenWithTag(cfRule, "formula")[index];
68
+ return formulaEl === void 0 ? void 0 : textContent(formulaEl);
69
+ }
70
+ function isSheetRuleOperator(value) {
71
+ return value === "between" || value === "notBetween" || value === "equal" || value === "notEqual" || value === "greaterThan" || value === "greaterThanOrEqual" || value === "lessThan" || value === "lessThanOrEqual";
72
+ }
73
+ const TEXT_PREDICATE_TYPES = /* @__PURE__ */ new Set([
74
+ "containsText",
75
+ "notContainsText",
76
+ "beginsWith",
77
+ "endsWith"
78
+ ]);
79
+ function isTextPredicateType(value) {
80
+ return value !== void 0 && TEXT_PREDICATE_TYPES.has(value);
81
+ }
82
+ const OPERAND_FREE_TYPES = /* @__PURE__ */ new Set([
83
+ "containsBlanks",
84
+ "notContainsBlanks",
85
+ "containsErrors",
86
+ "notContainsErrors",
87
+ "uniqueValues",
88
+ "duplicateValues"
89
+ ]);
90
+ function isOperandFreeType(value) {
91
+ return value !== void 0 && OPERAND_FREE_TYPES.has(value);
92
+ }
93
+ const TIME_PERIODS = /* @__PURE__ */ new Set([
94
+ "yesterday",
95
+ "today",
96
+ "tomorrow",
97
+ "last7Days",
98
+ "thisMonth",
99
+ "lastMonth",
100
+ "nextMonth",
101
+ "thisWeek",
102
+ "lastWeek",
103
+ "nextWeek"
104
+ ]);
105
+ function isTimePeriod(value) {
106
+ return value !== void 0 && TIME_PERIODS.has(value);
107
+ }
108
+ function isCfvoType(value) {
109
+ return value === "num" || value === "percent" || value === "max" || value === "min" || value === "formula" || value === "percentile";
110
+ }
111
+ function readCfvo(cfvoEl) {
112
+ const type = attr(cfvoEl, "type");
113
+ if (!isCfvoType(type)) return;
114
+ if (type === "min" || type === "max") return { type };
115
+ const valRaw = attr(cfvoEl, "val");
116
+ if (valRaw === void 0) return;
117
+ return {
118
+ type,
119
+ value: decodeEntities(valRaw)
120
+ };
121
+ }
122
+ function readColorScaleStops(colorScaleEl) {
123
+ const cfvoEls = childrenWithTag(colorScaleEl, "cfvo");
124
+ const colorEls = childrenWithTag(colorScaleEl, "color");
125
+ if (cfvoEls.length !== colorEls.length || cfvoEls.length < 2 || cfvoEls.length > 3) return;
126
+ const stops = [];
127
+ for (let index = 0; index < cfvoEls.length; index++) {
128
+ const cfvoEl = cfvoEls[index];
129
+ const colorEl = colorEls[index];
130
+ if (cfvoEl === void 0 || colorEl === void 0) return;
131
+ const value = readCfvo(cfvoEl);
132
+ const color = colorFromElement(colorEl);
133
+ if (value === void 0 || color === void 0) return;
134
+ stops.push({
135
+ value,
136
+ color
137
+ });
138
+ }
139
+ return stops;
140
+ }
141
+ function readDataBar(dataBarEl) {
142
+ const cfvoEls = childrenWithTag(dataBarEl, "cfvo");
143
+ const minEl = cfvoEls[0];
144
+ const maxEl = cfvoEls[1];
145
+ const min = minEl === void 0 ? void 0 : readCfvo(minEl);
146
+ const max = maxEl === void 0 ? void 0 : readCfvo(maxEl);
147
+ const color = colorFromElement(childrenWithTag(dataBarEl, "color")[0]);
148
+ if (min === void 0 || max === void 0 || color === void 0) return;
149
+ const result = {
150
+ min,
151
+ max,
152
+ color
153
+ };
154
+ const showValueRaw = attr(dataBarEl, "showValue");
155
+ if (showValueRaw !== void 0 && !readXmlBool(showValueRaw)) result.showValue = false;
156
+ return result;
157
+ }
158
+ const DEFAULT_ICON_SET_TYPE = "3TrafficLights1";
159
+ function readIconSet(iconSetEl) {
160
+ const thresholds = [];
161
+ for (const cfvoEl of childrenWithTag(iconSetEl, "cfvo")) {
162
+ const value = readCfvo(cfvoEl);
163
+ if (value === void 0) return;
164
+ thresholds.push(value);
165
+ }
166
+ if (thresholds.length === 0) return;
167
+ const result = {
168
+ iconSetType: attr(iconSetEl, "iconSet") ?? DEFAULT_ICON_SET_TYPE,
169
+ thresholds
170
+ };
171
+ if (readXmlBool(attr(iconSetEl, "reverse"))) result.reverse = true;
172
+ const showValueRaw = attr(iconSetEl, "showValue");
173
+ if (showValueRaw !== void 0 && !readXmlBool(showValueRaw)) result.showValue = false;
174
+ return result;
175
+ }
176
+ function styleFromDxf(dxf) {
177
+ const fontEl = childrenWithTag(dxf, "font")[0];
178
+ const textColor = fontEl === void 0 ? void 0 : readColorRgb(fontEl, "color");
179
+ const fillEl = childrenWithTag(dxf, "fill")[0];
180
+ const patternFillEl = fillEl === void 0 ? void 0 : childrenWithTag(fillEl, "patternFill")[0];
181
+ const background = patternFillEl === void 0 ? void 0 : readColorRgb(patternFillEl, "bgColor");
182
+ const residueChildren = dxfResidueChildren(dxf, textColor !== void 0, background !== void 0);
183
+ const style = {};
184
+ if (textColor !== void 0) style.textColor = textColor;
185
+ if (background !== void 0) style.background = background;
186
+ if (residueChildren.length > 0) style.source = {
187
+ format: "xlsx",
188
+ xml: buildXml(residueChildren)
189
+ };
190
+ return style.textColor === void 0 && style.background === void 0 && style.source === void 0 ? void 0 : style;
191
+ }
192
+ function withoutChildTag(element, tag) {
193
+ const remaining = element.children.filter((child) => !(child.type === "element" && child.tag === tag));
194
+ if (remaining.length === 0 && element.attributes.length === 0) return;
195
+ return {
196
+ ...element,
197
+ children: remaining
198
+ };
199
+ }
200
+ function fillResidue(fillEl) {
201
+ const patternFillEl = childrenWithTag(fillEl, "patternFill")[0];
202
+ const otherFillChildren = fillEl.children.filter((child) => !(child.type === "element" && child.tag === "patternFill"));
203
+ if (patternFillEl === void 0) return otherFillChildren.length === 0 && fillEl.attributes.length === 0 ? void 0 : {
204
+ ...fillEl,
205
+ children: otherFillChildren
206
+ };
207
+ const patternFillResidue = withoutChildTag(patternFillEl, "bgColor");
208
+ if (patternFillResidue === void 0) return otherFillChildren.length === 0 && fillEl.attributes.length === 0 ? void 0 : {
209
+ ...fillEl,
210
+ children: otherFillChildren
211
+ };
212
+ return {
213
+ ...fillEl,
214
+ children: [patternFillResidue, ...otherFillChildren]
215
+ };
216
+ }
217
+ function dxfResidueChildren(dxf, textColorCaptured, backgroundCaptured) {
218
+ const residue = [];
219
+ for (const child of dxf.children) {
220
+ if (child.type !== "element") continue;
221
+ if (child.tag === "font" && textColorCaptured) {
222
+ const remainder = withoutChildTag(child, "color");
223
+ if (remainder !== void 0) residue.push(remainder);
224
+ continue;
225
+ }
226
+ if (child.tag === "fill" && backgroundCaptured) {
227
+ const remainder = fillResidue(child);
228
+ if (remainder !== void 0) residue.push(remainder);
229
+ continue;
230
+ }
231
+ residue.push(child);
232
+ }
233
+ return residue;
234
+ }
235
+ function resolveStyle(cfRule, dxfs) {
236
+ const dxfIdRaw = attr(cfRule, "dxfId");
237
+ if (dxfIdRaw === void 0) return;
238
+ const dxfId = Number.parseInt(dxfIdRaw, 10);
239
+ const dxf = Number.isInteger(dxfId) ? dxfs[dxfId] : void 0;
240
+ return dxf === void 0 ? void 0 : styleFromDxf(dxf);
241
+ }
242
+ function readCfRule(cfRule, ranges, dxfs) {
243
+ const type = attr(cfRule, "type");
244
+ const common = readCommonFields(cfRule, ranges);
245
+ const style = resolveStyle(cfRule, dxfs);
246
+ const styleField = style === void 0 ? {} : { style };
247
+ if (type === "cellIs") {
248
+ const operatorRaw = attr(cfRule, "operator");
249
+ const formula1 = readFormula(cfRule, 0);
250
+ if (!isSheetRuleOperator(operatorRaw) || formula1 === void 0) return;
251
+ const formula2 = operatorRaw === "between" || operatorRaw === "notBetween" ? readFormula(cfRule, 1) : void 0;
252
+ return {
253
+ type: "cellIs",
254
+ ...common,
255
+ operator: operatorRaw,
256
+ formula1,
257
+ ...formula2 === void 0 ? {} : { formula2 },
258
+ ...styleField
259
+ };
260
+ }
261
+ if (isTextPredicateType(type)) {
262
+ const text = attr(cfRule, "text");
263
+ if (text === void 0) return;
264
+ return {
265
+ type,
266
+ ...common,
267
+ text: decodeEntities(text),
268
+ ...styleField
269
+ };
270
+ }
271
+ if (isOperandFreeType(type)) return {
272
+ type,
273
+ ...common,
274
+ ...styleField
275
+ };
276
+ if (type === "top10") {
277
+ const rankRaw = attr(cfRule, "rank");
278
+ const rank = rankRaw === void 0 ? void 0 : Number(rankRaw);
279
+ if (rank === void 0 || !Number.isFinite(rank) || rank <= 0) return;
280
+ return {
281
+ type: "top10",
282
+ ...common,
283
+ rank,
284
+ ...readXmlBool(attr(cfRule, "percent")) ? { percent: true } : {},
285
+ ...readXmlBool(attr(cfRule, "bottom")) ? { bottom: true } : {},
286
+ ...styleField
287
+ };
288
+ }
289
+ if (type === "aboveAverage") {
290
+ const aboveAverageRaw = attr(cfRule, "aboveAverage");
291
+ const stdDevRaw = attr(cfRule, "stdDev");
292
+ const stdDev = stdDevRaw === void 0 ? void 0 : Number.parseInt(stdDevRaw, 10);
293
+ return {
294
+ type: "aboveAverage",
295
+ ...common,
296
+ ...aboveAverageRaw !== void 0 && !readXmlBool(aboveAverageRaw) ? { aboveAverage: false } : {},
297
+ ...readXmlBool(attr(cfRule, "equalAverage")) ? { equalAverage: true } : {},
298
+ ...stdDev !== void 0 && Number.isInteger(stdDev) && stdDev > 0 ? { stdDev } : {},
299
+ ...styleField
300
+ };
301
+ }
302
+ if (type === "timePeriod") {
303
+ const timePeriod = attr(cfRule, "timePeriod");
304
+ if (!isTimePeriod(timePeriod)) return;
305
+ return {
306
+ type: "timePeriod",
307
+ ...common,
308
+ timePeriod,
309
+ ...styleField
310
+ };
311
+ }
312
+ if (type === "colorScale") {
313
+ const colorScaleEl = childrenWithTag(cfRule, "colorScale")[0];
314
+ const stops = colorScaleEl === void 0 ? void 0 : readColorScaleStops(colorScaleEl);
315
+ if (stops === void 0) return;
316
+ return {
317
+ type: "colorScale",
318
+ ...common,
319
+ stops
320
+ };
321
+ }
322
+ if (type === "dataBar") {
323
+ const dataBarEl = childrenWithTag(cfRule, "dataBar")[0];
324
+ const parsed = dataBarEl === void 0 ? void 0 : readDataBar(dataBarEl);
325
+ if (parsed === void 0) return;
326
+ return {
327
+ type: "dataBar",
328
+ ...common,
329
+ min: parsed.min,
330
+ max: parsed.max,
331
+ color: parsed.color,
332
+ ...parsed.showValue === void 0 ? {} : { showValue: parsed.showValue }
333
+ };
334
+ }
335
+ if (type === "iconSet") {
336
+ const iconSetEl = childrenWithTag(cfRule, "iconSet")[0];
337
+ const parsed = iconSetEl === void 0 ? void 0 : readIconSet(iconSetEl);
338
+ if (parsed === void 0) return;
339
+ return {
340
+ type: "iconSet",
341
+ ...common,
342
+ iconSetType: parsed.iconSetType,
343
+ thresholds: parsed.thresholds,
344
+ ...parsed.reverse === void 0 ? {} : { reverse: parsed.reverse },
345
+ ...parsed.showValue === void 0 ? {} : { showValue: parsed.showValue }
346
+ };
347
+ }
348
+ }
349
+ var DxfTable = class {
350
+ elements = [];
351
+ intern(style) {
352
+ const index = this.elements.length;
353
+ this.elements.push(buildDxfElement(style));
354
+ return index;
355
+ }
356
+ dxfElements() {
357
+ return this.elements;
358
+ }
359
+ };
360
+ function attrsRecord(attributes) {
361
+ const result = {};
362
+ for (const attribute of attributes) result[attribute.name] = attribute.value;
363
+ return result;
364
+ }
365
+ function extractResidueElements(source) {
366
+ if (source?.format !== "xlsx") return [];
367
+ const elements = [];
368
+ for (const node of parseXml(source.xml)) if (node.type === "element") elements.push(node);
369
+ return elements;
370
+ }
371
+ function buildDxfElement(style) {
372
+ const residueByTag = /* @__PURE__ */ new Map();
373
+ for (const element of extractResidueElements(style.source)) residueByTag.set(element.tag, element);
374
+ const children = [];
375
+ const residualFont = residueByTag.get("font");
376
+ if (style.textColor !== void 0) {
377
+ const fontChildren = residualFont === void 0 ? [] : residualFont.children;
378
+ const fontAttrs = residualFont === void 0 ? {} : attrsRecord(residualFont.attributes);
379
+ children.push(el("font", fontAttrs, [...fontChildren, el("color", { rgb: `FF${colorToRgbHex(style.textColor)}` })]));
380
+ } else if (residualFont !== void 0) children.push(residualFont);
381
+ const residualNumFmt = residueByTag.get("numFmt");
382
+ if (residualNumFmt !== void 0) children.push(residualNumFmt);
383
+ const residualFill = residueByTag.get("fill");
384
+ if (style.background !== void 0) {
385
+ const residualPatternFill = residualFill === void 0 ? void 0 : childrenWithTag(residualFill, "patternFill")[0];
386
+ const patternFillChildren = residualPatternFill === void 0 ? [] : residualPatternFill.children;
387
+ const patternFillAttrs = residualPatternFill === void 0 ? {} : attrsRecord(residualPatternFill.attributes);
388
+ const otherFillChildren = residualFill === void 0 ? [] : residualFill.children.filter((child) => !(child.type === "element" && child.tag === "patternFill"));
389
+ children.push(el("fill", residualFill === void 0 ? {} : attrsRecord(residualFill.attributes), [el("patternFill", patternFillAttrs, [...patternFillChildren, el("bgColor", { rgb: `FF${colorToRgbHex(style.background)}` })]), ...otherFillChildren]));
390
+ } else if (residualFill !== void 0) children.push(residualFill);
391
+ for (const tag of [
392
+ "alignment",
393
+ "border",
394
+ "protection"
395
+ ]) {
396
+ const residual = residueByTag.get(tag);
397
+ if (residual !== void 0) children.push(residual);
398
+ }
399
+ return el("dxf", {}, children);
400
+ }
401
+ function rangeSetKey(ranges) {
402
+ return ranges.map((range) => `${range.startRow}:${range.startColumn}:${range.endRow}:${range.endColumn}`).join("|");
403
+ }
404
+ const TEXT_PREDICATE_OPERATOR = {
405
+ containsText: "containsText",
406
+ notContainsText: "notContains",
407
+ beginsWith: "beginsWith",
408
+ endsWith: "endsWith"
409
+ };
410
+ function buildCfvoElement(value) {
411
+ const attrs = { type: value.type };
412
+ if (value.value !== void 0) attrs.val = encodeXmlText(value.value);
413
+ return el("cfvo", attrs);
414
+ }
415
+ function buildCfRuleElement(rule, priority, dxfTable) {
416
+ const attrs = residualAttributesFor(rule.source, "cfRule");
417
+ attrs.type = rule.type;
418
+ attrs.priority = String(priority);
419
+ if (rule.stopIfTrue === true) attrs.stopIfTrue = writeXmlBool(true);
420
+ const children = [];
421
+ let style;
422
+ switch (rule.type) {
423
+ case "cellIs":
424
+ attrs.operator = rule.operator;
425
+ children.push(el("formula", {}, [txt(encodeXmlText(rule.formula1))]));
426
+ if (rule.formula2 !== void 0) children.push(el("formula", {}, [txt(encodeXmlText(rule.formula2))]));
427
+ style = rule.style;
428
+ break;
429
+ case "containsText":
430
+ case "notContainsText":
431
+ case "beginsWith":
432
+ case "endsWith":
433
+ attrs.operator = TEXT_PREDICATE_OPERATOR[rule.type];
434
+ attrs.text = encodeXmlText(rule.text);
435
+ style = rule.style;
436
+ break;
437
+ case "containsBlanks":
438
+ case "notContainsBlanks":
439
+ case "containsErrors":
440
+ case "notContainsErrors":
441
+ case "uniqueValues":
442
+ case "duplicateValues":
443
+ style = rule.style;
444
+ break;
445
+ case "top10":
446
+ attrs.rank = String(rule.rank);
447
+ if (rule.percent === true) attrs.percent = writeXmlBool(true);
448
+ if (rule.bottom === true) attrs.bottom = writeXmlBool(true);
449
+ style = rule.style;
450
+ break;
451
+ case "aboveAverage":
452
+ if (rule.aboveAverage === false) attrs.aboveAverage = writeXmlBool(false);
453
+ if (rule.equalAverage === true) attrs.equalAverage = writeXmlBool(true);
454
+ if (rule.stdDev !== void 0) attrs.stdDev = String(rule.stdDev);
455
+ style = rule.style;
456
+ break;
457
+ case "timePeriod":
458
+ attrs.timePeriod = rule.timePeriod;
459
+ style = rule.style;
460
+ break;
461
+ case "colorScale":
462
+ children.push(el("colorScale", {}, [...rule.stops.map((stop) => buildCfvoElement(stop.value)), ...rule.stops.map((stop) => el("color", { rgb: `FF${colorToRgbHex(stop.color)}` }))]));
463
+ break;
464
+ case "dataBar": {
465
+ const dataBarChildren = [
466
+ buildCfvoElement(rule.min),
467
+ buildCfvoElement(rule.max),
468
+ el("color", { rgb: `FF${colorToRgbHex(rule.color)}` })
469
+ ];
470
+ const dataBarAttrs = rule.showValue === false ? { showValue: writeXmlBool(false) } : {};
471
+ children.push(el("dataBar", dataBarAttrs, dataBarChildren));
472
+ break;
473
+ }
474
+ case "iconSet": {
475
+ const iconSetAttrs = {};
476
+ if (rule.iconSetType !== DEFAULT_ICON_SET_TYPE) iconSetAttrs.iconSet = rule.iconSetType;
477
+ if (rule.reverse === true) iconSetAttrs.reverse = writeXmlBool(true);
478
+ if (rule.showValue === false) iconSetAttrs.showValue = writeXmlBool(false);
479
+ children.push(el("iconSet", iconSetAttrs, rule.thresholds.map(buildCfvoElement)));
480
+ break;
481
+ }
482
+ }
483
+ if (style !== void 0) attrs.dxfId = String(dxfTable.intern(style));
484
+ return el("cfRule", attrs, children);
485
+ }
486
+ function buildConditionalFormattingElements(formats, dxfTable) {
487
+ const groupsByKey = /* @__PURE__ */ new Map();
488
+ const groupOrder = [];
489
+ for (const format of formats) {
490
+ const key = rangeSetKey(format.ranges);
491
+ const existing = groupsByKey.get(key);
492
+ if (existing === void 0) {
493
+ const group = {
494
+ ranges: format.ranges,
495
+ rules: [format]
496
+ };
497
+ groupsByKey.set(key, group);
498
+ groupOrder.push(group);
499
+ } else existing.rules.push(format);
500
+ }
501
+ const usedPriorities = /* @__PURE__ */ new Set();
502
+ for (const format of formats) if (format.priority !== void 0) usedPriorities.add(format.priority);
503
+ let nextPriority = 1;
504
+ const assignPriority = (explicit) => {
505
+ if (explicit !== void 0) return explicit;
506
+ while (usedPriorities.has(nextPriority)) nextPriority++;
507
+ usedPriorities.add(nextPriority);
508
+ return nextPriority++;
509
+ };
510
+ return groupOrder.map((group) => {
511
+ const cfRuleElements = group.rules.map((rule) => buildCfRuleElement(rule, assignPriority(rule.priority), dxfTable));
512
+ return el("conditionalFormatting", { sqref: formatSqref(group.ranges) }, cfRuleElements);
513
+ });
514
+ }
515
+ //#endregion
516
+ export { DxfTable, buildConditionalFormattingElements, readConditionalFormats };
@@ -12,6 +12,8 @@ const require_typed_xlsx_serial = require("./serial.cjs");
12
12
  const require_typed_xlsx_shared_strings = require("./shared-strings.cjs");
13
13
  const require_typed_xlsx_styles = require("./styles.cjs");
14
14
  const require_typed_xlsx_comments = require("./comments.cjs");
15
+ const require_typed_xlsx_conditional_format = require("./conditional-format.cjs");
16
+ const require_typed_xlsx_data_validation = require("./data-validation.cjs");
15
17
  let document_schema_js = require("document-schema.js");
16
18
  //#region src/typed/xlsx/content.ts
17
19
  const WORKBOOK_PATH = "xl/workbook.xml";
@@ -268,6 +270,7 @@ function readCell(cell, sharedStrings, context) {
268
270
  if (entry.borders !== void 0) cellEntry.borders = entry.borders;
269
271
  if (entry.alignment !== void 0) cellEntry.alignment = entry.alignment;
270
272
  if (entry.verticalAlignment !== void 0) cellEntry.verticalAlignment = entry.verticalAlignment;
273
+ if (entry.numberFormatCode !== void 0) cellEntry.numberFormatCode = entry.numberFormatCode;
271
274
  }
272
275
  return cellEntry;
273
276
  }
@@ -320,10 +323,7 @@ function applyCellComments(comments, cells) {
320
323
  byPosition.set(key, materialised);
321
324
  }
322
325
  }
323
- function applyCellResidueRules(worksheet, cells) {
324
- const rules = [];
325
- for (const container of require_typed_util.childrenWithTag(worksheet, "dataValidations")) rules.push(...require_typed_util.childrenWithTag(container, "dataValidation"));
326
- rules.push(...require_typed_util.childrenWithTag(worksheet, "conditionalFormatting"));
326
+ function applyCellResidueRules(cells, rules) {
327
327
  if (rules.length === 0) return;
328
328
  const byPosition = /* @__PURE__ */ new Map();
329
329
  for (const cell of cells) byPosition.set(`${cell.row}:${cell.column}`, cell);
@@ -355,7 +355,7 @@ function applyCellResidueRules(worksheet, cells) {
355
355
  };
356
356
  }
357
357
  }
358
- function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context) {
358
+ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context, dxfs) {
359
359
  const worksheet = require_typed_util.rootElement(pkg.parts[entry.path]);
360
360
  if (worksheet === void 0) return {
361
361
  name: entry.name,
@@ -367,7 +367,9 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, c
367
367
  };
368
368
  const cells = readCells(worksheet, sharedStrings, context);
369
369
  applyCellComments(require_typed_xlsx_comments.readSheetCellComments(pkg, entry.path), cells);
370
- applyCellResidueRules(worksheet, cells);
370
+ const { validations, residueElements: dataValidationResidue } = require_typed_xlsx_data_validation.readDataValidations(worksheet);
371
+ const { formats, residueElements: conditionalFormatResidue } = require_typed_xlsx_conditional_format.readConditionalFormats(worksheet, dxfs);
372
+ applyCellResidueRules(cells, [...dataValidationResidue, ...conditionalFormatResidue]);
371
373
  const drawing = require_typed_xlsx_drawings.readSheetDrawing(pkg, entry.path, worksheet);
372
374
  return {
373
375
  name: entry.name,
@@ -376,6 +378,8 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, c
376
378
  rows: readRows(worksheet),
377
379
  images: drawing.images,
378
380
  ...drawing.embeddedObjects === void 0 ? {} : { embeddedObjects: drawing.embeddedObjects },
381
+ ...validations.length === 0 ? {} : { dataValidations: validations },
382
+ ...formats.length === 0 ? {} : { conditionalFormats: formats },
379
383
  printSettings: require_typed_xlsx_print_settings.readPrintSettings(worksheet, sheetIndex, definedNamesBySheet)
380
384
  };
381
385
  }
@@ -391,7 +395,8 @@ function readXlsxContent(pkg) {
391
395
  const sharedStrings = require_typed_xlsx_shared_strings.loadSharedStrings(pkg);
392
396
  const definedNamesBySheet = require_typed_xlsx_defined_names.readDefinedNamesBySheet(pkg);
393
397
  const context = readCellFormatContext(pkg);
394
- const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context));
398
+ const dxfs = require_typed_xlsx_styles.readDxfElements(pkg);
399
+ const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context, dxfs));
395
400
  return {
396
401
  kind: "spreadsheet",
397
402
  metadata: require_typed_shared_metadata.readCoreProperties(pkg),
@@ -9,8 +9,10 @@ import { columnWidthCharsToPt } from "./units.js";
9
9
  import { readSheetDrawing } from "./drawings.js";
10
10
  import { readDate1904, serialToIsoDate, serialToIsoDateTime, serialToIsoTime } from "./serial.js";
11
11
  import { loadSharedStrings } from "./shared-strings.js";
12
- import { readCellStyles } from "./styles.js";
12
+ import { readCellStyles, readDxfElements } from "./styles.js";
13
13
  import { readSheetCellComments } from "./comments.js";
14
+ import { readConditionalFormats } from "./conditional-format.js";
15
+ import { readDataValidations } from "./data-validation.js";
14
16
  import { parseCellReference, parseRangeReference } from "document-schema.js";
15
17
  //#region src/typed/xlsx/content.ts
16
18
  const WORKBOOK_PATH = "xl/workbook.xml";
@@ -267,6 +269,7 @@ function readCell(cell, sharedStrings, context) {
267
269
  if (entry.borders !== void 0) cellEntry.borders = entry.borders;
268
270
  if (entry.alignment !== void 0) cellEntry.alignment = entry.alignment;
269
271
  if (entry.verticalAlignment !== void 0) cellEntry.verticalAlignment = entry.verticalAlignment;
272
+ if (entry.numberFormatCode !== void 0) cellEntry.numberFormatCode = entry.numberFormatCode;
270
273
  }
271
274
  return cellEntry;
272
275
  }
@@ -319,10 +322,7 @@ function applyCellComments(comments, cells) {
319
322
  byPosition.set(key, materialised);
320
323
  }
321
324
  }
322
- function applyCellResidueRules(worksheet, cells) {
323
- const rules = [];
324
- for (const container of childrenWithTag(worksheet, "dataValidations")) rules.push(...childrenWithTag(container, "dataValidation"));
325
- rules.push(...childrenWithTag(worksheet, "conditionalFormatting"));
325
+ function applyCellResidueRules(cells, rules) {
326
326
  if (rules.length === 0) return;
327
327
  const byPosition = /* @__PURE__ */ new Map();
328
328
  for (const cell of cells) byPosition.set(`${cell.row}:${cell.column}`, cell);
@@ -354,7 +354,7 @@ function applyCellResidueRules(worksheet, cells) {
354
354
  };
355
355
  }
356
356
  }
357
- function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context) {
357
+ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context, dxfs) {
358
358
  const worksheet = rootElement(pkg.parts[entry.path]);
359
359
  if (worksheet === void 0) return {
360
360
  name: entry.name,
@@ -366,7 +366,9 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, c
366
366
  };
367
367
  const cells = readCells(worksheet, sharedStrings, context);
368
368
  applyCellComments(readSheetCellComments(pkg, entry.path), cells);
369
- applyCellResidueRules(worksheet, cells);
369
+ const { validations, residueElements: dataValidationResidue } = readDataValidations(worksheet);
370
+ const { formats, residueElements: conditionalFormatResidue } = readConditionalFormats(worksheet, dxfs);
371
+ applyCellResidueRules(cells, [...dataValidationResidue, ...conditionalFormatResidue]);
370
372
  const drawing = readSheetDrawing(pkg, entry.path, worksheet);
371
373
  return {
372
374
  name: entry.name,
@@ -375,6 +377,8 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, c
375
377
  rows: readRows(worksheet),
376
378
  images: drawing.images,
377
379
  ...drawing.embeddedObjects === void 0 ? {} : { embeddedObjects: drawing.embeddedObjects },
380
+ ...validations.length === 0 ? {} : { dataValidations: validations },
381
+ ...formats.length === 0 ? {} : { conditionalFormats: formats },
378
382
  printSettings: readPrintSettings(worksheet, sheetIndex, definedNamesBySheet)
379
383
  };
380
384
  }
@@ -390,7 +394,8 @@ function readXlsxContent(pkg) {
390
394
  const sharedStrings = loadSharedStrings(pkg);
391
395
  const definedNamesBySheet = readDefinedNamesBySheet(pkg);
392
396
  const context = readCellFormatContext(pkg);
393
- const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context));
397
+ const dxfs = readDxfElements(pkg);
398
+ const sheets = resolveSheetEntries(pkg).map((entry, sheetIndex) => readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context, dxfs));
394
399
  return {
395
400
  kind: "spreadsheet",
396
401
  metadata: readCoreProperties(pkg),