@shbernal/ts-xlsx 2.1.0 → 3.1.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.
Files changed (225) hide show
  1. package/README.md +4 -1
  2. package/dist/bytes.d.ts +7 -0
  3. package/dist/bytes.js +22 -0
  4. package/dist/core/address.d.ts +60 -2
  5. package/dist/core/address.js +40 -24
  6. package/dist/core/autofilter.d.ts +5 -4
  7. package/dist/core/autofilter.js +34 -35
  8. package/dist/core/axis-handle.d.ts +10 -0
  9. package/dist/core/axis-handle.js +17 -0
  10. package/dist/core/cell.d.ts +25 -0
  11. package/dist/core/cell.js +9 -3
  12. package/dist/core/clone.d.ts +29 -0
  13. package/dist/core/clone.js +24 -0
  14. package/dist/core/color-resolution.js +2 -4
  15. package/dist/core/column.d.ts +5 -1
  16. package/dist/core/column.js +34 -35
  17. package/dist/core/comment-thread.js +2 -1
  18. package/dist/core/conditional-formatting-overlay.d.ts +2 -1
  19. package/dist/core/conditional-formatting-overlay.js +2 -2
  20. package/dist/core/conditional-formatting.d.ts +14 -6
  21. package/dist/core/conditional-formatting.js +45 -43
  22. package/dist/core/containers.d.ts +12 -0
  23. package/dist/core/containers.js +5 -0
  24. package/dist/core/data-validation-overlay.d.ts +2 -1
  25. package/dist/core/data-validation-overlay.js +4 -4
  26. package/dist/core/data-validation.d.ts +9 -3
  27. package/dist/core/data-validation.js +21 -18
  28. package/dist/core/date-format.d.ts +20 -0
  29. package/dist/core/date-format.js +160 -0
  30. package/dist/core/date.d.ts +43 -8
  31. package/dist/core/date.js +18 -2
  32. package/dist/core/formula.d.ts +26 -0
  33. package/dist/core/formula.js +20 -4
  34. package/dist/core/grid-edits.d.ts +2 -3
  35. package/dist/core/grid-edits.js +69 -70
  36. package/dist/core/grid-shift.d.ts +58 -9
  37. package/dist/core/grid-shift.js +26 -4
  38. package/dist/core/image.d.ts +14 -10
  39. package/dist/core/image.js +9 -9
  40. package/dist/core/internal.d.ts +8 -2
  41. package/dist/core/limits.d.ts +23 -0
  42. package/dist/core/limits.js +4 -0
  43. package/dist/core/merge-index.d.ts +31 -0
  44. package/dist/core/merge-index.js +60 -0
  45. package/dist/core/merge.d.ts +5 -14
  46. package/dist/core/merge.js +18 -27
  47. package/dist/core/page-setup.d.ts +72 -2
  48. package/dist/core/page-setup.js +34 -8
  49. package/dist/core/pivot-table.d.ts +1 -1
  50. package/dist/core/pivot-table.js +67 -53
  51. package/dist/core/protection.js +2 -11
  52. package/dist/core/range.js +34 -30
  53. package/dist/core/row-input.js +2 -2
  54. package/dist/core/row.d.ts +5 -1
  55. package/dist/core/row.js +22 -23
  56. package/dist/core/style.d.ts +134 -75
  57. package/dist/core/style.js +112 -53
  58. package/dist/core/table-style.d.ts +1 -1
  59. package/dist/core/table-style.js +4 -4
  60. package/dist/core/table.d.ts +28 -10
  61. package/dist/core/table.js +54 -39
  62. package/dist/core/theme.js +6 -5
  63. package/dist/core/used-extent.d.ts +44 -0
  64. package/dist/core/used-extent.js +102 -0
  65. package/dist/core/value.d.ts +9 -0
  66. package/dist/core/value.js +36 -34
  67. package/dist/core/workbook-media.d.ts +34 -0
  68. package/dist/core/workbook-media.js +44 -0
  69. package/dist/core/workbook-styles.d.ts +67 -1
  70. package/dist/core/workbook-vba.js +3 -2
  71. package/dist/core/workbook.d.ts +23 -2
  72. package/dist/core/workbook.js +24 -40
  73. package/dist/core/worksheet-comments.d.ts +2 -1
  74. package/dist/core/worksheet-comments.js +20 -13
  75. package/dist/core/worksheet-merges.d.ts +44 -0
  76. package/dist/core/worksheet-merges.js +59 -0
  77. package/dist/core/worksheet-model.d.ts +9 -1
  78. package/dist/core/worksheet-model.js +24 -9
  79. package/dist/core/worksheet.d.ts +72 -12
  80. package/dist/core/worksheet.js +68 -70
  81. package/dist/customui/ribbon.js +6 -7
  82. package/dist/entries/core.d.ts +18 -13
  83. package/dist/entries/core.js +12 -6
  84. package/dist/entries/xlsx.d.ts +1 -1
  85. package/dist/errors.d.ts +64 -0
  86. package/dist/errors.js +22 -0
  87. package/dist/hex.d.ts +8 -0
  88. package/dist/hex.js +3 -0
  89. package/dist/io/csv/delimiter.d.ts +9 -0
  90. package/dist/io/csv/delimiter.js +6 -0
  91. package/dist/io/csv/read.js +11 -4
  92. package/dist/io/csv/write.d.ts +9 -2
  93. package/dist/io/csv/write.js +9 -38
  94. package/dist/io/opc/inflate.js +15 -1
  95. package/dist/io/opc/namespaces.d.ts +16 -0
  96. package/dist/io/opc/namespaces.js +4 -0
  97. package/dist/io/opc/part-paths.d.ts +10 -0
  98. package/dist/io/opc/part-paths.js +16 -1
  99. package/dist/io/opc/read-opc.d.ts +69 -10
  100. package/dist/io/opc/read-opc.js +49 -55
  101. package/dist/io/opc/read-options.d.ts +5 -1
  102. package/dist/io/opc/rels.d.ts +1 -6
  103. package/dist/io/opc/rels.js +1 -4
  104. package/dist/io/opc/sniff-format.d.ts +3 -3
  105. package/dist/io/opc/sniff-format.js +2 -2
  106. package/dist/io/style/xf-style.d.ts +48 -2
  107. package/dist/io/style/xf-style.js +14 -0
  108. package/dist/io/xlsb/formula.d.ts +2 -2
  109. package/dist/io/xlsb/formula.js +49 -34
  110. package/dist/io/xlsb/primitives.js +8 -14
  111. package/dist/io/xlsb/ptg-functions.d.ts +19 -10
  112. package/dist/io/xlsb/ptg-functions.js +385 -596
  113. package/dist/io/xlsb/read-styles.js +50 -83
  114. package/dist/io/xlsb/read-worksheet.d.ts +20 -1
  115. package/dist/io/xlsb/read-worksheet.js +73 -89
  116. package/dist/io/xlsb/read.d.ts +6 -3
  117. package/dist/io/xlsb/read.js +47 -29
  118. package/dist/io/xlsb/record-stream.d.ts +30 -0
  119. package/dist/io/xlsb/record-stream.js +20 -0
  120. package/dist/io/xlsb/record-types.d.ts +1 -5
  121. package/dist/io/xlsb/record-types.js +1 -5
  122. package/dist/io/xlsx/cell-accumulator.d.ts +9 -2
  123. package/dist/io/xlsx/cell-accumulator.js +32 -9
  124. package/dist/io/xlsx/cell-style-resolution.d.ts +25 -0
  125. package/dist/io/xlsx/cell-style-resolution.js +29 -0
  126. package/dist/io/xlsx/cell-value.d.ts +5 -3
  127. package/dist/io/xlsx/cell-value.js +13 -15
  128. package/dist/io/xlsx/color-xml.js +3 -2
  129. package/dist/io/xlsx/column-budget.d.ts +26 -0
  130. package/dist/io/xlsx/column-budget.js +22 -0
  131. package/dist/io/xlsx/comments.d.ts +6 -2
  132. package/dist/io/xlsx/comments.js +36 -31
  133. package/dist/io/xlsx/conditional-formatting.d.ts +9 -5
  134. package/dist/io/xlsx/conditional-formatting.js +51 -46
  135. package/dist/io/xlsx/data-validation.d.ts +9 -7
  136. package/dist/io/xlsx/data-validation.js +38 -35
  137. package/dist/io/xlsx/edit-vba.d.ts +7 -2
  138. package/dist/io/xlsx/edit-vba.js +15 -29
  139. package/dist/io/xlsx/font-xml.d.ts +7 -0
  140. package/dist/io/xlsx/font-xml.js +104 -0
  141. package/dist/io/xlsx/hyperlinks.d.ts +41 -7
  142. package/dist/io/xlsx/hyperlinks.js +40 -28
  143. package/dist/io/xlsx/images.js +24 -25
  144. package/dist/io/xlsx/namespaces.d.ts +16 -0
  145. package/dist/io/xlsx/namespaces.js +7 -0
  146. package/dist/io/xlsx/package-plan.d.ts +23 -3
  147. package/dist/io/xlsx/package-plan.js +66 -25
  148. package/dist/io/xlsx/part-names.d.ts +41 -0
  149. package/dist/io/xlsx/part-names.js +46 -0
  150. package/dist/io/xlsx/pivot.js +8 -7
  151. package/dist/io/xlsx/read-parts.d.ts +59 -0
  152. package/dist/io/xlsx/read-parts.js +252 -0
  153. package/dist/io/xlsx/read-pivot.js +3 -1
  154. package/dist/io/xlsx/read-repair.d.ts +26 -0
  155. package/dist/io/xlsx/read-repair.js +39 -0
  156. package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +1 -1
  157. package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +7 -3
  158. package/dist/io/xlsx/read-rows.d.ts +18 -5
  159. package/dist/io/xlsx/read-rows.js +50 -37
  160. package/dist/io/xlsx/read-shared-strings.js +5 -3
  161. package/dist/io/xlsx/read-styles.d.ts +1 -6
  162. package/dist/io/xlsx/read-styles.js +65 -109
  163. package/dist/io/xlsx/read-workbook-xml.d.ts +36 -0
  164. package/dist/io/xlsx/read-workbook-xml.js +170 -0
  165. package/dist/io/xlsx/read-worksheet.d.ts +11 -1
  166. package/dist/io/xlsx/read-worksheet.js +51 -193
  167. package/dist/io/xlsx/read.d.ts +5 -13
  168. package/dist/io/xlsx/read.js +111 -436
  169. package/dist/io/xlsx/rich-text.js +1 -1
  170. package/dist/io/xlsx/row-position.d.ts +18 -0
  171. package/dist/io/xlsx/row-position.js +11 -0
  172. package/dist/io/xlsx/row-xml.d.ts +128 -0
  173. package/dist/io/xlsx/row-xml.js +203 -0
  174. package/dist/io/xlsx/shared-formulas.js +2 -2
  175. package/dist/io/xlsx/sheet-properties.d.ts +10 -1
  176. package/dist/io/xlsx/sheet-properties.js +166 -37
  177. package/dist/io/xlsx/style-elements.d.ts +43 -0
  178. package/dist/io/xlsx/style-elements.js +156 -0
  179. package/dist/io/xlsx/styles.d.ts +12 -3
  180. package/dist/io/xlsx/styles.js +5 -204
  181. package/dist/io/xlsx/tables.js +11 -14
  182. package/dist/io/xlsx/theme-xml.d.ts +26 -4
  183. package/dist/io/xlsx/theme-xml.js +107 -69
  184. package/dist/io/xlsx/threaded-comments.d.ts +8 -10
  185. package/dist/io/xlsx/threaded-comments.js +3 -1
  186. package/dist/io/xlsx/workbook-xml.d.ts +54 -4
  187. package/dist/io/xlsx/workbook-xml.js +84 -57
  188. package/dist/io/xlsx/worksheet-xml.d.ts +23 -70
  189. package/dist/io/xlsx/worksheet-xml.js +59 -242
  190. package/dist/io/xlsx/write-stream.d.ts +71 -16
  191. package/dist/io/xlsx/write-stream.js +79 -41
  192. package/dist/io/xlsx/write.d.ts +6 -2
  193. package/dist/io/xlsx/write.js +217 -153
  194. package/dist/rel-type.d.ts +16 -0
  195. package/dist/rel-type.js +6 -0
  196. package/dist/token-set.d.ts +28 -0
  197. package/dist/token-set.js +7 -0
  198. package/dist/vba/bytes.d.ts +14 -5
  199. package/dist/vba/bytes.js +16 -6
  200. package/dist/vba/cfb-format.d.ts +32 -0
  201. package/dist/vba/cfb-format.js +13 -0
  202. package/dist/vba/cfb-writer.d.ts +9 -0
  203. package/dist/vba/cfb-writer.js +28 -25
  204. package/dist/vba/cfb.d.ts +13 -1
  205. package/dist/vba/cfb.js +73 -57
  206. package/dist/vba/codepage.js +2 -1
  207. package/dist/vba/errors.d.ts +7 -0
  208. package/dist/vba/ms-ovba.js +79 -23
  209. package/dist/vba/project-editor.js +35 -40
  210. package/dist/vba/project.d.ts +11 -1
  211. package/dist/vba/project.js +40 -21
  212. package/dist/vba/vba-encoding.js +5 -6
  213. package/dist/xml/xml-attrs.d.ts +37 -0
  214. package/dist/xml/xml-attrs.js +30 -0
  215. package/dist/xml/xml-chars.d.ts +40 -0
  216. package/dist/xml/xml-chars.js +12 -0
  217. package/dist/xml/xml-namespaces.d.ts +31 -0
  218. package/dist/xml/xml-namespaces.js +50 -0
  219. package/dist/xml/xml-read.d.ts +128 -81
  220. package/dist/xml/xml-read.js +161 -178
  221. package/dist/xml/xml-scan.d.ts +78 -0
  222. package/dist/xml/xml-scan.js +180 -0
  223. package/dist/xml/xml.d.ts +29 -28
  224. package/dist/xml/xml.js +24 -24
  225. package/package.json +13 -9
