@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
@@ -0,0 +1,175 @@
1
+ import { parseDateText } from '../../core/date.js';
2
+ import { definedNameKeys, 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: text });
129
+ pending = undefined;
130
+ },
131
+ },
132
+ closeEmptyElements: new Set(['definedName']),
133
+ result(sheetOrder) {
134
+ const names = definedNameKeys(drafts);
135
+ return drafts.map(({ localSheetId, refersTo: stored, ...draft }) => {
136
+ const named = { ...draft, refersTo: unmangleFunctions(stored, names) };
137
+ const scope = sheetOrder[localSheetId];
138
+ return scope === undefined ? named : { ...named, scope };
139
+ });
140
+ },
141
+ spellings() {
142
+ return definedNameKeys(drafts);
143
+ },
144
+ };
145
+ }
146
+ const CORE_PROPERTY_LOCAL_NAMES = new Set([
147
+ 'title',
148
+ 'creator',
149
+ 'lastModifiedBy',
150
+ 'created',
151
+ 'modified',
152
+ ]);
153
+ export function applyCoreProperties(workbook, xml) {
154
+ for (const { local, text } of capturedText(xml, CORE_PROPERTY_LOCAL_NAMES)) {
155
+ if (local === 'title')
156
+ workbook.properties.title = text;
157
+ else if (local === 'creator')
158
+ workbook.properties.creator = text;
159
+ else if (local === 'lastModifiedBy')
160
+ workbook.properties.lastModifiedBy = text;
161
+ else {
162
+ const date = parseDateText(text);
163
+ if (date !== null) {
164
+ if (local === 'created')
165
+ workbook.properties.created = date;
166
+ else
167
+ workbook.properties.modified = date;
168
+ }
169
+ }
170
+ }
171
+ }
172
+ export function applyAppProperties(workbook, xml) {
173
+ for (const { text } of capturedText(xml, 'Company'))
174
+ workbook.properties.company = text;
175
+ }
@@ -1,5 +1,7 @@
1
+ import type { DateEpoch } from '../../core/date.ts';
1
2
  import type { Worksheet } from '../../core/worksheet.ts';
2
3
  import { type SaxPass } from '../../xml/xml-read.ts';
4
+ import type { CellMetadataIndex } from '../cell-metadata/metadata.ts';
3
5
  import type { XfStyle } from '../style/xf-style.ts';
4
6
  import type { SharedString } from './cell-value.ts';
5
7
  /**
@@ -7,7 +9,11 @@ import type { SharedString } from './cell-value.ts';
7
9
  * merges, the autofilter, page breaks, and the view and print layout. It commits as it goes rather
8
10
  * than gathering, so it has nothing to hand back once the parse ends.
9
11
  *
10
- * Offered as a pass because the worksheet is the largest part in a package and four other readers
11
- * want the same events, so the five share one parse of it rather than scanning it once each.
12
+ * Offered as a pass because the worksheet is the largest part in a package and other readers want
13
+ * the same events, so they all share one parse of it rather than scanning it once each.
14
+ *
15
+ * `definedNames` is every name the workbook defines, as `definedNameKeys` spells them: the workbook
16
+ * part is read before any sheet, so they are known before the first formula is. `cellMetadata` is
17
+ * what the workbook's `cm` and `vm` values resolve to, read from the parts they index.
12
18
  */
13
- export declare function worksheetPass(sheet: Worksheet, sharedStrings: readonly SharedString[], xfStyles: ReadonlyArray<XfStyle>): SaxPass;
19
+ export declare function worksheetPass(sheet: Worksheet, sharedStrings: readonly SharedString[], xfStyles: ReadonlyArray<XfStyle>, dateEpoch: DateEpoch, definedNames: ReadonlySet<string>, cellMetadata: CellMetadataIndex): SaxPass;
@@ -1,18 +1,26 @@
1
- import { MAX_COLUMN, MAX_ROW, tryDecodeRange } from '../../core/address.js';
1
+ import { boundedRect, tryDecodeRange } from '../../core/address.js';
2
2
  import { isCustomFilterOperator, } from '../../core/autofilter.js';
3
3
  import { INTERNAL } from '../../core/internal.js';
