@shbernal/ts-xlsx 3.0.0 → 3.2.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 (277) hide show
  1. package/README.md +34 -24
  2. package/dist/bytes.d.ts +10 -2
  3. package/dist/bytes.js +22 -0
  4. package/dist/core/address.d.ts +96 -2
  5. package/dist/core/address.js +87 -33
  6. package/dist/core/array-formula-ranges.d.ts +33 -0
  7. package/dist/core/array-formula-ranges.js +62 -0
  8. package/dist/core/autofilter.d.ts +4 -3
  9. package/dist/core/autofilter.js +31 -30
  10. package/dist/core/axis-handle.d.ts +2 -0
  11. package/dist/core/axis-handle.js +5 -2
  12. package/dist/core/cell.d.ts +4 -3
  13. package/dist/core/cell.js +4 -6
  14. package/dist/core/clone.d.ts +29 -0
  15. package/dist/core/clone.js +24 -0
  16. package/dist/core/color-resolution.js +4 -6
  17. package/dist/core/column.d.ts +1 -0
  18. package/dist/core/column.js +6 -2
  19. package/dist/core/comment-thread.d.ts +7 -3
  20. package/dist/core/comment-thread.js +2 -1
  21. package/dist/core/conditional-formatting-overlay.d.ts +11 -1
  22. package/dist/core/conditional-formatting-overlay.js +30 -3
  23. package/dist/core/conditional-formatting.d.ts +107 -11
  24. package/dist/core/conditional-formatting.js +76 -19
  25. package/dist/core/containers.d.ts +12 -0
  26. package/dist/core/containers.js +5 -0
  27. package/dist/core/data-validation-overlay.d.ts +7 -1
  28. package/dist/core/data-validation-overlay.js +19 -4
  29. package/dist/core/data-validation.d.ts +22 -0
  30. package/dist/core/data-validation.js +30 -4
  31. package/dist/core/date-format.d.ts +20 -0
  32. package/dist/core/date-format.js +170 -0
  33. package/dist/core/date.d.ts +43 -8
  34. package/dist/core/date.js +19 -3
  35. package/dist/core/formula-references.d.ts +26 -0
  36. package/dist/core/formula-references.js +173 -0
  37. package/dist/core/formula-scan.d.ts +2 -0
  38. package/dist/core/formula-scan.js +58 -0
  39. package/dist/core/formula.d.ts +76 -17
  40. package/dist/core/formula.js +87 -80
  41. package/dist/core/function-values.d.ts +4 -0
  42. package/dist/core/function-values.js +58 -0
  43. package/dist/core/future-functions.d.ts +3 -0
  44. package/dist/core/{modern-functions.js → future-functions.js} +119 -88
  45. package/dist/core/grid-edits.d.ts +30 -3
  46. package/dist/core/grid-edits.js +248 -81
  47. package/dist/core/grid-shift.d.ts +58 -9
  48. package/dist/core/grid-shift.js +26 -4
  49. package/dist/core/hyperlink.d.ts +39 -0
  50. package/dist/core/hyperlink.js +88 -0
  51. package/dist/core/image.d.ts +49 -14
  52. package/dist/core/image.js +16 -5
  53. package/dist/core/internal.d.ts +10 -2
  54. package/dist/core/limits.d.ts +25 -0
  55. package/dist/core/limits.js +4 -0
  56. package/dist/core/merge.d.ts +18 -4
  57. package/dist/core/merge.js +33 -20
  58. package/dist/core/page-setup.d.ts +26 -11
  59. package/dist/core/pivot-table.d.ts +49 -10
  60. package/dist/core/pivot-table.js +112 -60
  61. package/dist/core/protection.d.ts +66 -4
  62. package/dist/core/protection.js +6 -11
  63. package/dist/core/range.js +34 -30
  64. package/dist/core/row-input.js +2 -2
  65. package/dist/core/row.d.ts +1 -0
  66. package/dist/core/row.js +6 -2
  67. package/dist/core/structured-reference.d.ts +7 -0
  68. package/dist/core/structured-reference.js +7 -0
  69. package/dist/core/style.d.ts +85 -70
  70. package/dist/core/style.js +92 -28
  71. package/dist/core/table-style.d.ts +1 -1
  72. package/dist/core/table-style.js +4 -4
  73. package/dist/core/table.d.ts +64 -16
  74. package/dist/core/table.js +87 -40
  75. package/dist/core/theme.d.ts +2 -0
  76. package/dist/core/theme.js +9 -5
  77. package/dist/core/value.d.ts +60 -28
  78. package/dist/core/value.js +48 -43
  79. package/dist/core/workbook-media.d.ts +34 -0
  80. package/dist/core/workbook-media.js +44 -0
  81. package/dist/core/workbook-styles.d.ts +83 -1
  82. package/dist/core/workbook-styles.js +4 -0
  83. package/dist/core/workbook-theme.js +5 -3
  84. package/dist/core/workbook-vba.js +3 -2
  85. package/dist/core/workbook.d.ts +41 -3
  86. package/dist/core/workbook.js +46 -41
  87. package/dist/core/worksheet-comments.d.ts +2 -1
  88. package/dist/core/worksheet-comments.js +20 -13
  89. package/dist/core/worksheet-merges.d.ts +49 -0
  90. package/dist/core/worksheet-merges.js +65 -0
  91. package/dist/core/worksheet-model.d.ts +10 -2
  92. package/dist/core/worksheet-model.js +28 -9
  93. package/dist/core/worksheet-pictures.d.ts +3 -3
  94. package/dist/core/worksheet-pictures.js +7 -6
  95. package/dist/core/worksheet.d.ts +165 -27
  96. package/dist/core/worksheet.js +206 -89
  97. package/dist/customui/ribbon.js +2 -1
  98. package/dist/entries/core.d.ts +21 -14
  99. package/dist/entries/core.js +14 -7
  100. package/dist/entries/errors.d.ts +1 -0
  101. package/dist/entries/errors.js +1 -0
  102. package/dist/entries/xlsx.d.ts +1 -1
  103. package/dist/errors.d.ts +64 -0
  104. package/dist/errors.js +22 -0
  105. package/dist/hex.d.ts +8 -0
  106. package/dist/hex.js +3 -0
  107. package/dist/io/cell-metadata/metadata.d.ts +42 -0
  108. package/dist/io/cell-metadata/metadata.js +35 -0
  109. package/dist/io/cell-metadata/rich-values.d.ts +11 -0
  110. package/dist/io/cell-metadata/rich-values.js +80 -0
  111. package/dist/io/csv/delimiter.d.ts +21 -0
  112. package/dist/io/csv/delimiter.js +18 -0
  113. package/dist/io/csv/errors.d.ts +14 -0
  114. package/dist/io/csv/errors.js +5 -0
  115. package/dist/io/csv/read.d.ts +6 -1
  116. package/dist/io/csv/read.js +51 -22
  117. package/dist/io/csv/write.d.ts +19 -5
  118. package/dist/io/csv/write.js +24 -44
  119. package/dist/io/opc/inflate.js +14 -0
  120. package/dist/io/opc/namespaces.d.ts +16 -0
  121. package/dist/io/opc/namespaces.js +4 -0
  122. package/dist/io/opc/part-paths.d.ts +9 -0
  123. package/dist/io/opc/part-paths.js +5 -5
  124. package/dist/io/opc/read-opc.d.ts +58 -14
  125. package/dist/io/opc/read-opc.js +49 -21
  126. package/dist/io/opc/read-options.d.ts +5 -1
  127. package/dist/io/opc/sniff-format.d.ts +3 -3
  128. package/dist/io/opc/sniff-format.js +2 -2
  129. package/dist/io/opc/strict-relationships.d.ts +2 -0
  130. package/dist/io/opc/strict-relationships.js +12 -0
  131. package/dist/io/read-policy/column-budget.d.ts +26 -0
  132. package/dist/io/read-policy/column-budget.js +18 -0
  133. package/dist/io/read-policy/read-repair.d.ts +74 -0
  134. package/dist/io/read-policy/read-repair.js +119 -0
  135. package/dist/io/style/cell-style-resolution.d.ts +25 -0
  136. package/dist/io/style/cell-style-resolution.js +30 -0
  137. package/dist/io/style/xf-style.d.ts +23 -1
  138. package/dist/io/style/xf-style.js +8 -0
  139. package/dist/io/xlsb/formula.d.ts +2 -2
  140. package/dist/io/xlsb/formula.js +52 -35
  141. package/dist/io/xlsb/primitives.js +8 -14
  142. package/dist/io/xlsb/ptg-functions.d.ts +19 -10
  143. package/dist/io/xlsb/ptg-functions.js +495 -596
  144. package/dist/io/xlsb/read-metadata.d.ts +7 -0
  145. package/dist/io/xlsb/read-metadata.js +69 -0
  146. package/dist/io/xlsb/read-styles.js +45 -81
  147. package/dist/io/xlsb/read-worksheet.d.ts +26 -1
  148. package/dist/io/xlsb/read-worksheet.js +148 -106
  149. package/dist/io/xlsb/read.d.ts +6 -3
  150. package/dist/io/xlsb/read.js +70 -31
  151. package/dist/io/xlsb/record-stream.d.ts +30 -0
  152. package/dist/io/xlsb/record-stream.js +20 -0
  153. package/dist/io/xlsb/record-types.d.ts +14 -5
  154. package/dist/io/xlsb/record-types.js +14 -5
  155. package/dist/io/xlsb/sheet-protection.d.ts +20 -0
  156. package/dist/io/xlsb/sheet-protection.js +60 -0
  157. package/dist/io/xlsx/cell-accumulator.d.ts +24 -9
  158. package/dist/io/xlsx/cell-accumulator.js +74 -21
  159. package/dist/io/xlsx/cell-metadata.d.ts +39 -0
  160. package/dist/io/xlsx/cell-metadata.js +162 -0
  161. package/dist/io/xlsx/cell-value.d.ts +19 -5
  162. package/dist/io/xlsx/cell-value.js +45 -30
  163. package/dist/io/xlsx/color-xml.js +3 -2
  164. package/dist/io/xlsx/column-span.d.ts +11 -0
  165. package/dist/io/xlsx/column-span.js +9 -0
  166. package/dist/io/xlsx/comments.d.ts +9 -30
  167. package/dist/io/xlsx/comments.js +25 -83
  168. package/dist/io/xlsx/conditional-formatting.d.ts +43 -23
  169. package/dist/io/xlsx/conditional-formatting.js +437 -138
  170. package/dist/io/xlsx/data-validation.d.ts +12 -7
  171. package/dist/io/xlsx/data-validation.js +67 -53
  172. package/dist/io/xlsx/edit-vba.d.ts +7 -2
  173. package/dist/io/xlsx/edit-vba.js +52 -52
  174. package/dist/io/xlsx/font-xml.d.ts +7 -0
  175. package/dist/io/xlsx/font-xml.js +104 -0
  176. package/dist/io/xlsx/hyperlinks.d.ts +19 -21
  177. package/dist/io/xlsx/hyperlinks.js +12 -32
  178. package/dist/io/xlsx/images.d.ts +49 -16
  179. package/dist/io/xlsx/images.js +149 -50
  180. package/dist/io/xlsx/namespaces.d.ts +24 -0
  181. package/dist/io/xlsx/namespaces.js +11 -0
  182. package/dist/io/xlsx/package-plan.d.ts +60 -15
  183. package/dist/io/xlsx/package-plan.js +83 -18
  184. package/dist/io/xlsx/part-names.d.ts +6 -8
  185. package/dist/io/xlsx/part-names.js +3 -7
  186. package/dist/io/xlsx/pivot.d.ts +5 -5
  187. package/dist/io/xlsx/pivot.js +26 -24
  188. package/dist/io/xlsx/preserved-splices.d.ts +6 -0
  189. package/dist/io/xlsx/preserved-splices.js +74 -0
  190. package/dist/io/xlsx/read-comments.d.ts +29 -0
  191. package/dist/io/xlsx/read-comments.js +75 -0
  192. package/dist/io/xlsx/read-parts.d.ts +59 -0
  193. package/dist/io/xlsx/read-parts.js +259 -0
  194. package/dist/io/xlsx/read-pivot.js +11 -4
  195. package/dist/io/xlsx/{rich-runs.d.ts → read-rich-runs.d.ts} +8 -5
  196. package/dist/io/xlsx/{rich-runs.js → read-rich-runs.js} +24 -4
  197. package/dist/io/xlsx/read-rows.d.ts +35 -11
  198. package/dist/io/xlsx/read-rows.js +73 -49
  199. package/dist/io/xlsx/read-shared-strings.js +3 -2
  200. package/dist/io/xlsx/read-styles.d.ts +0 -30
  201. package/dist/io/xlsx/read-styles.js +45 -105
  202. package/dist/io/xlsx/read-workbook-xml.d.ts +42 -0
  203. package/dist/io/xlsx/read-workbook-xml.js +175 -0
  204. package/dist/io/xlsx/read-worksheet.d.ts +9 -3
  205. package/dist/io/xlsx/read-worksheet.js +70 -177
  206. package/dist/io/xlsx/read.d.ts +3 -14
  207. package/dist/io/xlsx/read.js +74 -411
  208. package/dist/io/xlsx/relationships.d.ts +3 -0
  209. package/dist/io/xlsx/relationships.js +4 -0
  210. package/dist/io/xlsx/rich-text.js +1 -1
  211. package/dist/io/xlsx/row-position.d.ts +20 -0
  212. package/dist/io/xlsx/row-position.js +11 -0
  213. package/dist/io/xlsx/row-xml.d.ts +139 -0
  214. package/dist/io/xlsx/row-xml.js +222 -0
  215. package/dist/io/xlsx/shared-formulas.js +2 -2
  216. package/dist/io/xlsx/sheet-properties.d.ts +10 -1
  217. package/dist/io/xlsx/sheet-properties.js +182 -20
  218. package/dist/io/xlsx/strict-parts.d.ts +7 -0
  219. package/dist/io/xlsx/strict-parts.js +171 -0
  220. package/dist/io/xlsx/style-elements.d.ts +41 -0
  221. package/dist/io/xlsx/style-elements.js +136 -0
  222. package/dist/io/xlsx/styles.d.ts +17 -3
  223. package/dist/io/xlsx/styles.js +13 -209
  224. package/dist/io/xlsx/tables.d.ts +10 -2
  225. package/dist/io/xlsx/tables.js +55 -52
  226. package/dist/io/xlsx/theme-xml.d.ts +32 -4
  227. package/dist/io/xlsx/theme-xml.js +106 -71
  228. package/dist/io/xlsx/threaded-comments.d.ts +14 -11
  229. package/dist/io/xlsx/threaded-comments.js +16 -8
  230. package/dist/io/xlsx/workbook-xml.d.ts +45 -6
  231. package/dist/io/xlsx/workbook-xml.js +62 -54
  232. package/dist/io/xlsx/worksheet-xml.d.ts +26 -70
  233. package/dist/io/xlsx/worksheet-xml.js +69 -282
  234. package/dist/io/xlsx/write-stream.d.ts +90 -19
  235. package/dist/io/xlsx/write-stream.js +80 -25
  236. package/dist/io/xlsx/write.d.ts +12 -6
  237. package/dist/io/xlsx/write.js +226 -123
  238. package/dist/rel-type.d.ts +25 -0
  239. package/dist/rel-type.js +9 -0
  240. package/dist/token-set.d.ts +13 -0
  241. package/dist/token-set.js +4 -1
  242. package/dist/vba/bytes.d.ts +16 -5
  243. package/dist/vba/bytes.js +27 -6
  244. package/dist/vba/cfb-format.d.ts +55 -0
  245. package/dist/vba/cfb-format.js +35 -0
  246. package/dist/vba/cfb-writer.d.ts +8 -0
  247. package/dist/vba/cfb-writer.js +40 -40
  248. package/dist/vba/cfb.d.ts +21 -4
  249. package/dist/vba/cfb.js +124 -90
  250. package/dist/vba/codepage.js +2 -1
  251. package/dist/vba/dir-records.d.ts +6 -0
  252. package/dist/vba/dir-records.js +10 -2
  253. package/dist/vba/errors.d.ts +11 -4
  254. package/dist/vba/index.d.ts +0 -2
  255. package/dist/vba/index.js +0 -2
  256. package/dist/vba/ms-ovba.d.ts +6 -2
  257. package/dist/vba/ms-ovba.js +66 -22
  258. package/dist/vba/project-editor.js +129 -119
  259. package/dist/vba/project.d.ts +15 -1
  260. package/dist/vba/project.js +38 -13
  261. package/dist/vba/vba-encoding.d.ts +4 -10
  262. package/dist/vba/vba-encoding.js +3 -17
  263. package/dist/xml/xml-attrs.d.ts +37 -0
  264. package/dist/xml/xml-attrs.js +30 -0
  265. package/dist/xml/xml-chars.d.ts +40 -0
  266. package/dist/xml/xml-chars.js +12 -0
  267. package/dist/xml/xml-namespaces.d.ts +31 -0
  268. package/dist/xml/xml-namespaces.js +50 -0
  269. package/dist/xml/xml-read.d.ts +101 -11
  270. package/dist/xml/xml-read.js +150 -18
  271. package/dist/xml/xml-scan.d.ts +25 -34
  272. package/dist/xml/xml-scan.js +69 -46
  273. package/dist/xml/xml.d.ts +59 -26
  274. package/dist/xml/xml.js +45 -23
  275. package/package.json +15 -9
  276. package/skills/ts-xlsx-upstream/SKILL.md +21 -13
  277. package/dist/core/modern-functions.d.ts +0 -1