@@ -1,7 +1,10 @@
1
- import { isBorderStyle, isFillPatternType, isFontScheme, isFontVerticalAlignment, isHorizontalAlignment, isNamedUnderlineStyle, isVerticalAlignment, } from '../../core/style.js';
2
- import { boolPresent, boolStrict, closeEmptyElements, localName, numFinite, numInteger, openElements, xmlEvents, } from '../../xml/xml-read.js';
3
- import { numFmtCodeFor, resolveStyleTable, } from '../style/xf-style.js';
1
+ import { ALIGNMENT_FACETS, isBorderStyle, isFillPatternType, } from '../../core/style.js';
2
+ import { numFinite, numInteger } from '../../xml/xml-attrs.js';
3
+ import { closeEmptyElements, elementSubtrees, openElements, } from '../../xml/xml-read.js';
4
+ import { boolStrict, boolTristate, localName, xmlEvents, } from '../../xml/xml-scan.js';
5
+ import { NO_PRESERVED_STYLE_TABLES, numFmtCodeFor, protectionFrom, resolveStyleTable, } from '../style/xf-style.js';
4
6
  import { parseColor } from './color-xml.js';
7
+ import { applyFontChild } from './font-xml.js';
5
8
  const BORDER_EDGE_NAMES = ['left', 'right', 'top', 'bottom', 'diagonal'];