4
- import { HEADER_FOOTER_ELEMENTS, MARGIN_SIDES, PAGE_SETUP_FACETS, PRINT_OPTION_FLAGS, } from '../../core/page-setup.js';
5
- import { SHEET_PROTECTION_FLAGS, } from '../../core/protection.js';
4
+ import { HEADER_FOOTER_ELEMENTS } from '../../core/page-setup.js';
6
5
  import { assignStyleFacets } from '../../core/style.js';
7
- import {} from '../../xml/xml-read.js';
8
- import { boolPresent, boolStrict, boolTristate, decodeSpreadsheetText, localName, numFinite, numInteger, } from '../../xml/xml-scan.js';
9
- import { CellAccumulator } from './cell-accumulator.js';
10
- import { parseColor } from './color-xml.js';
6
+ import { decodeSpreadsheetText, numFinite, numInteger } from '../../xml/xml-attrs.js';
7
+ import { TextCapture } from '../../xml/xml-read.js';
8
+ import { boolPresent, boolStrict, localName } from '../../xml/xml-scan.js';
9
+ import { ColumnRecordBudget } from '../read-policy/column-budget.js';
10
+ import { admitting } from '../read-policy/read-repair.js';
11
+ import { CellStyleResolver } from '../style/cell-style-resolution.js';
12
+ import { CellAccumulator, WORKSHEET_BODY_EMPTY_CLOSES } from './cell-accumulator.js';
13
+ import { takeColumnSpan } from './column-span.js';
14
+ import { RowPositionTracker } from './row-position.js';
15
+ import { applySheetProperties, PageBreakAccumulator, parseSheetProtection, } from './sheet-properties.js';
11
16
  const HEADER_FOOTER_CHILDREN = new Set(HEADER_FOOTER_ELEMENTS);
12
17
  function isHeaderFooterElement(local) {
13
18
  return HEADER_FOOTER_CHILDREN.has(local);
14
19
  }