@@ -1,12 +1,39 @@
1
- import { AuthoringError } from '../../errors.js';
1
+ import { INTERNAL } from '../../core/internal.js';
2
+ import { AuthoringError, InternalError, quoted } from '../../errors.js';
2
3
  import { extensionOf, relativePartPath, relsPathFor, THEME_PART_PATH } from '../opc/part-paths.js';
3
4
  import { relsPartXml } from '../opc/rels.js';
4
- import { drawingPart, mediaPart, vmlDrawingPart } from './part-names.js';
5
+ import { mergePictures } from './images.js';
6
+ import { drawingPart, mediaPart, pivotCacheDefinitionPart, pivotCacheRecordsPart, pivotTablePart, vmlDrawingPart, } from './part-names.js';
7
+ import { splicePreservedPart } from './preserved-splices.js';
5
8
  import { applyThemeOverrides } from './theme-xml.js';
6
- export class SheetRelIds {
9
+ export class RelationshipLedger {
10
+ #owner;
11
+ #taken;
12
+ #relationships = [];
7
13
  #next = 1;
8
- next() {
9
- return `rId${this.#next++}`;
14
+ constructor(owner, taken = new Set()) {
15
+ this.#owner = owner;
16
+ this.#taken = taken;
17
+ }
18
+ add(type, partPath) {
19
+ return this.#record({ type, target: relativePartPath(this.#owner, partPath) });
20
+ }
21
+ addExternal(type, url) {
22
+ return this.#record({ type, target: url, external: true });
23
+ }
24
+ addInDocument(type, location) {
25
+ return this.#record({ type, target: location });
26
+ }
27
+ get relationships() {
28
+ return this.#relationships;
29
+ }
30
+ #record(relationship) {
31
+ while (this.#taken.has(`rId${this.#next}`))
32
+ this.#next += 1;
33
+ const id = `rId${this.#next}`;
34
+ this.#next += 1;
35
+ this.#relationships.push({ id, ...relationship });
36
+ return id;
10
37
  }
11
38
  }
12
39
  export function planMedia(workbook, sheets) {
@@ -32,7 +59,7 @@ export function planMedia(workbook, sheets) {
32
59
  const image = workbook.getImage(id);
33
60
  if (image === undefined) {
34
61
  const reference = role === 'anchor' ? `anchors image id ${id}` : `sets background image id ${id}`;
35
- throw new AuthoringError(`sheet "${sheetName}" ${reference}, which is not registered on the workbook`);
62
+ throw new AuthoringError(`sheet ${quoted(sheetName)} ${reference}, which is not registered on the workbook`);
36
63
  }
37
64
  const number = i + 1;
38
65
  parts.push({ number, extension: image.extension, data: image.data });
@@ -51,12 +78,15 @@ export function planMedia(workbook, sheets) {
51
78
  },
52
79
  };
53
80
  }
54
- export function planPreservedParts(workbook, generatedDrawingCount, generatedMediaCount) {
81
+ export function planPreservedParts(workbook, generatedDrawingCount, generatedMediaCount, generatedPivotCount, pictures) {
55
82
  const sheets = workbook.worksheets;
56
83
  const numbering = {
57
84
  drawing: generatedDrawingCount,
58
85
  vml: sheets.length,
59
86
  media: generatedMediaCount,
87
+ pivotTable: generatedPivotCount,
88
+ pivotCacheDefinition: generatedPivotCount,
89
+ pivotCacheRecords: generatedPivotCount,
60
90
  };
61
91
  const remap = new Map();
62
92
  const theme = workbook.themePart;
@@ -75,9 +105,10 @@ export function planPreservedParts(workbook, generatedDrawingCount, generatedMed
75
105
  }
76
106
  }
77
107
  const emitted = new Map();
108
+ const splices = workbook[INTERNAL].splices();
78
109
  for (const reference of allReferences) {
79
110
  for (const part of reference.parts) {
80
- const newPath = remap.get(part.path);
111
+ const newPath = resolveRemapped(remap, part.path);
81
112
  if (emitted.has(newPath))
82
113
  continue;
83
114
  const rels = part.rels.flatMap((rel) => {
@@ -90,31 +121,40 @@ export function planPreservedParts(workbook, generatedDrawingCount, generatedMed
90
121
  : [{ id: rel.id, type: rel.type, target: relativePartPath(newPath, target) }];
91
122
  });
92
123
  const overrides = newPath === THEME_PART_PATH ? workbook.themeOverrides : undefined;
124
+ let bytes = overrides === undefined
125
+ ? splicePreservedPart(part.bytes, part.contentType, splices)
126
+ : new TextEncoder().encode(applyThemeOverrides(new TextDecoder().decode(part.bytes), overrides));
127
+ let relationships = rels;
128
+ const joining = pictures.get(part.path);
129
+ if (joining !== undefined) {
130
+ const ledger = new RelationshipLedger(newPath, new Set(rels.map((rel) => rel.id)));
131
+ const images = joining(ledger);
132
+ bytes = new TextEncoder().encode(mergePictures(new TextDecoder().decode(bytes), images));
133
+ relationships = [...rels, ...ledger.relationships];
134
+ }
93
135
  emitted.set(newPath, {
94
136
  path: newPath,
95
- bytes: overrides === undefined
96
- ? part.bytes
97
- : new TextEncoder().encode(applyThemeOverrides(new TextDecoder().decode(part.bytes), overrides)),
137
+ bytes,
98
138
  contentType: part.contentType,
99
- relsPath: rels.length === 0 ? null : relsPathFor(newPath),
100
- relsXml: rels.length === 0 ? null : relsPartXml(rels),
139
+ relsPath: relationships.length === 0 ? null : relsPathFor(newPath),
140
+ relsXml: relationships.length === 0 ? null : relsPartXml(relationships),
101
141
  });
102
142
  }
103
143
  }
104
144
  const perSheet = sheets.map((sheet) => sheet.preservedReferences.map((reference) => ({
105
145
  element: reference.element,
106
146
  relType: reference.relType,
107
- entryPath: remap.get(reference.entryPath),
147
+ entryPath: resolveRemapped(remap, reference.entryPath),
108
148
  })));
109
149
  const workbookRefs = workbook.preservedReferences.map((reference) => ({
110
150
  relType: reference.relType,
111
- entryPath: remap.get(reference.entryPath),
151
+ entryPath: resolveRemapped(remap, reference.entryPath),
112
152
  pivotCacheId: reference.pivotCacheId,
113
153
  externalReferenceIndex: reference.externalReferenceIndex,
114
154
  }));
115
155
  const rootRefs = workbook.preservedRootReferences.map((reference) => ({
116
156
  relType: reference.relType,
117
- entryPath: remap.get(reference.entryPath),
157
+ entryPath: resolveRemapped(remap, reference.entryPath),
118
158
  }));
119
159
  return {
120
160
  perSheet,
@@ -124,14 +164,39 @@ export function planPreservedParts(workbook, generatedDrawingCount, generatedMed
124
164
  themeEmitted: theme !== undefined,
125
165
  };
126
166
  }
167
+ function resolveRemapped(remap, path) {
168
+ const resolved = remap.get(path);
169
+ if (resolved === undefined) {
170
+ throw new InternalError(`preserved part ${quoted(path)} was never assigned a new path`);
171
+ }
172
+ return resolved;
173
+ }
127
174
  function preservedPartPath(originalPath, numbering) {
128
175
  const ext = extensionOf(originalPath);
129
- if (ext.toLowerCase() === 'vml')
176
+ if (ext === 'vml')
130
177
  return vmlDrawingPart(++numbering.vml);
131
178
  if (originalPath.startsWith('xl/media/'))
132
179
  return mediaPart(++numbering.media, ext);
133
- if (originalPath.startsWith('xl/drawings/') && ext.toLowerCase() === 'xml') {
180
+ if (originalPath.startsWith('xl/drawings/') && ext === 'xml') {
134
181
  return drawingPart(++numbering.drawing);
135
182
  }
183
+ if (isNumberedPart(originalPath, PIVOT_TABLE_PREFIX)) {
184
+ return pivotTablePart(++numbering.pivotTable);
185
+ }
186
+ if (isNumberedPart(originalPath, PIVOT_CACHE_DEFINITION_PREFIX)) {
187
+ return pivotCacheDefinitionPart(++numbering.pivotCacheDefinition);
188
+ }
189
+ if (isNumberedPart(originalPath, PIVOT_CACHE_RECORDS_PREFIX)) {
190
+ return pivotCacheRecordsPart(++numbering.pivotCacheRecords);
191
+ }
136
192
  return originalPath;
137
193
  }
194
+ const PIVOT_TABLE_PREFIX = numberedPartPrefix(pivotTablePart);
195
+ const PIVOT_CACHE_DEFINITION_PREFIX = numberedPartPrefix(pivotCacheDefinitionPart);
196
+ const PIVOT_CACHE_RECORDS_PREFIX = numberedPartPrefix(pivotCacheRecordsPart);
197
+ function numberedPartPrefix(part) {
198
+ return part(1).slice(0, -'1.xml'.length);
199
+ }
200
+ function isNumberedPart(path, prefix) {
201
+ return path.startsWith(prefix) && /^\d+\.xml$/.test(path.slice(prefix.length));
202
+ }
@@ -5,6 +5,12 @@ export declare const SHARED_STRINGS_PART = "xl/sharedStrings.xml";
5
5
  /** Singular and unnumbered, unlike the per-sheet thread parts: one identity registry serves the
6
6
  * whole workbook's threaded comments. */
7
7
  export declare const PERSONS_PART = "xl/persons/person.xml";
8
+ /** The metadata a `<c cm>` and `<c vm>` index: what marks a formula a dynamic array, and what names
9
+ * the error behind a `#VALUE!`. */
10
+ export declare const METADATA_PART = "xl/metadata.xml";
11
+ /** The rich values a value-metadata block names, and the structures they are read against. */
12
+ export declare const RICH_VALUES_PART = "xl/richData/rdrichvalue.xml";
13
+ export declare const RICH_VALUE_STRUCTURES_PART = "xl/richData/rdrichvaluestructure.xml";
8
14
  export declare const CORE_PROPS_PART = "docProps/core.xml";
9
15
  export declare const APP_PROPS_PART = "docProps/app.xml";
10
16
  /** `xl/worksheets/sheet{n}.xml`, numbered by the sheet's position in the workbook (1-based). */
@@ -31,11 +37,3 @@ export declare function pivotTablePart(number: number): string;
31
37
  export declare function pivotCacheDefinitionPart(number: number): string;
32
38
  /** `xl/pivotCache/pivotCacheRecords{n}.xml`: the cached rows the definition points at. */
33
39
  export declare function pivotCacheRecordsPart(number: number): string;
34
- /**
35
- * A part named as a Target of a relationship carried by a *worksheet*. Every worksheet part lives in
36
- * `xl/worksheets/`, so one sheet's view of a target is every sheet's, and the sheet number the
37
- * arithmetic runs against does not matter.
38
- */
39
- export declare function targetFromWorksheet(partPath: string): string;
40
- /** A part named as a Target of a relationship carried by the workbook part. */
41
- export declare function targetFromWorkbook(partPath: string): string;
@@ -1,8 +1,10 @@
1
- import { relativePartPath } from '../opc/part-paths.js';
2
1
  export const WORKBOOK_PART = 'xl/workbook.xml';
3
2
  export const STYLES_PART = 'xl/styles.xml';
4
3
  export const SHARED_STRINGS_PART = 'xl/sharedStrings.xml';
5
4
  export const PERSONS_PART = 'xl/persons/person.xml';
5
+ export const METADATA_PART = 'xl/metadata.xml';
6
+ export const RICH_VALUES_PART = 'xl/richData/rdrichvalue.xml';
7
+ export const RICH_VALUE_STRUCTURES_PART = 'xl/richData/rdrichvaluestructure.xml';
6
8
  export const CORE_PROPS_PART = 'docProps/core.xml';
7
9
  export const APP_PROPS_PART = 'docProps/app.xml';
8
10
  export function worksheetPart(number) {
@@ -38,9 +40,3 @@ export function pivotCacheDefinitionPart(number) {
38
40
  export function pivotCacheRecordsPart(number) {
39
41
  return `xl/pivotCache/pivotCacheRecords${number}.xml`;
40
42
  }
41
- export function targetFromWorksheet(partPath) {
42
- return relativePartPath(worksheetPart(1), partPath);
43
- }
44
- export function targetFromWorkbook(partPath) {
45
- return relativePartPath(WORKBOOK_PART, partPath);
46
- }
@@ -1,9 +1,9 @@
1
1
  import type { PivotTable } from '../../core/pivot-table.ts';
2
- /** The `pivotCacheDefinition` part: the source reference and the field catalogue. `r:id="rId1"`
3
- * names the cache-records part through this cache's own rels part. `refreshOnLoad="1"` tells Excel to
4
- * rebuild the pivot body from the cache on open, so the layout stays correct without us computing it
5
- * to the pixel. `recordCount` is the number of source data rows. */
6
- export declare function pivotCacheDefinitionXml(table: PivotTable): string;
2
+ /** The `pivotCacheDefinition` part: the source reference and the field catalogue. `recordsRelId` is
3
+ * the id this cache's own rels part gives the cache-records part, which `r:id` cites.
4
+ * `refreshOnLoad="1"` tells Excel to rebuild the pivot body from the cache on open, so the layout stays
5
+ * correct without us computing it to the pixel. `recordCount` is the number of source data rows. */
6
+ export declare function pivotCacheDefinitionXml(table: PivotTable, recordsRelId: string): string;
7
7
  /** The `pivotCacheRecords` part: one `<r>` per source data row, each cell either an index into an
8
8
  * axis field's shared-items catalogue (`<x>`) or an inline value (`<n>`/`<s>`/`<m>`). */
9
9
  export declare function pivotCacheRecordsXml(table: PivotTable): string;
@@ -1,5 +1,5 @@
1
1
  import { encodeAddress } from '../../core/address.js';
2
- import { escapeAttr, XML_DECLARATION } from '../../xml/xml.js';
2
+ import { escapeAttr, numberText, XML_DECLARATION } from '../../xml/xml.js';
3
3
  import { RELATIONSHIPS_NS } from '../opc/namespaces.js';
4
4
  import { SPREADSHEETML_NS } from './namespaces.js';
5
5
  const METRIC_CAPTIONS = {
@@ -15,29 +15,19 @@ const METRIC_CAPTIONS = {
15
15
  var: 'Var',
16
16
  varp: 'Varp',
17
17
  };
18
- export function pivotCacheDefinitionXml(table) {
18
+ export function pivotCacheDefinitionXml(table, recordsRelId) {
19
19
  const fields = table.cacheFields
20
20
  .map((field) => {
21
21
  const shared = field.sharedItems;
22
- if (shared !== null) {
23
- const items = shared.map(sharedItemXml).join('');
24
- const blank = field.containsBlank ? ' containsBlank="1"' : '';
25
- return (`<cacheField name="${escapeAttr(field.name)}" numFmtId="0">` +
26
- `<sharedItems${blank} count="${shared.length}">${items}</sharedItems>` +
27
- `</cacheField>`);
28
- }
29
- const blank = field.containsBlank ? ' containsBlank="1"' : '';
30
- const numeric = field.numeric;
31
- const descriptor = numeric === null
32
- ? `<sharedItems${blank}/>`
33
- : `<sharedItems containsSemiMixedTypes="0" containsString="0" containsNumber="1" ` +
34
- `containsInteger="${numeric.allInteger ? 1 : 0}"${blank} ` +
35
- `minValue="${numeric.min}" maxValue="${numeric.max}"/>`;
22
+ const kinds = sharedItemsKinds(field);
23
+ const descriptor = shared === null
24
+ ? `<sharedItems${kinds}/>`
25
+ : `<sharedItems${kinds} count="${shared.length}">${shared.map(sharedItemXml).join('')}</sharedItems>`;
36
26
  return `<cacheField name="${escapeAttr(field.name)}" numFmtId="0">${descriptor}</cacheField>`;
37
27
  })
38
28
  .join('');
39
29
  return (XML_DECLARATION +
40
- `<pivotCacheDefinition xmlns="${SPREADSHEETML_NS}" xmlns:r="${RELATIONSHIPS_NS}" r:id="rId1" refreshOnLoad="1" ` +
30
+ `<pivotCacheDefinition xmlns="${SPREADSHEETML_NS}" xmlns:r="${RELATIONSHIPS_NS}" r:id="${escapeAttr(recordsRelId)}" refreshOnLoad="1" ` +
41
31
  `refreshedBy="ts-xlsx" createdVersion="8" refreshedVersion="8" minRefreshableVersion="3" ` +
42
32
  `recordCount="${table.records.length}">` +
43
33
  `<cacheSource type="worksheet">` +
@@ -56,22 +46,21 @@ export function pivotCacheRecordsXml(table) {
56
46
  `</pivotCacheRecords>`);
57
47
  }
58
48
  export function pivotTableXml(table, name, cacheId) {
59
- const rowField = table.rowFields[0];
60
- const columnField = table.columnFields[0];
49
+ const rowField = table.rowFields[0] ?? 0;
50
+ const columnField = table.columnFields[0] ?? 0;
61
51
  const rowGroups = table.cacheFields[rowField]?.sharedItems?.length ?? 1;
62
52
  const columnGroups = table.cacheFields[columnField]?.sharedItems?.length ?? 1;
63
53
  const location = `A1:${encodeAddress(2 + columnGroups, 3 + rowGroups)}`;
64
54
  const pivotFields = table.cacheFields
65
55
  .map((field, index) => {
56
+ const dataField = index === table.valueField ? ' dataField="1"' : '';
66
57
  if (table.rowFields.includes(index) || table.columnFields.includes(index)) {
67
58
  const axis = table.rowFields.includes(index) ? 'axisRow' : 'axisCol';
68
59
  const items = field.sharedItems ?? [];
69
60
  const entries = `${items.map((_item, i) => `<item x="${i}"/>`).join('')}<item t="default"/>`;
70
- return `<pivotField axis="${axis}" showAll="0"><items count="${items.length + 1}">${entries}</items></pivotField>`;
61
+ return `<pivotField axis="${axis}"${dataField} showAll="0"><items count="${items.length + 1}">${entries}</items></pivotField>`;
71
62
  }
72
- if (index === table.valueField)
73
- return '<pivotField dataField="1" showAll="0"/>';
74
- return '<pivotField showAll="0"/>';
63
+ return `<pivotField${dataField} showAll="0"/>`;
75
64
  })
76
65
  .join('');
77
66
  const rowFields = table.rowFields.map((index) => `<field x="${index}"/>`).join('');
@@ -102,12 +91,25 @@ function dataFieldXml(table) {
102
91
  return (`<dataField name="${escapeAttr(caption)}" fld="${table.valueField}"${subtotal} ` +
103
92
  `baseField="0" baseItem="0"/>`);
104
93
  }
94
+ function sharedItemsKinds(field) {
95
+ const { containsString, containsBlank, numeric } = field;
96
+ const hasNumber = numeric !== null;
97
+ return ((!containsString && !containsBlank && hasNumber ? ' containsSemiMixedTypes="0"' : '') +
98
+ (containsString ? '' : ' containsString="0"') +
99
+ (containsBlank ? ' containsBlank="1"' : '') +
100
+ (containsString && hasNumber ? ' containsMixedTypes="1"' : '') +
101
+ (numeric === null
102
+ ? ''
103
+ : ' containsNumber="1"' +
104
+ (numeric.allInteger ? ' containsInteger="1"' : '') +
105
+ ` minValue="${numberText(numeric.min)}" maxValue="${numberText(numeric.max)}"`));
106
+ }
105
107
  function sharedItemXml(item) {
106
108
  switch (item.kind) {
107
109
  case 'string':
108
110
  return `<s v="${escapeAttr(item.value)}"/>`;
109
111
  case 'number':
110
- return `<n v="${item.value}"/>`;
112
+ return `<n v="${numberText(item.value)}"/>`;
111
113
  case 'blank':
112
114
  return '<m/>';
113
115
  }
@@ -0,0 +1,6 @@
1
+ import { type SheetSplice } from '../../core/formula-references.ts';
2
+ /**
3
+ * A preserved part's bytes with the references it spells moved through `splices`, in order, or the
4
+ * same bytes when the part is of a kind that spells none or nothing in it moved.
5
+ */
6
+ export declare function splicePreservedPart(bytes: Uint8Array, contentType: string, splices: readonly SheetSplice[]): Uint8Array;
@@ -0,0 +1,74 @@
1
+ import { spliceFormula } from '../../core/formula-references.js';
2
+ import { splicePivotSource } from '../../core/pivot-table.js';
3
+ import { XmlParseError } from '../../xml/errors.js';
4
+ import { elementRange, elementRanges, openElements } from '../../xml/xml-read.js';
5
+ import { decodeEntities } from '../../xml/xml-scan.js';
6
+ import { escapeText, startTag } from '../../xml/xml.js';
7
+ import { relAttr } from '../opc/namespaces.js';
8
+ const chartReferences = (xml, splices) => {
9
+ const edits = [];
10
+ for (const range of elementRanges(xml, 'f')) {
11
+ const content = xml.slice(range.contentStart, range.contentEnd);
12
+ if (content.includes('<'))
13
+ continue;
14
+ const formula = decodeEntities(content);
15
+ const moved = splices.reduce((text, edit) => spliceFormula(text, undefined, edit), formula);
16
+ if (moved !== formula) {
17
+ edits.push({ start: range.contentStart, end: range.contentEnd, text: escapeText(moved) });
18
+ }
19
+ }
20
+ return edits;
21
+ };
22
+ const pivotCacheSource = (xml, splices) => {
23
+ for (const source of openElements(xml, 'worksheetSource')) {
24
+ if (relAttr(source.scope, source.attrs, 'id') !== undefined)
25
+ return [];
26
+ break;
27
+ }
28
+ const range = elementRange(xml, ['cacheSource', 'worksheetSource']);
29
+ const { sheet, ref } = range?.attrs ?? {};
30
+ if (range === undefined || sheet === undefined || ref === undefined)
31
+ return [];
32
+ const moved = splices.reduce((text, edit) => splicePivotSource(sheet, text, edit), ref);
33
+ if (moved === ref)
34
+ return [];
35
+ return [
36
+ {
37
+ start: range.start,
38
+ end: range.end,
39
+ text: startTag(range.name, { ...range.attrs, ref: moved }, true),
40
+ },
41
+ ];
42
+ };
43
+ const REWRITERS = new Map([
44
+ ['application/vnd.openxmlformats-officedocument.drawingml.chart+xml', chartReferences],
45
+ ['application/vnd.ms-office.chartex+xml', chartReferences],
46
+ [
47
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml',
48
+ pivotCacheSource,
49
+ ],
50
+ ].map(([type, rewrite]) => [type.toLowerCase(), rewrite]));
51
+ export function splicePreservedPart(bytes, contentType, splices) {
52
+ if (splices.length === 0)
53
+ return bytes;
54
+ const rewrite = REWRITERS.get(contentType.toLowerCase());
55
+ if (rewrite === undefined)
56
+ return bytes;
57
+ const source = new TextDecoder().decode(bytes);
58
+ let edits;
59
+ try {
60
+ edits = rewrite(source, splices);
61
+ }
62
+ catch (error) {
63
+ if (error instanceof XmlParseError)
64
+ return bytes;
65
+ throw error;
66
+ }
67
+ if (edits.length === 0)
68
+ return bytes;
69
+ let xml = source;
70
+ for (const edit of edits.toSorted((a, b) => b.start - a.start)) {
71
+ xml = xml.slice(0, edit.start) + edit.text + xml.slice(edit.end);
72
+ }
73
+ return new TextEncoder().encode(xml);
74
+ }
@@ -0,0 +1,29 @@
1
+ import type { Worksheet } from '../../core/worksheet.ts';
2
+ /** One `<comment>` read back from a comments part. */
3
+ export interface ParsedComment {
4
+ readonly text: string;
5
+ /**
6
+ * The thread head id this comment is the legacy fallback for, read off its synthetic `tc={headId}`
7
+ * author; absent for a user's own note.
8
+ */
9
+ readonly threadId?: string;
10
+ }
11
+ /**
12
+ * Parse a `comments{n}.xml` part into a map of A1 reference → comment. Text runs within one comment are
13
+ * concatenated; an author-name run is Excel's own convention and is not stripped, so a note reads back
14
+ * as exactly the text that was written.
15
+ */
16
+ export declare function parseComments(xml: string): Map<string, ParsedComment>;
17
+ /**
18
+ * Apply a parsed comments part onto a sheet's cells as notes, addressing each by its A1 reference.
19
+ *
20
+ * A thread's legacy fallback is not a note and does not become one: its text is boilerplate wrapping a
21
+ * copy of the conversation, so surfacing it as `cell.note` hands the caller garbage, and on write it
22
+ * would be re-emitted as a plain note, destroying the `tc=`/`xr:uid` binding and leaving Excel unable to
23
+ * see the thread at all.
24
+ *
25
+ * Suppressed only for a conversation the reader actually holds: a file whose thread part is missing or
26
+ * damaged has nothing else left, so there the boilerplate is kept rather than the content lost. Call
27
+ * after the sheet's threads are restored, since that is what this reads to decide.
28
+ */
29
+ export declare function applyNotes(sheet: Worksheet, comments: ReadonlyMap<string, ParsedComment>): void;
@@ -0,0 +1,75 @@
1
+ import { tryDecodeCellRef } from '../../core/address.js';
2
+ import { numInteger } from '../../xml/xml-attrs.js';
3
+ import { parseXml, TextCapture } from '../../xml/xml-read.js';
4
+ import { localName } from '../../xml/xml-scan.js';
5
+ import { RunAccumulator } from './read-rich-runs.js';
6
+ const COMMENT_EMPTY_CLOSES = new Set(['author', 'text']);
7
+ const THREAD_AUTHOR_PREFIX = 'tc=';
8
+ export function parseComments(xml) {
9
+ const comments = new Map();
10
+ const authors = [];
11
+ let currentRef;
12
+ let currentAuthorId;
13
+ const author = new TextCapture('author');
14
+ const bodyRuns = new RunAccumulator({ container: 'text', readRuns: false });
15
+ let body = '';
16
+ parseXml(xml, {
17
+ onOpen(name, attrs, selfClosing) {
18
+ const local = localName(name);
19
+ if (local === 'comment') {
20
+ currentRef = attrs.ref;
21
+ currentAuthorId = attrs.authorId;
22
+ body = '';
23
+ }
24
+ if (!bodyRuns.open(local, attrs, selfClosing))
25
+ author.open(local, selfClosing);
26
+ },
27
+ onText(text) {
28
+ bodyRuns.text(text);
29
+ author.text(text);
30
+ },
31
+ onClose(name) {
32
+ const local = localName(name);
33
+ const bodyClose = bodyRuns.close(local);
34
+ if (bodyClose === 'container') {
35
+ body = bodyRuns.plainText;
36
+ return;
37
+ }
38
+ if (bodyClose === 'claimed')
39
+ return;
40
+ const text = author.close(local);
41
+ if (local === 'author') {
42
+ authors.push(text ?? '');
43
+ }
44
+ else if (local === 'comment' && currentRef !== undefined) {
45
+ const threadId = threadIdOf(authors[numInteger(currentAuthorId, 0) ?? -1]);
46
+ comments.set(currentRef, {
47
+ text: body,
48
+ ...(threadId !== undefined ? { threadId } : {}),
49
+ });
50
+ currentRef = undefined;
51
+ currentAuthorId = undefined;
52
+ }
53
+ },
54
+ }, { closeEmptyElements: COMMENT_EMPTY_CLOSES });
55
+ return comments;
56
+ }
57
+ function threadIdOf(author) {
58
+ if (author === undefined || !author.startsWith(THREAD_AUTHOR_PREFIX))
59
+ return undefined;
60
+ const id = author.slice(THREAD_AUTHOR_PREFIX.length);
61
+ return id === '' ? undefined : id;
62
+ }
63
+ export function applyNotes(sheet, comments) {
64
+ const headIds = new Set(sheet.commentThreads.flatMap((thread) => {
65
+ const head = thread.comments[0];
66
+ return head === undefined ? [] : [head.id];
67
+ }));
68
+ for (const [ref, comment] of comments) {
69
+ if (comment.threadId !== undefined && headIds.has(comment.threadId))
70
+ continue;
71
+ if (tryDecodeCellRef(ref) === undefined)
72
+ continue;
73
+ sheet.getCell(ref).note = comment.text;
74
+ }
75
+ }
@@ -0,0 +1,59 @@
1
+ import type { CommentThread } from '../../core/comment-thread.ts';
2
+ import { Workbook } from '../../core/workbook.ts';
3
+ import type { Worksheet } from '../../core/worksheet.ts';
4
+ import type { CollectingPass } from '../../xml/xml-read.ts';
5
+ import { type PackageAccessors, type PartRelationships } from '../opc/read-opc.ts';
6
+ import { type ParsedComment } from './read-comments.ts';
7
+ /**
8
+ * What every part reader in one package read shares: the inflated package, the model being built, the
9
+ * content-type resolver a preserved part's closure is captured through, and the interning map that
10
+ * makes one workbook image per media part however many places point at it.
11
+ *
12
+ * None of the four varies within a read, and threading them positionally is what let `internImage`
13
+ * end up taking the same three in a different order from both of its callers. What genuinely varies
14
+ * -- a part's relationships, the sheet being filled -- stays a positional argument, and the sheet's
15
+ * rels in particular are deliberately *not* in here: they are per sheet, and a stale copy of them
16
+ * would send every sheet's parts to the first sheet's.
17
+ */
18
+ export interface PackageReadContext {
19
+ readonly pkg: PackageAccessors;
20
+ readonly workbook: Workbook;
21
+ readonly contentTypeOf: (path: string) => string;
22
+ readonly imageIdByMediaPath: Map<string, number>;
23
+ }
24
+ export declare function readSheetComments(sheetRels: PartRelationships): Map<string, ParsedComment> | undefined;
25
+ export declare function readWorkbookPersons({ workbook }: PackageReadContext, workbookRels: PartRelationships): void;
26
+ export declare function readWorkbookTheme(context: PackageReadContext, workbookRels: PartRelationships): void;
27
+ export declare function readSheetCommentThreads({ workbook }: PackageReadContext, sheetRels: PartRelationships): CommentThread[];
28
+ export declare function readSheetPrinterSettings(sheetRels: PartRelationships): Uint8Array | undefined;
29
+ export declare function readSheetImages(context: PackageReadContext, sheetRels: PartRelationships, sheet: Worksheet): void;
30
+ export declare function readSheetBackground(context: PackageReadContext, sheetRels: PartRelationships, sheet: Worksheet): void;
31
+ export declare function readSheetPreservedReferences(context: PackageReadContext, sheetRels: PartRelationships, referenceRelIds: WorksheetReferenceRelIds, sheet: Worksheet): void;
32
+ export declare function readWorkbookPreservedReferences(context: PackageReadContext, workbookRels: PartRelationships, registrations: WorkbookRegistrations): void;
33
+ export declare function readRootPreservedReferences(context: PackageReadContext): void;
34
+ /** The two `<pivotCaches>`/`<externalReferences>` registries a preserved reference is wired by,
35
+ * gathered from the workbook part's own scan rather than from two more of it. */
36
+ export interface WorkbookRegistrations {
37
+ readonly cacheIdByRelId: ReadonlyMap<string, string>;
38
+ readonly externalIndexByRelId: ReadonlyMap<string, number>;
39
+ }
40
+ export declare function pivotCacheRegistrationsPass(): CollectingPass<ReadonlyMap<string, string>>;
41
+ export declare function externalReferenceRegistrationsPass(): CollectingPass<ReadonlyMap<string, number>>;
42
+ /** The `r:id` each of the two element-wired references carries, or `undefined` where absent. */
43
+ export type WorksheetReferenceRelIds = Readonly<Partial<Record<'drawing' | 'legacyDrawingHF', string>>>;
44
+ /**
45
+ * A pass gathering the `r:id` of the first `<drawing>` and `<legacyDrawingHF>` in a worksheet.
46
+ *
47
+ * These two references live in the worksheet body rather than being distinguishable by relationship
48
+ * Type, since a header/footer VML and a comment VML share the `vmlDrawing` type, so the specific
49
+ * relationship is found by reading the element's own `r:id`.
50
+ *
51
+ * A pass rather than its own scan, because the sheet part is the largest in a package by a wide
52
+ * margin and this ran a full extra scan of it, once or twice per sheet, for two attributes.
53
+ * `readSheet` already builds a multi-pass single parse of it whose own comment records that five
54
+ * separate scans "spent 45% of a large file's read on four scans that matched no element"; this was
55
+ * the sixth scan, added later, that the same argument covers.
56
+ */
57
+ export declare function worksheetReferencePass(): CollectingPass<WorksheetReferenceRelIds>;
58
+ export declare function readSheetTables({ pkg }: PackageReadContext, sheetRels: PartRelationships, sheet: Worksheet, definedNames: ReadonlySet<string>): void;
59
+ export declare function readSheetPivotTables({ pkg }: PackageReadContext, sheetRels: PartRelationships, sheet: Worksheet): void;