6
9
  const BORDER_EDGES = new Set(BORDER_EDGE_NAMES);
7
10
  const isBorderEdgeName = (name) => BORDER_EDGES.has(name);
@@ -15,7 +18,7 @@ const STYLE_EMPTY_CLOSES = new Set([
15
18
  ]);
16
19
  export function parseStyleTable(xml) {
17
20
  if (xml === '')
18
- return { cellXfs: [], namedStyles: [] };
21
+ return { cellXfs: [], namedStyles: [], preserved: NO_PRESERVED_STYLE_TABLES };
19
22
  let fills = [];
20
23
  let fonts = [];
21
24
  let borders = [];
@@ -54,7 +57,17 @@ export function parseStyleTable(xml) {
54
57
  }
55
58
  next = events.next();
56
59
  }
57
- return resolveStyleTable({ directXfs: xfStyles, namedXfs, labels: cellStyleNames, fonts });
60
+ const { fragments, attributes } = elementSubtrees(xml, PRESERVED_SUBTREES);
61
+ const preserved = {
62
+ dxfs: fragments.get('dxfs') ?? [],
63
+ indexedColors: fragments.get('indexedColors') ?? [],
64
+ mruColors: fragments.get('mruColors') ?? [],
65
+ tableStyles: buildTableStyleTable(xml, fragments.get('tableStyles') ?? [], attributes.get('tableStyles')),
66
+ };
67
+ return {
68
+ ...resolveStyleTable({ directXfs: xfStyles, namedXfs, labels: cellStyleNames, fonts }),
69
+ preserved,
70
+ };
58
71
  }