15
- const WORKSHEET_EMPTY_CLOSES = new Set(['c', 'autoFilter']);
20
+ const WORKSHEET_EMPTY_CLOSES = new Set([
21
+ ...WORKSHEET_BODY_EMPTY_CLOSES,
22
+ 'autoFilter',
23
+ ]);
16
24
  function pendingFilterCriteria(values, blank, predicates, and) {
17
25
  if (values !== null && (values.length > 0 || blank)) {
18
26
  return { kind: 'values', values, blank };
@@ -22,31 +30,6 @@ function pendingFilterCriteria(values, blank, predicates, and) {
22
30
  }
23
31
  return null;
24
32
  }
25
- function parseSheetProtection(attrs) {
26
- if (boolTristate(attrs.sheet) === false)
27
- return undefined;
28
- const flags = {};
29
- for (const { key } of SHEET_PROTECTION_FLAGS) {
30
- const raw = attrs[key];
31
- if (raw !== undefined)
32
- flags[key] = !boolStrict(raw);
33
- }
34
- const { algorithmName, hashValue, saltValue, spinCount } = attrs;
35
- const spin = numInteger(spinCount, 0);
36
- if (algorithmName !== undefined &&
37
- hashValue !== undefined &&
38
- saltValue !== undefined &&
39
- spin !== undefined) {
40
- const credential = {
41
- algorithmName,
42
- hashValue,
43
- saltValue,
44
- spinCount: spin,
45
- };
46
- return { flags, credential };
47
- }
48
- return { flags };
49
- }
50
33
  class AutoFilterAccumulator {
51
34
  #ref = null;
52
35
  #columns = [];
@@ -96,82 +79,67 @@ class AutoFilterAccumulator {
96
79
  if (this.#ref === null)
97
80
  return;
98
81
  const decoded = tryDecodeRange(this.#ref);
99
- const left = decoded?.left;
100
- const right = decoded?.right;
101
- if (left !== undefined && right !== undefined) {
102
- const width = right - left + 1;
82
+ const rect = decoded === undefined ? undefined : boundedRect(decoded);
83
+ if (rect !== undefined) {
84
+ const width = rect.right - rect.left + 1;
103
85
  sheet.autoFilter = { ref: this.#ref, columns: this.#columns.filter((c) => c.colId < width) };
104
86
  }
105
87
  this.#ref = null;
106
88
  this.#columns = [];
107
89
  }
108
90
  }
109
- class PageBreakAccumulator {
110
- #target = null;
111
- begin(target) {
112
- this.#target = target;
113
- }
114
- end() {
115
- this.#target = null;
116
- }
117
- add(attrs) {
118
- if (this.#target === null)
119
- return;
120
- const id = numInteger(attrs.id, 1);
121
- if (id === undefined)
122
- return;
123
- const brk = { id };
124
- const max = numInteger(attrs.max, 0);
125
- if (max !== undefined)
126
- brk.max = max;
127
- if (boolStrict(attrs.man))
128
- brk.man = true;
129
- this.#target.push(brk);
130
- }
131
- }
132
- export function worksheetPass(sheet, sharedStrings, xfStyles) {
133
- const cell = new CellAccumulator({ richRuns: true });
134
- let rowStyle = -1;
135
- let rowCustomFormat = false;
91
+ export function worksheetPass(sheet, sharedStrings, xfStyles, dateEpoch, definedNames, cellMetadata) {
92
+ const cell = new CellAccumulator({ dateEpoch, definedNames, cellMetadata });
136
93
  const autoFilter = new AutoFilterAccumulator();
137
94
  const pageBreaks = new PageBreakAccumulator();
138
- const columnStyle = new Map();
95
+ const styleResolution = new CellStyleResolver();
96
+ const columnBudget = new ColumnRecordBudget();
97
+ const rowPosition = new RowPositionTracker();
98
+ const headerFooterText = new TextCapture(HEADER_FOOTER_ELEMENTS);
99
+ let customViewDepth = 0;
139
100
  const finalizeCellFromState = () => {
140
- const styleIndex = cell.styleIndex >= 0
141
- ? cell.styleIndex
142
- : rowCustomFormat && rowStyle >= 0
143
- ? rowStyle
144
- : (columnStyle.get(cell.col) ?? -1);
145
- const style = styleIndex >= 0 ? xfStyles[styleIndex] : xfStyles[0];
146
- cell.finalize(sheet, sharedStrings, style);
101
+ cell.finalize(sheet, sharedStrings, styleResolution.styleFor(cell.col, cell.styleIndex, xfStyles));
147
102
  };
148
103
  const handlers = {
149
104
  onOpen(name, attrs, selfClosing) {
150
105
  const local = localName(name);
106
+ if (customViewDepth > 0) {
107
+ if (!selfClosing)
108
+ customViewDepth++;
109
+ return;
110
+ }
111
+ if (local === 'customSheetViews') {
112
+ if (!selfClosing)
113
+ customViewDepth = 1;
114
+ return;
115
+ }
151
116
  if (cell.openElement(local, attrs, selfClosing))
152
117
  return;
153
- if (HEADER_FOOTER_CHILDREN.has(local)) {
154
- cell.capture();
118
+ if (isHeaderFooterElement(local)) {
119
+ headerFooterText.open(local, selfClosing);
155
120
  return;
156
121
  }
157
122
  switch (local) {
158
123
  case 'col':
159
- applyColumn(sheet, attrs, xfStyles, columnStyle);
124
+ applyColumn(sheet, attrs, xfStyles, styleResolution, columnBudget);
160
125
  break;
161
- case 'row':
162
- applyRow(sheet, attrs);
163
- rowStyle = numInteger(attrs.s, 0) ?? -1;
164
- rowCustomFormat = boolStrict(attrs.customFormat);
126
+ case 'row': {
127
+ const { number, inGrid } = rowPosition.open(attrs);
128
+ if (inGrid)
129
+ applyRow(sheet, number, attrs);
130
+ cell.openRow(number, inGrid);
131
+ styleResolution.openRow(numInteger(attrs.s, 0) ?? -1, boolStrict(attrs.customFormat));
165
132
  break;
133
+ }
166
134
  case 'mergeCell':
167
135
  if (attrs.ref !== undefined && attrs.ref !== '') {
168
- try {
169
- sheet.mergeCells(attrs.ref);
170
- }
171
- catch {
172
- }
136
+ const ref = attrs.ref;
137
+ admitting(() => {
138
+ sheet.mergeCells(ref);
139
+ });
173
140
  }
174
141
  break;
142
+ case 'sheetPr':
175
143
  case 'tabColor':
176
144
  case 'outlinePr':
177
145
  case 'sheetView':
@@ -218,9 +186,16 @@ export function worksheetPass(sheet, sharedStrings, xfStyles) {
218
186
  }
219
187
  },
220
188
  onText(chunk) {
189
+ if (customViewDepth > 0)
190
+ return;
221
191
  cell.appendChunk(chunk);
192
+ headerFooterText.text(chunk);
222
193
  },
223
194
  onClose(name) {
195
+ if (customViewDepth > 0) {
196
+ customViewDepth--;
197
+ return;
198
+ }
224
199
  const local = localName(name);
225
200
  const claimed = cell.closeElement(local);
226
201
  if (claimed === 'cell') {
@@ -229,14 +204,15 @@ export function worksheetPass(sheet, sharedStrings, xfStyles) {
229
204
  }
230
205
  if (claimed === 'claimed')
231
206
  return;
232
- if (isHeaderFooterElement(local)) {
233
- sheet.headerFooter[local] = decodeSpreadsheetText(cell.capturedText);
207
+ const headerFooter = headerFooterText.close(local);
208
+ if (headerFooter !== undefined && isHeaderFooterElement(local)) {
209
+ sheet.headerFooter[local] = decodeSpreadsheetText(headerFooter);
234
210
  return;
235
211
  }
236
212
  switch (local) {
237
213
  case 'row':
238
- rowStyle = -1;
239
- rowCustomFormat = false;
214
+ styleResolution.closeRow();
215
+ cell.closeRow();
240
216
  break;
241
217
  case 'filterColumn':
242
218
  autoFilter.endColumn();
@@ -255,56 +231,11 @@ export function worksheetPass(sheet, sharedStrings, xfStyles) {
255
231
  };
256
232
  return { handlers, closeEmptyElements: WORKSHEET_EMPTY_CLOSES };
257
233
  }
258
- function applySheetProperties(local, attrs, sheet) {
259
- switch (local) {
260
- case 'tabColor':
261
- sheet.tabColor = parseColor(attrs);
262
- break;
263
- case 'outlinePr':
264
- if (attrs.summaryBelow !== undefined)
265
- sheet.outline.summaryBelow = boolPresent(attrs.summaryBelow);
266
- if (attrs.summaryRight !== undefined)
267
- sheet.outline.summaryRight = boolPresent(attrs.summaryRight);
268
- break;
269
- case 'sheetView':
270
- if (attrs.showGridLines !== undefined && !boolPresent(attrs.showGridLines)) {
271
- sheet.view.showGridLines = false;
272
- }
273
- break;
274
- case 'pane':
275
- if (attrs.state === 'frozen' || attrs.state === 'frozenSplit') {
276
- sheet.view.state = 'frozen';
277
- const xSplit = numInteger(attrs.xSplit, 0);
278
- const ySplit = numInteger(attrs.ySplit, 0);
279
- if (xSplit !== undefined)
280
- sheet.view.xSplit = xSplit;
281
- if (ySplit !== undefined)
282
- sheet.view.ySplit = ySplit;
283
- if (attrs.topLeftCell !== undefined)
284
- sheet.view.topLeftCell = attrs.topLeftCell;
285
- }
286
- break;
287
- case 'pageSetUpPr':
288
- if (attrs.fitToPage !== undefined)
289
- sheet.pageSetup.fitToPage = boolPresent(attrs.fitToPage);
290
- break;
291
- case 'printOptions':
292
- applyPrintOptions(sheet.printOptions, attrs);
293
- break;
294
- case 'pageMargins':
295
- applyMargins(sheet.pageMargins, attrs);
296
- break;
297
- case 'pageSetup':
298
- applyPageSetup(sheet.pageSetup, attrs);
299
- break;
300
- }
301
- }
302
- function applyColumn(sheet, attrs, xfStyles, columnStyle) {
303
- const min = numInteger(attrs.min, 1);
304
- const max = numInteger(attrs.max, 1);
305
- if (min === undefined || max === undefined || min > MAX_COLUMN)
234
+ function applyColumn(sheet, attrs, xfStyles, styleResolution, budget) {
235
+ const span = takeColumnSpan(attrs, budget);
236
+ if (span === undefined)
306
237
  return;
307
- const last = Math.min(max, MAX_COLUMN);
238
+ const { first: min, last } = span;
308
239
  const width = numFinite(attrs.width);
309
240
  const hidden = boolStrict(attrs.hidden);
310
241
  const styleIndex = numInteger(attrs.style, 0) ?? -1;
@@ -322,14 +253,10 @@ function applyColumn(sheet, attrs, xfStyles, columnStyle) {
322
253
  column.collapsed = true;
323
254
  if (style !== undefined)
324
255
  assignStyleFacets(column, style);
325
- if (styleIndex >= 0)
326
- columnStyle.set(index, styleIndex);
327
256
  }
257
+ styleResolution.noteColumnSpan(min, last, numInteger(attrs.style, 0) ?? -1);
328
258
  }
329
- function applyRow(sheet, attrs) {
330
- const number = numInteger(attrs.r, 1);
331
- if (number === undefined || number > MAX_ROW)
332
- return;
259
+ function applyRow(sheet, number, attrs) {
333
260
  const row = sheet.getRow(number);
334
261
  const height = numFinite(attrs.ht);
335
262
  if (height !== undefined && boolPresent(attrs.customHeight))
@@ -342,37 +269,3 @@ function applyRow(sheet, attrs) {
342
269
  if (boolStrict(attrs.collapsed))
343
270
  row.collapsed = true;
344
271
  }
345
- function applyPrintOptions(printOptions, attrs) {
346
- for (const flag of PRINT_OPTION_FLAGS) {
347
- const value = boolTristate(attrs[flag]);
348
- if (value !== undefined)
349
- printOptions[flag] = value;
350
- }
351
- }
352
- function applyMargins(margins, attrs) {
353
- for (const side of MARGIN_SIDES) {
354
- const value = numFinite(attrs[side]);
355
- if (value !== undefined)
356
- margins[side] = value;
357
- }
358
- }
359
- function applyPageSetup(pageSetup, attrs) {
360
- for (const facet of PAGE_SETUP_FACETS) {
361
- const raw = attrs[facet.key];
362
- switch (facet.kind) {
363
- case 'count': {
364
- const value = numInteger(raw, 0);
365
- if (value !== undefined)
366
- pageSetup[facet.key] = value;
367
- break;
368
- }
369
- case 'token':
370
- if (raw !== undefined && facet.isValid(raw))
371
- assignPageSetupToken(pageSetup, facet.key, raw);
372
- break;
373
- }
374
- }
375
- }
376
- function assignPageSetupToken(pageSetup, key, raw) {
377
- pageSetup[key] = raw;
378
- }
@@ -1,9 +1,5 @@
1
- import { Workbook, type WorkbookView } from '../../core/workbook.ts';
2
- import { type WorksheetState } from '../../core/worksheet.ts';
3
- import type { ReadXlsxOptions } from '../opc/read-options.ts';
4
- export type { ReadXlsxOptions } from '../opc/read-options.ts';
5
- export type { StyleTable, XfStyle } from '../style/xf-style.ts';
6
- export { parseStyleTable } from './read-styles.ts';
1
+ import { Workbook } from '../../core/workbook.ts';
2
+ import type { ReadPackageOptions } from '../opc/read-options.ts';
7
3
  /**
8
4
  * Read a spreadsheet package into a {@link Workbook}.
9
5
  *
@@ -19,11 +15,4 @@ export { parseStyleTable } from './read-styles.ts';
19
15
  * @throws {PackageReadError} if the input is a ZIP that cannot be unpacked: a corrupt or
20
16
  * truncated archive, or one exceeding the inflate bound (a probable zip bomb).
21
17
  */
22
- export declare function readXlsx(data: Uint8Array, options?: ReadXlsxOptions): Workbook;
23
- export interface SheetEntry {
24
- readonly name: string;
25
- readonly relId: string;
26
- readonly state?: WorksheetState['state'];
27
- }
28
- export declare function parseWorkbookSheets(xml: string): SheetEntry[];
29
- export declare function applyWorkbookView(view: WorkbookView, xml: string): void;
18
+ export declare function readXlsx(data: Uint8Array, options?: ReadPackageOptions): Workbook;