59
72
  function* until(events, container) {
60
73
  let next = events.next();
@@ -298,68 +311,6 @@ function parseCellStyles(events) {
298
311
  }
299
312
  return names;
300
313
  }
301
- export function applyFontChild(draft, local, attrs) {
302
- switch (local) {
303
- case 'b':
304
- draft.bold = boolPresent(attrs.val);
305
- break;
306
- case 'i':
307
- draft.italic = boolPresent(attrs.val);
308
- break;
309
- case 'strike':
310
- draft.strike = boolPresent(attrs.val);
311
- break;
312
- case 'outline':
313
- draft.outline = boolPresent(attrs.val);
314
- break;
315
- case 'u':
316
- draft.underline =
317
- attrs.val === undefined
318
- ? true
319
- : attrs.val === 'none'
320
- ? false
321
- : isNamedUnderlineStyle(attrs.val)
322
- ? attrs.val
323
- : true;
324
- break;
325
- case 'vertAlign':
326
- if (attrs.val !== undefined && isFontVerticalAlignment(attrs.val))
327
- draft.vertAlign = attrs.val;
328
- break;
329
- case 'sz': {
330
- const size = numFinite(attrs.val);
331
- if (size !== undefined)
332
- draft.size = size;
333
- break;
334
- }
335
- case 'color':
336
- draft.color = parseColor(attrs);
337
- break;
338
- case 'name':
339
- case 'rFont':
340
- if (attrs.val !== undefined)
341
- draft.name = attrs.val;
342
- break;
343
- case 'family': {
344
- const family = numInteger(attrs.val);
345
- if (family !== undefined)
346
- draft.family = family;
347
- break;
348
- }
349
- case 'charset': {
350
- const charset = numInteger(attrs.val);
351
- if (charset !== undefined)
352
- draft.charset = charset;
353
- break;
354
- }
355
- case 'scheme':
356
- if (attrs.val !== undefined && isFontScheme(attrs.val))
357
- draft.scheme = attrs.val;
358
- break;
359
- default:
360
- break;
361
- }
362
- }
363
314
  function resolveNumFmt(raw, custom) {
364
315
  const id = numInteger(raw, 1);
365
316
  return id === undefined ? undefined : numFmtCodeFor(id, custom);
@@ -389,53 +340,53 @@ function borderToStyle(draft) {
389
340
  }
390
341
  function parseAlignment(attrs) {
391
342
  const out = {};
392
- if (attrs.horizontal !== undefined &&
393
- attrs.horizontal !== 'general' &&
394
- isHorizontalAlignment(attrs.horizontal)) {
395
- out.horizontal = attrs.horizontal;
343
+ for (const facet of ALIGNMENT_FACETS) {
344
+ const raw = attrs[facet.key];
345
+ switch (facet.kind) {
346
+ case 'token':
347
+ if (raw !== undefined && raw !== facet.omit && facet.isValid(raw)) {
348
+ assignAlignmentToken(out, facet.key, raw);
349
+ }
350
+ break;
351
+ case 'number': {
352
+ const value = numFinite(raw);
353
+ if (value !== undefined && value !== 0)
354
+ out[facet.key] = value;
355
+ break;
356
+ }
357
+ case 'flag':
358
+ if (boolStrict(raw))
359
+ out[facet.key] = true;
360
+ break;
361
+ }
396
362
  }
397
- if (attrs.vertical !== undefined && isVerticalAlignment(attrs.vertical))
398
- out.vertical = attrs.vertical;
399
- const rotation = numFinite(attrs.textRotation);
400
- if (rotation !== undefined && rotation !== 0)
401
- out.textRotation = rotation;
402
- if (boolStrict(attrs.wrapText))
403
- out.wrapText = true;
404
- const indent = numInteger(attrs.indent);
405
- if (indent !== undefined && indent !== 0)
406
- out.indent = indent;
407
- if (boolStrict(attrs.shrinkToFit))
408
- out.shrinkToFit = true;
409
- const order = numInteger(attrs.readingOrder);
410
- if (order !== undefined && order !== 0)
411
- out.readingOrder = order;
412
363
  return Object.keys(out).length > 0 ? out : undefined;
413
364
  }
365
+ function assignAlignmentToken(out, key, raw) {
366
+ out[key] = raw;
367
+ }
414
368
  function parseProtection(attrs) {
415
- const out = {};
416
- if (attrs.locked === '0' || attrs.locked === 'false')
417
- out.locked = false;
418
- if (boolStrict(attrs.hidden))
419
- out.hidden = true;
420
- return Object.keys(out).length > 0 ? out : undefined;
369
+ return protectionFrom({ locked: boolTristate(attrs.locked), hidden: boolStrict(attrs.hidden) });
421
370
  }
422
371
  export function parseIndexedColors(stylesXml) {
423
- return elementFragments(stylesXml, 'indexedColors', 'rgbColor');
372
+ return capturedFragments(stylesXml, 'indexedColors');
424
373
  }
425
374
  export function parseMruColors(stylesXml) {
426
- return elementFragments(stylesXml, 'mruColors', 'color');
375
+ return capturedFragments(stylesXml, 'mruColors');
427
376
  }
428
377
  export function parseTableStyles(stylesXml) {
429
- const styles = elementFragments(stylesXml, 'tableStyles', 'tableStyle');
430
- const table = { styles };
431
- for (const { attrs } of openElements(stylesXml, 'tableStyles')) {
432
- if (attrs.defaultTableStyle !== undefined)
433
- table.defaultTableStyle = attrs.defaultTableStyle;
434
- if (attrs.defaultPivotStyle !== undefined)
435
- table.defaultPivotStyle = attrs.defaultPivotStyle;
436
- break;
378
+ const { fragments, attributes } = elementSubtrees(stylesXml, new Map([['tableStyles', 'tableStyle']]));
379
+ return buildTableStyleTable(stylesXml, fragments.get('tableStyles') ?? [], attributes.get('tableStyles'));
380
+ }
381
+ function buildTableStyleTable(stylesXml, styles, containerAttrs) {
382
+ const table = { styles: [...styles] };
383
+ if (containerAttrs?.defaultTableStyle !== undefined) {
384
+ table.defaultTableStyle = containerAttrs.defaultTableStyle;
437
385
  }
438
- const namespaces = fragmentNamespaces(stylesXml, styles);
386
+ if (containerAttrs?.defaultPivotStyle !== undefined) {
387
+ table.defaultPivotStyle = containerAttrs.defaultPivotStyle;
388
+ }
389
+ const namespaces = fragmentNamespaces(stylesXml, table.styles);
439
390
  if (namespaces.length > 0)
440
391
  table.namespaces = namespaces;
441
392
  return table;
@@ -470,11 +421,16 @@ function fragmentNamespaces(stylesXml, fragments) {
470
421
  ignorable: ignorable.has(prefix),
471
422
  }));
472
423
  }
473
- function elementFragments(xml, container, child) {
474
- const block = new RegExp(`<${container}\\b[^>]*>([\\s\\S]*?)</${container}>`).exec(xml);
475
- if (block === null)
424
+ const PRESERVED_SUBTREES = new Map([
425
+ ['dxfs', 'dxf'],
426
+ ['indexedColors', 'rgbColor'],
427
+ ['mruColors', 'color'],
428
+ ['tableStyles', 'tableStyle'],
429
+ ]);
430
+ function capturedFragments(xml, container) {
431
+ const child = PRESERVED_SUBTREES.get(container);
432
+ if (child === undefined)
476
433
  return [];
477
- const inner = block[1] ?? '';
478
- const pattern = new RegExp(`<${child}\\b[^>]*/>|<${child}\\b[^>]*>[\\s\\S]*?</${child}>`, 'g');
479
- return [...inner.matchAll(pattern)].map((m) => m[0] ?? '');
434
+ const { fragments } = elementSubtrees(xml, new Map([[container, child]]));
435
+ return [...(fragments.get(container) ?? [])];
480
436
  }
@@ -0,0 +1,36 @@
1
+ import { type WorkbookProtection } from '../../core/workbook-protection.ts';
2
+ import type { DefinedName, Workbook, WorkbookView } from '../../core/workbook.ts';
3
+ import { type WorksheetState } from '../../core/worksheet.ts';
4
+ import { type CollectingPass, type SaxPass } from '../../xml/xml-read.ts';
5
+ export interface SheetEntry {
6
+ readonly name: string;
7
+ readonly relId: string;
8
+ readonly state?: WorksheetState['state'];
9
+ }
10
+ export declare function workbookSheetsPass(): CollectingPass<SheetEntry[]>;
11
+ export declare function workbookProtectionPass(): CollectingPass<WorkbookProtection | undefined>;
12
+ /**
13
+ * Apply `<workbookPr>`: the workbook's date system and its VBA code name.
14
+ *
15
+ * Both are read for the same reason and it is not that the model computes anything from them. The
16
+ * date system is what every serial in every sheet counts from, so a workbook read without it is read
17
+ * with every date four years and a day out; the code name is what the VBA project means by
18
+ * `ThisWorkbook`, so a `.xlsm` written back without it has had its macros unbound from its document.
19
+ * Neither has any signal in the file other than this element.
20
+ */
21
+ export declare function workbookPropertiesPass(workbook: Workbook): SaxPass;
22
+ export declare function workbookViewPass(view: WorkbookView): SaxPass;
23
+ export interface DefinedNamesPass extends SaxPass {
24
+ /**
25
+ * The names, scoped against the sheet order.
26
+ *
27
+ * The order is supplied here rather than to the pass, and that is what lets the names ride the same
28
+ * scan as everything else this part carries. A scoped name's `localSheetId` indexes the sheets in
29
+ * declaration order, and the model's answer for index n is known only after the sheet loop has run
30
+ * and repaired the names it had to; resolving during the scan would have forced a second one.
31
+ */
32
+ result(sheetOrder: readonly string[]): DefinedName[];
33
+ }
34
+ export declare function definedNamesPass(): DefinedNamesPass;
35
+ export declare function applyCoreProperties(workbook: Workbook, xml: string): void;
36
+ export declare function applyAppProperties(workbook: Workbook, xml: string): void;
@@ -0,0 +1,170 @@
1
+ import { parseDateText } from '../../core/date.js';
2
+ import { unmangleFunctions } from '../../core/formula.js';
3
+ import { WORKBOOK_PROTECTION_CREDENTIAL_ATTRS, } from '../../core/workbook-protection.js';
4
+ import { isVisibility } from '../../core/worksheet.js';
5
+ import { enumToken, numInteger } from '../../xml/xml-attrs.js';
6
+ import { capturedText, TextCapture } from '../../xml/xml-read.js';
7
+ import { boolStrict, localName } from '../../xml/xml-scan.js';
8
+ import { relAttr } from '../opc/namespaces.js';
9
+ export function workbookSheetsPass() {
10
+ const sheets = [];
11
+ return {
12
+ handlers: {
13
+ onOpen(name, attrs, _selfClosing, scope) {
14
+ if (localName(name) !== 'sheet')
15
+ return;
16
+ const entry = {
17
+ name: attrs.name ?? '',
18
+ relId: relAttr(scope, attrs, 'id') ?? '',
19
+ };
20
+ const state = enumToken(attrs.state, isVisibility);
21
+ if (state !== undefined && state !== 'visible')
22
+ entry.state = state;
23
+ sheets.push(entry);
24
+ },
25
+ },
26
+ result: () => sheets,
27
+ };
28
+ }
29
+ export function workbookProtectionPass() {
30
+ let found;
31
+ const handlers = {
32
+ onOpen(name, attrs) {
33
+ if (localName(name) !== 'workbookProtection')
34
+ return;
35
+ const protection = {};
36
+ if (boolStrict(attrs.lockStructure))
37
+ protection.lockStructure = true;
38
+ if (boolStrict(attrs.lockWindows))
39
+ protection.lockWindows = true;
40
+ if (boolStrict(attrs.lockRevision))
41
+ protection.lockRevision = true;
42
+ const credentials = {};
43
+ for (const key of WORKBOOK_PROTECTION_CREDENTIAL_ATTRS) {
44
+ const value = attrs[key];
45
+ if (value !== undefined)
46
+ credentials[key] = value;
47
+ }
48
+ if (Object.keys(credentials).length > 0)
49
+ protection.credentials = credentials;
50
+ found = protection;
51
+ },
52
+ };
53
+ return { handlers, result: () => found };
54
+ }
55
+ export function workbookPropertiesPass(workbook) {
56
+ let seen = false;
57
+ return {
58
+ handlers: {
59
+ onOpen(name, attrs) {
60
+ if (seen || localName(name) !== 'workbookPr')
61
+ return;
62
+ seen = true;
63
+ if (boolStrict(attrs.date1904))
64
+ workbook.dateEpoch = 1904;
65
+ if (attrs.codeName !== undefined)
66
+ workbook.codeName = attrs.codeName;
67
+ },
68
+ },
69
+ };
70
+ }
71
+ export function workbookViewPass(view) {
72
+ let seen = false;
73
+ return {
74
+ handlers: {
75
+ onOpen(name, attrs) {
76
+ if (seen || localName(name) !== 'workbookView')
77
+ return;
78
+ seen = true;
79
+ const x = numInteger(attrs.xWindow);
80
+ if (x !== undefined)
81
+ view.x = x;
82
+ const y = numInteger(attrs.yWindow);
83
+ if (y !== undefined)
84
+ view.y = y;
85
+ const width = numInteger(attrs.windowWidth, 0);
86
+ if (width !== undefined)
87
+ view.width = width;
88
+ const height = numInteger(attrs.windowHeight, 0);
89
+ if (height !== undefined)
90
+ view.height = height;
91
+ const activeTab = numInteger(attrs.activeTab, 0);
92
+ if (activeTab !== undefined)
93
+ view.activeTab = activeTab;
94
+ const visibility = enumToken(attrs.visibility, isVisibility);
95
+ if (visibility !== undefined && visibility !== 'visible')
96
+ view.visibility = visibility;
97
+ if (boolStrict(attrs.minimized))
98
+ view.minimized = true;
99
+ },
100
+ },
101
+ };
102
+ }
103
+ export function definedNamesPass() {
104
+ const drafts = [];
105
+ const refersTo = new TextCapture('definedName');
106
+ let pending;
107
+ return {
108
+ handlers: {
109
+ onOpen(name, attrs, selfClosing) {
110
+ if (localName(name) !== 'definedName' || attrs.name === undefined)
111
+ return;
112
+ if (attrs.name === '_xlnm._FilterDatabase')
113
+ return;
114
+ refersTo.open(localName(name), selfClosing);
115
+ pending = { name: attrs.name, localSheetId: numInteger(attrs.localSheetId, 0) ?? -1 };
116
+ if (attrs.comment !== undefined)
117
+ pending.comment = attrs.comment;
118
+ if (boolStrict(attrs.hidden))
119
+ pending.hidden = true;
120
+ },
121
+ onText(chunk) {
122
+ refersTo.text(chunk);
123
+ },
124
+ onClose(name) {
125
+ const text = refersTo.close(localName(name));
126
+ if (text === undefined || pending === undefined)
127
+ return;
128
+ drafts.push({ ...pending, refersTo: unmangleFunctions(text) });
129
+ pending = undefined;
130
+ },
131
+ },
132
+ closeEmptyElements: new Set(['definedName']),
133
+ result(sheetOrder) {
134
+ return drafts.map(({ localSheetId, ...draft }) => {
135
+ const scope = sheetOrder[localSheetId];
136
+ return scope === undefined ? draft : { ...draft, scope };
137
+ });
138
+ },
139
+ };
140
+ }
141
+ const CORE_PROPERTY_LOCAL_NAMES = new Set([
142
+ 'title',
143
+ 'creator',
144
+ 'lastModifiedBy',
145
+ 'created',
146
+ 'modified',
147
+ ]);
148
+ export function applyCoreProperties(workbook, xml) {
149
+ for (const { local, text } of capturedText(xml, CORE_PROPERTY_LOCAL_NAMES)) {
150
+ if (local === 'title')
151
+ workbook.properties.title = text;
152
+ else if (local === 'creator')
153
+ workbook.properties.creator = text;
154
+ else if (local === 'lastModifiedBy')
155
+ workbook.properties.lastModifiedBy = text;
156
+ else {
157
+ const date = parseDateText(text);
158
+ if (date !== null) {
159
+ if (local === 'created')
160
+ workbook.properties.created = date;
161
+ else
162
+ workbook.properties.modified = date;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ export function applyAppProperties(workbook, xml) {
168
+ for (const { text } of capturedText(xml, 'Company'))
169
+ workbook.properties.company = text;
170
+ }
@@ -1,4 +1,14 @@
1
+ import type { DateEpoch } from '../../core/date.ts';
1
2
  import type { Worksheet } from '../../core/worksheet.ts';
3
+ import { type SaxPass } from '../../xml/xml-read.ts';
2
4
  import type { XfStyle } from '../style/xf-style.ts';
3
5
  import type { SharedString } from './cell-value.ts';
4
- export declare function parseWorksheet(xml: string, sheet: Worksheet, sharedStrings: readonly SharedString[], xfStyles: ReadonlyArray<XfStyle>): void;
6
+ /**
7
+ * A pass reading a worksheet part into `sheet`: cells and their styles, the column and row metadata,
8
+ * merges, the autofilter, page breaks, and the view and print layout. It commits as it goes rather
9
+ * than gathering, so it has nothing to hand back once the parse ends.
10
+ *
11
+ * Offered as a pass because the worksheet is the largest part in a package and four other readers
12
+ * want the same events, so the five share one parse of it rather than scanning it once each.
13
+ */
14
+ export declare function worksheetPass(sheet: Worksheet, sharedStrings: readonly SharedString[], xfStyles: ReadonlyArray<XfStyle>, dateEpoch: DateEpoch): SaxPass;