@cj-tech-master/excelts 9.2.1 → 9.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. package/README.md +25 -2
  2. package/README_zh.md +29 -6
  3. package/dist/browser/index.browser.d.ts +1 -1
  4. package/dist/browser/index.browser.js +4 -0
  5. package/dist/browser/index.d.ts +1 -1
  6. package/dist/browser/index.js +4 -0
  7. package/dist/browser/modules/excel/cell.d.ts +17 -3
  8. package/dist/browser/modules/excel/cell.js +170 -22
  9. package/dist/browser/modules/excel/defined-names.d.ts +96 -1
  10. package/dist/browser/modules/excel/defined-names.js +411 -21
  11. package/dist/browser/modules/excel/image.d.ts +11 -0
  12. package/dist/browser/modules/excel/image.js +24 -1
  13. package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  14. package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
  15. package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
  16. package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  17. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
  18. package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
  19. package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
  20. package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
  21. package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
  22. package/dist/browser/modules/excel/table.js +15 -2
  23. package/dist/browser/modules/excel/types.d.ts +133 -2
  24. package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
  25. package/dist/browser/modules/excel/utils/col-cache.js +15 -0
  26. package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
  27. package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
  28. package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
  29. package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
  30. package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
  31. package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
  32. package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
  33. package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
  34. package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
  35. package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
  36. package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
  37. package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
  38. package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
  39. package/dist/browser/modules/excel/workbook.browser.js +318 -34
  40. package/dist/browser/modules/excel/workbook.d.ts +1 -1
  41. package/dist/browser/modules/excel/worksheet.d.ts +3 -1
  42. package/dist/browser/modules/excel/worksheet.js +21 -2
  43. package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
  44. package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
  45. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  46. package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  47. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  48. package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  49. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  50. package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  51. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  52. package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  53. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  54. package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  55. package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  56. package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  57. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  58. package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  59. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  60. package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  61. package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  62. package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  63. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  64. package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  65. package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  66. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  67. package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  68. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  69. package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  70. package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  71. package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
  72. package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
  73. package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
  74. package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
  75. package/dist/browser/modules/formula/compile/address-utils.js +83 -0
  76. package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
  77. package/dist/browser/modules/formula/compile/binder.js +487 -0
  78. package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
  79. package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
  80. package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
  81. package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
  82. package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
  83. package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
  84. package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  85. package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
  86. package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
  87. package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
  88. package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
  89. package/dist/browser/modules/formula/functions/_date-context.js +29 -0
  90. package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
  91. package/dist/browser/modules/formula/functions/_shared.js +381 -0
  92. package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
  93. package/dist/browser/modules/formula/functions/conditional.js +343 -0
  94. package/dist/browser/modules/formula/functions/database.d.ts +37 -0
  95. package/dist/browser/modules/formula/functions/database.js +274 -0
  96. package/dist/browser/modules/formula/functions/date.d.ts +61 -0
  97. package/dist/browser/modules/formula/functions/date.js +855 -0
  98. package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
  99. package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
  100. package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
  101. package/dist/browser/modules/formula/functions/engineering.js +1128 -0
  102. package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
  103. package/dist/browser/modules/formula/functions/financial.js +2296 -0
  104. package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
  105. package/dist/browser/modules/formula/functions/lookup.js +886 -0
  106. package/dist/browser/modules/formula/functions/math.d.ts +114 -0
  107. package/dist/browser/modules/formula/functions/math.js +1406 -0
  108. package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
  109. package/dist/browser/modules/formula/functions/statistical.js +3390 -0
  110. package/dist/browser/modules/formula/functions/text.d.ts +86 -0
  111. package/dist/browser/modules/formula/functions/text.js +1845 -0
  112. package/dist/browser/modules/formula/host-registry.d.ts +53 -0
  113. package/dist/browser/modules/formula/host-registry.js +69 -0
  114. package/dist/browser/modules/formula/index.d.ts +39 -0
  115. package/dist/browser/modules/formula/index.js +49 -0
  116. package/dist/browser/modules/formula/install.d.ts +62 -0
  117. package/dist/browser/modules/formula/install.js +88 -0
  118. package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  119. package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
  120. package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  121. package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
  122. package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
  123. package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
  124. package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
  125. package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
  126. package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
  127. package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
  128. package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  129. package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
  130. package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  131. package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
  132. package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
  133. package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
  134. package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
  135. package/dist/browser/modules/formula/materialize/types.js +29 -0
  136. package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
  137. package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
  138. package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
  139. package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
  140. package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
  141. package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
  142. package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
  143. package/dist/browser/modules/formula/runtime/values.js +385 -0
  144. package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
  145. package/dist/browser/modules/formula/syntax/ast.js +28 -0
  146. package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
  147. package/dist/browser/modules/formula/syntax/parser.js +439 -0
  148. package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
  149. package/dist/browser/modules/formula/syntax/token-types.js +59 -0
  150. package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
  151. package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
  152. package/dist/browser/modules/pdf/excel-bridge.js +9 -0
  153. package/dist/cjs/index.js +4 -0
  154. package/dist/cjs/modules/excel/cell.js +170 -22
  155. package/dist/cjs/modules/excel/defined-names.js +411 -21
  156. package/dist/cjs/modules/excel/image.js +24 -1
  157. package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
  158. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
  159. package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
  160. package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
  161. package/dist/cjs/modules/excel/table.js +15 -2
  162. package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
  163. package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
  164. package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
  165. package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
  166. package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
  167. package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
  168. package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
  169. package/dist/cjs/modules/excel/workbook.browser.js +318 -34
  170. package/dist/cjs/modules/excel/worksheet.js +20 -1
  171. package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
  172. package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  173. package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
  174. package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
  175. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  176. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
  177. package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  178. package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
  179. package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
  180. package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
  181. package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  182. package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  183. package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  184. package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  185. package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
  186. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  187. package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  188. package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
  189. package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
  190. package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
  191. package/dist/cjs/modules/formula/compile/binder.js +489 -0
  192. package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
  193. package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
  194. package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
  195. package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
  196. package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
  197. package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
  198. package/dist/cjs/modules/formula/functions/_shared.js +396 -0
  199. package/dist/cjs/modules/formula/functions/conditional.js +354 -0
  200. package/dist/cjs/modules/formula/functions/database.js +288 -0
  201. package/dist/cjs/modules/formula/functions/date.js +883 -0
  202. package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
  203. package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
  204. package/dist/cjs/modules/formula/functions/financial.js +2348 -0
  205. package/dist/cjs/modules/formula/functions/lookup.js +902 -0
  206. package/dist/cjs/modules/formula/functions/math.js +1487 -0
  207. package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
  208. package/dist/cjs/modules/formula/functions/text.js +1889 -0
  209. package/dist/cjs/modules/formula/host-registry.js +75 -0
  210. package/dist/cjs/modules/formula/index.js +58 -0
  211. package/dist/cjs/modules/formula/install.js +93 -0
  212. package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
  213. package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
  214. package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
  215. package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
  216. package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
  217. package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
  218. package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
  219. package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
  220. package/dist/cjs/modules/formula/materialize/types.js +32 -0
  221. package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
  222. package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
  223. package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
  224. package/dist/cjs/modules/formula/runtime/values.js +385 -0
  225. package/dist/cjs/modules/formula/syntax/ast.js +8 -0
  226. package/dist/cjs/modules/formula/syntax/parser.js +440 -0
  227. package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
  228. package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
  229. package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
  230. package/dist/esm/index.browser.js +4 -0
  231. package/dist/esm/index.js +4 -0
  232. package/dist/esm/modules/excel/cell.js +170 -22
  233. package/dist/esm/modules/excel/defined-names.js +411 -21
  234. package/dist/esm/modules/excel/image.js +24 -1
  235. package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
  236. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
  237. package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
  238. package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
  239. package/dist/esm/modules/excel/table.js +15 -2
  240. package/dist/esm/modules/excel/utils/col-cache.js +15 -0
  241. package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
  242. package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
  243. package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
  244. package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
  245. package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
  246. package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
  247. package/dist/esm/modules/excel/workbook.browser.js +318 -34
  248. package/dist/esm/modules/excel/worksheet.js +21 -2
  249. package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
  250. package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
  251. package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
  252. package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
  253. package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
  254. package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
  255. package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
  256. package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
  257. package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
  258. package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
  259. package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
  260. package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
  261. package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
  262. package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
  263. package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
  264. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
  265. package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
  266. package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
  267. package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
  268. package/dist/esm/modules/formula/compile/address-utils.js +83 -0
  269. package/dist/esm/modules/formula/compile/binder.js +487 -0
  270. package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
  271. package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
  272. package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
  273. package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
  274. package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
  275. package/dist/esm/modules/formula/functions/_date-context.js +29 -0
  276. package/dist/esm/modules/formula/functions/_shared.js +381 -0
  277. package/dist/esm/modules/formula/functions/conditional.js +343 -0
  278. package/dist/esm/modules/formula/functions/database.js +274 -0
  279. package/dist/esm/modules/formula/functions/date.js +855 -0
  280. package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
  281. package/dist/esm/modules/formula/functions/engineering.js +1128 -0
  282. package/dist/esm/modules/formula/functions/financial.js +2296 -0
  283. package/dist/esm/modules/formula/functions/lookup.js +886 -0
  284. package/dist/esm/modules/formula/functions/math.js +1406 -0
  285. package/dist/esm/modules/formula/functions/statistical.js +3390 -0
  286. package/dist/esm/modules/formula/functions/text.js +1845 -0
  287. package/dist/esm/modules/formula/host-registry.js +69 -0
  288. package/dist/esm/modules/formula/index.js +49 -0
  289. package/dist/esm/modules/formula/install.js +88 -0
  290. package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
  291. package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
  292. package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
  293. package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
  294. package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
  295. package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
  296. package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
  297. package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
  298. package/dist/esm/modules/formula/materialize/types.js +29 -0
  299. package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
  300. package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
  301. package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
  302. package/dist/esm/modules/formula/runtime/values.js +385 -0
  303. package/dist/esm/modules/formula/syntax/ast.js +28 -0
  304. package/dist/esm/modules/formula/syntax/parser.js +439 -0
  305. package/dist/esm/modules/formula/syntax/token-types.js +59 -0
  306. package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
  307. package/dist/esm/modules/pdf/excel-bridge.js +9 -0
  308. package/dist/iife/excelts.iife.js +2302 -373
  309. package/dist/iife/excelts.iife.js.map +1 -1
  310. package/dist/iife/excelts.iife.min.js +34 -34
  311. package/dist/types/index.browser.d.ts +1 -1
  312. package/dist/types/index.d.ts +1 -1
  313. package/dist/types/modules/excel/cell.d.ts +17 -3
  314. package/dist/types/modules/excel/defined-names.d.ts +96 -1
  315. package/dist/types/modules/excel/image.d.ts +11 -0
  316. package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
  317. package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
  318. package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
  319. package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
  320. package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
  321. package/dist/types/modules/excel/types.d.ts +133 -2
  322. package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
  323. package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
  324. package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
  325. package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
  326. package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
  327. package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
  328. package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
  329. package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
  330. package/dist/types/modules/excel/workbook.d.ts +1 -1
  331. package/dist/types/modules/excel/worksheet.d.ts +3 -1
  332. package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
  333. package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
  334. package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
  335. package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
  336. package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
  337. package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
  338. package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
  339. package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
  340. package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
  341. package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
  342. package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
  343. package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
  344. package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
  345. package/dist/types/modules/formula/compile/binder.d.ts +42 -0
  346. package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
  347. package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
  348. package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
  349. package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
  350. package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
  351. package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
  352. package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
  353. package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
  354. package/dist/types/modules/formula/functions/database.d.ts +37 -0
  355. package/dist/types/modules/formula/functions/date.d.ts +61 -0
  356. package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
  357. package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
  358. package/dist/types/modules/formula/functions/financial.d.ts +202 -0
  359. package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
  360. package/dist/types/modules/formula/functions/math.d.ts +114 -0
  361. package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
  362. package/dist/types/modules/formula/functions/text.d.ts +86 -0
  363. package/dist/types/modules/formula/host-registry.d.ts +53 -0
  364. package/dist/types/modules/formula/index.d.ts +39 -0
  365. package/dist/types/modules/formula/install.d.ts +62 -0
  366. package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
  367. package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
  368. package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
  369. package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
  370. package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
  371. package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
  372. package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
  373. package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
  374. package/dist/types/modules/formula/materialize/types.d.ts +179 -0
  375. package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
  376. package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
  377. package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
  378. package/dist/types/modules/formula/runtime/values.d.ts +211 -0
  379. package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
  380. package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
  381. package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
  382. package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
  383. package/package.json +28 -28
@@ -1,4 +1,3 @@
1
- import { colCache } from "../../../utils/col-cache.js";
2
1
  import { BaseXform } from "../base-xform.js";
3
2
  class DefinedNamesXform extends BaseXform {
4
3
  constructor() {
@@ -7,14 +6,21 @@ class DefinedNamesXform extends BaseXform {
7
6
  }
8
7
  render(xmlStream, model) {
9
8
  // <definedNames>
10
- // <definedName name="name">name.ranges.join(',')</definedName>
11
- // <definedName name="_xlnm.Print_Area" localSheetId="0">name.ranges.join(',')</definedName>
9
+ // <definedName name="name">text</definedName>
10
+ // <definedName name="_xlnm.Print_Area" localSheetId="0">text</definedName>
12
11
  // </definedNames>
13
12
  xmlStream.openNode("definedName", {
14
13
  name: model.name,
15
14
  localSheetId: model.localSheetId
16
15
  });
17
- xmlStream.writeText(model.ranges.join(","));
16
+ // For opaque names, write the rawText verbatim to preserve round-trip fidelity.
17
+ // For reference/formula names, join the ranges array as before.
18
+ if (model.kind === "opaque" && model.rawText) {
19
+ xmlStream.writeText(model.rawText);
20
+ }
21
+ else {
22
+ xmlStream.writeText(model.ranges.join(","));
23
+ }
18
24
  xmlStream.closeNode();
19
25
  }
20
26
  parseOpen(node) {
@@ -31,94 +37,23 @@ class DefinedNamesXform extends BaseXform {
31
37
  parseText(text) {
32
38
  this._parsedText.push(text);
33
39
  }
40
+ /**
41
+ * Stage 1 of the two-phase defined name design: the XLSX layer only
42
+ * preserves the raw XML text. Semantic classification (reference vs
43
+ * formula vs opaque) is deferred to `DefinedNames.set model()`.
44
+ */
34
45
  parseClose() {
35
- this.model = {
46
+ const rawText = this._parsedText.join("");
47
+ const model = {
36
48
  name: this._parsedName,
37
- ranges: extractRanges(this._parsedText.join(""))
49
+ ranges: [],
50
+ rawText: rawText.trim() || undefined
38
51
  };
39
52
  if (this._parsedLocalSheetId !== undefined) {
40
- this.model.localSheetId = parseInt(this._parsedLocalSheetId, 10);
41
- }
42
- return false;
43
- }
44
- }
45
- // Regex to validate cell range format:
46
- // - Cell: $A$1 or A1
47
- // - Range: $A$1:$B$10 or A1:B10
48
- // - Row range: $1:$2 (for print titles)
49
- // - Column range: $A:$B (for print titles)
50
- const cellRangeRegexp = /^[$]?[A-Za-z]{1,3}[$]?\d+(:[$]?[A-Za-z]{1,3}[$]?\d+)?$/;
51
- const rowRangeRegexp = /^[$]?\d+:[$]?\d+$/;
52
- const colRangeRegexp = /^[$]?[A-Za-z]{1,3}:[$]?[A-Za-z]{1,3}$/;
53
- function isValidRange(range) {
54
- // Skip array constants wrapped in {} - these are not valid cell ranges
55
- // e.g., {"'Sheet1'!$A$1:$B$10"} or {#N/A,#N/A,FALSE,"text"}
56
- if (range.startsWith("{") || range.endsWith("}")) {
57
- return false;
58
- }
59
- // Extract the cell reference part (after the sheet name if present)
60
- const cellRef = range.split("!").pop() ?? "";
61
- // Must match one of the valid patterns
62
- if (!cellRangeRegexp.test(cellRef) &&
63
- !rowRangeRegexp.test(cellRef) &&
64
- !colRangeRegexp.test(cellRef)) {
65
- return false;
66
- }
67
- try {
68
- const decoded = colCache.decodeEx(range);
69
- // For cell ranges: row/col or top/bottom/left/right should be valid numbers
70
- // For row ranges ($1:$2): top/bottom are numbers, left/right are null
71
- // For column ranges ($A:$B): left/right are numbers, top/bottom are null
72
- if (("row" in decoded && typeof decoded.row === "number") ||
73
- ("top" in decoded && typeof decoded.top === "number") ||
74
- ("left" in decoded && typeof decoded.left === "number")) {
75
- return true;
53
+ model.localSheetId = parseInt(this._parsedLocalSheetId, 10);
76
54
  }
55
+ this.model = model;
77
56
  return false;
78
57
  }
79
- catch {
80
- return false;
81
- }
82
- }
83
- function extractRanges(parsedText) {
84
- // Skip if the entire text is wrapped in {} (array constant)
85
- const trimmed = parsedText.trim();
86
- if (trimmed.startsWith("{") && trimmed.endsWith("}")) {
87
- return [];
88
- }
89
- const ranges = [];
90
- let quotesOpened = false;
91
- let last = "";
92
- parsedText.split(",").forEach(item => {
93
- if (!item) {
94
- return;
95
- }
96
- const quotes = (item.match(/'/g) ?? []).length;
97
- if (!quotes) {
98
- if (quotesOpened) {
99
- last += `${item},`;
100
- }
101
- else if (isValidRange(item)) {
102
- ranges.push(item);
103
- }
104
- return;
105
- }
106
- const quotesEven = quotes % 2 === 0;
107
- if (!quotesOpened && quotesEven && isValidRange(item)) {
108
- ranges.push(item);
109
- }
110
- else if (quotesOpened && !quotesEven) {
111
- quotesOpened = false;
112
- if (isValidRange(last + item)) {
113
- ranges.push(last + item);
114
- }
115
- last = "";
116
- }
117
- else {
118
- quotesOpened = true;
119
- last += `${item},`;
120
- }
121
- });
122
- return ranges;
123
58
  }
124
59
  export { DefinedNamesXform };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * ExternalLinkXform — read and write `xl/externalLinks/externalLinkN.xml`.
3
+ *
4
+ * This part describes one external workbook referenced by the current file:
5
+ * the list of sheets inside the foreign workbook, plus an optional cache of
6
+ * the primitive values at each referenced address. The `r:id` attribute on
7
+ * `<externalBook>` points (via the neighbouring `_rels/externalLinkN.xml.rels`)
8
+ * at the actual file; that resolution is handled by the writer/reader in
9
+ * `xlsx.browser.ts`, not here.
10
+ *
11
+ * Schema shape:
12
+ *
13
+ * <externalLink xmlns=".../spreadsheetml/2006/main"
14
+ * xmlns:r=".../relationships">
15
+ * <externalBook r:id="rId1">
16
+ * <sheetNames>
17
+ * <sheetName val="Sheet1"/>
18
+ * <sheetName val="Sheet2"/>
19
+ * </sheetNames>
20
+ * <sheetDataSet>
21
+ * <sheetData sheetId="0"> (0-based index into sheetNames)
22
+ * <row r="1">
23
+ * <cell r="A1" t="n"><v>123</v></cell>
24
+ * <cell r="B1" t="str"><v>hello</v></cell>
25
+ * </row>
26
+ * <row r="2">
27
+ * <cell r="A2" t="b"><v>1</v></cell>
28
+ * </row>
29
+ * </sheetData>
30
+ * <sheetData sheetId="1" refreshError="1"/> (no cached values)
31
+ * </sheetDataSet>
32
+ * </externalBook>
33
+ * </externalLink>
34
+ *
35
+ * The `t` attribute on `<cell>` mirrors the inline-value types used inside a
36
+ * worksheet's `<c>` element: "n" (number, default), "str" (string), "b"
37
+ * (boolean), "e" (error). We don't emit shared-string indices here because
38
+ * the externalLink part is self-contained — each cached string is serialised
39
+ * inline as plain text inside `<v>`.
40
+ *
41
+ * Parser state machine:
42
+ * externalLink → externalBook → sheetNames → sheetName (stores names in order)
43
+ * \→ sheetDataSet → sheetData → row → cell → v (values)
44
+ *
45
+ * The parser tolerates missing cache data (Excel's `refreshError="1"` mode);
46
+ * sheets without a matching `<sheetData>` simply have no entry in
47
+ * `cachedValues`.
48
+ */
49
+ import type { ExternalLinkCachedSheet, ExternalLinkModel } from "../../../workbook.browser.js";
50
+ import { BaseXform } from "../base-xform.js";
51
+ import type { XmlSink } from "../../../../xml/types.js";
52
+ /**
53
+ * Parsed shape of a single externalLinkN.xml part. Callers (xlsx.browser.ts)
54
+ * merge `rId` with the matching `workbookRels` entry to recover the model's
55
+ * `target` / `targetMode`, since those live in the sibling `.rels` file.
56
+ */
57
+ export interface ParsedExternalLink {
58
+ /** r:id on <externalBook>. Points at the rel inside externalLinkN.xml.rels. */
59
+ externalBookRId: string;
60
+ sheetNames: string[];
61
+ cachedValues: Record<string, ExternalLinkCachedSheet>;
62
+ }
63
+ declare class ExternalLinkXform extends BaseXform<ParsedExternalLink> {
64
+ /** Sheet name indexed by sheetId (0-based) — filled during parse. */
65
+ private sheetNamesByIndex;
66
+ /** Current sheet's accumulated cached cells. */
67
+ private currentSheetCells;
68
+ /** Current sheet's name (looked up from sheetId). */
69
+ private currentSheetName;
70
+ /** Current cell being parsed: address + type. */
71
+ private currentCellAddress;
72
+ private currentCellType;
73
+ /** Accumulated text content of the current <v> element. */
74
+ private currentCellValue;
75
+ /** Which element we're currently inside. */
76
+ private inV;
77
+ get tag(): string;
78
+ reset(): void;
79
+ render(xmlStream: XmlSink, model: ExternalLinkModel): void;
80
+ parseOpen(node: any): boolean;
81
+ parseText(text: string): void;
82
+ parseClose(name: string): boolean;
83
+ }
84
+ export { ExternalLinkXform };
@@ -0,0 +1,330 @@
1
+ /**
2
+ * ExternalLinkXform — read and write `xl/externalLinks/externalLinkN.xml`.
3
+ *
4
+ * This part describes one external workbook referenced by the current file:
5
+ * the list of sheets inside the foreign workbook, plus an optional cache of
6
+ * the primitive values at each referenced address. The `r:id` attribute on
7
+ * `<externalBook>` points (via the neighbouring `_rels/externalLinkN.xml.rels`)
8
+ * at the actual file; that resolution is handled by the writer/reader in
9
+ * `xlsx.browser.ts`, not here.
10
+ *
11
+ * Schema shape:
12
+ *
13
+ * <externalLink xmlns=".../spreadsheetml/2006/main"
14
+ * xmlns:r=".../relationships">
15
+ * <externalBook r:id="rId1">
16
+ * <sheetNames>
17
+ * <sheetName val="Sheet1"/>
18
+ * <sheetName val="Sheet2"/>
19
+ * </sheetNames>
20
+ * <sheetDataSet>
21
+ * <sheetData sheetId="0"> (0-based index into sheetNames)
22
+ * <row r="1">
23
+ * <cell r="A1" t="n"><v>123</v></cell>
24
+ * <cell r="B1" t="str"><v>hello</v></cell>
25
+ * </row>
26
+ * <row r="2">
27
+ * <cell r="A2" t="b"><v>1</v></cell>
28
+ * </row>
29
+ * </sheetData>
30
+ * <sheetData sheetId="1" refreshError="1"/> (no cached values)
31
+ * </sheetDataSet>
32
+ * </externalBook>
33
+ * </externalLink>
34
+ *
35
+ * The `t` attribute on `<cell>` mirrors the inline-value types used inside a
36
+ * worksheet's `<c>` element: "n" (number, default), "str" (string), "b"
37
+ * (boolean), "e" (error). We don't emit shared-string indices here because
38
+ * the externalLink part is self-contained — each cached string is serialised
39
+ * inline as plain text inside `<v>`.
40
+ *
41
+ * Parser state machine:
42
+ * externalLink → externalBook → sheetNames → sheetName (stores names in order)
43
+ * \→ sheetDataSet → sheetData → row → cell → v (values)
44
+ *
45
+ * The parser tolerates missing cache data (Excel's `refreshError="1"` mode);
46
+ * sheets without a matching `<sheetData>` simply have no entry in
47
+ * `cachedValues`.
48
+ */
49
+ import { BaseXform } from "../base-xform.js";
50
+ import { StdDocAttributes } from "../../../../xml/writer.js";
51
+ const NAMESPACE = "http://schemas.openxmlformats.org/spreadsheetml/2006/main";
52
+ const R_NAMESPACE = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
53
+ /** Pretty attribute constant used on the root element. */
54
+ const ROOT_ATTRIBUTES = { xmlns: NAMESPACE, "xmlns:r": R_NAMESPACE };
55
+ class ExternalLinkXform extends BaseXform {
56
+ constructor() {
57
+ super(...arguments);
58
+ /** Sheet name indexed by sheetId (0-based) — filled during parse. */
59
+ this.sheetNamesByIndex = [];
60
+ /** Current sheet's accumulated cached cells. */
61
+ this.currentSheetCells = null;
62
+ /** Current sheet's name (looked up from sheetId). */
63
+ this.currentSheetName = null;
64
+ /** Current cell being parsed: address + type. */
65
+ this.currentCellAddress = null;
66
+ this.currentCellType = "n";
67
+ /** Accumulated text content of the current <v> element. */
68
+ this.currentCellValue = null;
69
+ /** Which element we're currently inside. */
70
+ this.inV = false;
71
+ }
72
+ get tag() {
73
+ return "externalLink";
74
+ }
75
+ reset() {
76
+ super.reset();
77
+ this.sheetNamesByIndex = [];
78
+ this.currentSheetCells = null;
79
+ this.currentSheetName = null;
80
+ this.currentCellAddress = null;
81
+ this.currentCellType = "n";
82
+ this.currentCellValue = null;
83
+ this.inV = false;
84
+ }
85
+ // ==========================================================================
86
+ // Rendering
87
+ // ==========================================================================
88
+ render(xmlStream, model) {
89
+ xmlStream.openXml(StdDocAttributes);
90
+ xmlStream.openNode("externalLink", ROOT_ATTRIBUTES);
91
+ // We always use "rId1" for the externalBook ref — the externalLinkN.rels
92
+ // file only ever has a single relationship (the externalLinkPath one).
93
+ xmlStream.openNode("externalBook", { "r:id": "rId1" });
94
+ if (model.sheetNames.length > 0) {
95
+ xmlStream.openNode("sheetNames");
96
+ for (const name of model.sheetNames) {
97
+ xmlStream.leafNode("sheetName", { val: name });
98
+ }
99
+ xmlStream.closeNode();
100
+ }
101
+ // Emit cached values when supplied. We must always emit <sheetDataSet>
102
+ // if any sheet has cached values — it's fine to omit when none do.
103
+ const cache = model.cachedValues ?? {};
104
+ const hasAnyCache = Object.keys(cache).some(name => {
105
+ const sheet = cache[name];
106
+ return sheet && Object.keys(sheet).length > 0;
107
+ });
108
+ if (hasAnyCache) {
109
+ xmlStream.openNode("sheetDataSet");
110
+ // Iterate in sheetNames order so sheetId indices are stable.
111
+ for (let i = 0; i < model.sheetNames.length; i++) {
112
+ const sheetName = model.sheetNames[i];
113
+ const cells = cache[sheetName];
114
+ if (!cells || Object.keys(cells).length === 0) {
115
+ continue;
116
+ }
117
+ renderSheetData(xmlStream, i, cells);
118
+ }
119
+ xmlStream.closeNode();
120
+ }
121
+ xmlStream.closeNode(); // </externalBook>
122
+ xmlStream.closeNode(); // </externalLink>
123
+ }
124
+ // ==========================================================================
125
+ // Parsing
126
+ // ==========================================================================
127
+ parseOpen(node) {
128
+ const name = node.name;
129
+ switch (name) {
130
+ case "externalLink":
131
+ this.model = {
132
+ externalBookRId: "",
133
+ sheetNames: [],
134
+ cachedValues: {}
135
+ };
136
+ this.sheetNamesByIndex = [];
137
+ return true;
138
+ case "externalBook":
139
+ if (this.model) {
140
+ this.model.externalBookRId = node.attributes["r:id"] ?? "";
141
+ }
142
+ return true;
143
+ case "sheetName":
144
+ if (this.model) {
145
+ const val = node.attributes.val ?? "";
146
+ this.model.sheetNames.push(val);
147
+ this.sheetNamesByIndex.push(val);
148
+ }
149
+ return true;
150
+ case "sheetData": {
151
+ const sheetIdRaw = node.attributes.sheetId;
152
+ const sheetId = sheetIdRaw !== undefined ? parseInt(sheetIdRaw, 10) : NaN;
153
+ this.currentSheetName = Number.isFinite(sheetId)
154
+ ? (this.sheetNamesByIndex[sheetId] ?? null)
155
+ : null;
156
+ this.currentSheetCells = this.currentSheetName ? {} : null;
157
+ return true;
158
+ }
159
+ case "cell":
160
+ this.currentCellAddress = node.attributes.r ?? null;
161
+ this.currentCellType = node.attributes.t ?? "n";
162
+ this.currentCellValue = null;
163
+ return true;
164
+ case "v":
165
+ this.inV = true;
166
+ this.currentCellValue = "";
167
+ return true;
168
+ default:
169
+ return false;
170
+ }
171
+ }
172
+ parseText(text) {
173
+ if (this.inV) {
174
+ this.currentCellValue = (this.currentCellValue ?? "") + text;
175
+ }
176
+ }
177
+ parseClose(name) {
178
+ switch (name) {
179
+ case "v":
180
+ this.inV = false;
181
+ return true;
182
+ case "cell":
183
+ if (this.model && this.currentSheetCells && this.currentCellAddress) {
184
+ this.currentSheetCells[this.currentCellAddress.toUpperCase()] = decodePrimitive(this.currentCellType, this.currentCellValue);
185
+ }
186
+ this.currentCellAddress = null;
187
+ this.currentCellType = "n";
188
+ this.currentCellValue = null;
189
+ return true;
190
+ case "sheetData":
191
+ if (this.model &&
192
+ this.currentSheetName &&
193
+ this.currentSheetCells &&
194
+ Object.keys(this.currentSheetCells).length > 0) {
195
+ this.model.cachedValues[this.currentSheetName] = this.currentSheetCells;
196
+ }
197
+ this.currentSheetName = null;
198
+ this.currentSheetCells = null;
199
+ return true;
200
+ case "externalLink":
201
+ // Document root closed — stop parsing
202
+ return false;
203
+ default:
204
+ return true;
205
+ }
206
+ }
207
+ }
208
+ // ==========================================================================
209
+ // Serialisation helpers
210
+ // ==========================================================================
211
+ function renderSheetData(xmlStream, sheetIdx, cells) {
212
+ // Group cells by row so the XML tree is well-formed. Excel tolerates any
213
+ // ordering, but grouping by row matches the schema contract and keeps the
214
+ // output stable for diffing.
215
+ const rows = groupByRow(cells);
216
+ xmlStream.openNode("sheetData", { sheetId: sheetIdx });
217
+ for (const row of rows) {
218
+ xmlStream.openNode("row", { r: row.rowNum });
219
+ for (const { address, value } of row.cells) {
220
+ renderCell(xmlStream, address, value);
221
+ }
222
+ xmlStream.closeNode();
223
+ }
224
+ xmlStream.closeNode();
225
+ }
226
+ function groupByRow(cells) {
227
+ const byRow = new Map();
228
+ for (const rawAddress of Object.keys(cells)) {
229
+ const address = rawAddress.toUpperCase();
230
+ const rowNum = extractRowNumber(address);
231
+ if (rowNum === undefined) {
232
+ // Addresses that don't match the A1 shape are skipped rather than
233
+ // corrupting the file. An address like "A1" or "$B$12" yields a valid
234
+ // row number; anything else would produce malformed XML.
235
+ continue;
236
+ }
237
+ let bucket = byRow.get(rowNum);
238
+ if (!bucket) {
239
+ bucket = { rowNum, cells: [] };
240
+ byRow.set(rowNum, bucket);
241
+ }
242
+ bucket.cells.push({ address: stripAbsoluteMarkers(address), value: cells[rawAddress] });
243
+ }
244
+ return [...byRow.values()].sort((a, b) => a.rowNum - b.rowNum);
245
+ }
246
+ function extractRowNumber(address) {
247
+ // Strip leading $ and column letters, keep trailing digits.
248
+ const match = /^\$?[A-Z]+\$?(\d+)$/.exec(address);
249
+ return match ? parseInt(match[1], 10) : undefined;
250
+ }
251
+ function stripAbsoluteMarkers(address) {
252
+ return address.replace(/\$/g, "");
253
+ }
254
+ function renderCell(xmlStream, address, value) {
255
+ if (value === null || value === undefined) {
256
+ // An explicit blank — emit the address with no type/value so Excel shows
257
+ // an empty cell when displaying cached values.
258
+ xmlStream.leafNode("cell", { r: address });
259
+ return;
260
+ }
261
+ if (typeof value === "number") {
262
+ xmlStream.openNode("cell", { r: address });
263
+ xmlStream.leafNode("v", undefined, String(value));
264
+ xmlStream.closeNode();
265
+ return;
266
+ }
267
+ if (typeof value === "boolean") {
268
+ xmlStream.openNode("cell", { r: address, t: "b" });
269
+ xmlStream.leafNode("v", undefined, value ? "1" : "0");
270
+ xmlStream.closeNode();
271
+ return;
272
+ }
273
+ // Error values like "#DIV/0!", "#REF!", "#N/A" etc. are stored as t="e".
274
+ // Detect them so the round-trip preserves the type correctly (otherwise
275
+ // Excel would display the error literal as a plain string).
276
+ if (isErrorLiteral(value)) {
277
+ xmlStream.openNode("cell", { r: address, t: "e" });
278
+ xmlStream.leafNode("v", undefined, value);
279
+ xmlStream.closeNode();
280
+ return;
281
+ }
282
+ // String — emit t="str" with the text inside <v>.
283
+ xmlStream.openNode("cell", { r: address, t: "str" });
284
+ xmlStream.leafNode("v", undefined, value);
285
+ xmlStream.closeNode();
286
+ }
287
+ // ==========================================================================
288
+ // Deserialisation helpers
289
+ // ==========================================================================
290
+ /** Excel error literals that should be written with `t="e"`. */
291
+ const ERROR_LITERALS = new Set([
292
+ "#NULL!",
293
+ "#DIV/0!",
294
+ "#VALUE!",
295
+ "#REF!",
296
+ "#NAME?",
297
+ "#NUM!",
298
+ "#N/A",
299
+ "#GETTING_DATA",
300
+ "#SPILL!",
301
+ "#CALC!",
302
+ "#CONNECT!",
303
+ "#BLOCKED!",
304
+ "#UNKNOWN!",
305
+ "#FIELD!",
306
+ "#PYTHON!"
307
+ ]);
308
+ function isErrorLiteral(value) {
309
+ return ERROR_LITERALS.has(value);
310
+ }
311
+ function decodePrimitive(type, raw) {
312
+ if (raw === null || raw === "") {
313
+ return null;
314
+ }
315
+ switch (type) {
316
+ case "b":
317
+ return raw !== "0" && raw.toLowerCase() !== "false";
318
+ case "e":
319
+ // Preserve the error literal as a string — consumers can match on it.
320
+ return raw;
321
+ case "str":
322
+ return raw;
323
+ case "n":
324
+ default: {
325
+ const n = Number(raw);
326
+ return Number.isFinite(n) ? n : raw;
327
+ }
328
+ }
329
+ }
330
+ export { ExternalLinkXform };
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Xform for a single `<externalReference r:id="..."/>` element inside
3
+ * `<externalReferences>` in `xl/workbook.xml`. Each `<externalReference>`
4
+ * maps positionally (in document order, 1-based) to an `[N]Sheet!Ref`
5
+ * prefix in formula strings.
6
+ */
7
+ import { BaseXform } from "../base-xform.js";
8
+ export interface ExternalReferenceModel {
9
+ rId: string;
10
+ }
11
+ declare class ExternalReferenceXform extends BaseXform<ExternalReferenceModel> {
12
+ render(xmlStream: any, model: ExternalReferenceModel): void;
13
+ parseOpen(node: any): boolean;
14
+ parseText(): void;
15
+ parseClose(): boolean;
16
+ }
17
+ export { ExternalReferenceXform };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Xform for a single `<externalReference r:id="..."/>` element inside
3
+ * `<externalReferences>` in `xl/workbook.xml`. Each `<externalReference>`
4
+ * maps positionally (in document order, 1-based) to an `[N]Sheet!Ref`
5
+ * prefix in formula strings.
6
+ */
7
+ import { BaseXform } from "../base-xform.js";
8
+ class ExternalReferenceXform extends BaseXform {
9
+ render(xmlStream, model) {
10
+ xmlStream.leafNode("externalReference", { "r:id": model.rId });
11
+ }
12
+ parseOpen(node) {
13
+ if (node.name === "externalReference") {
14
+ this.model = { rId: node.attributes["r:id"] ?? "" };
15
+ return true;
16
+ }
17
+ return false;
18
+ }
19
+ parseText() { }
20
+ parseClose() {
21
+ return false;
22
+ }
23
+ }
24
+ export { ExternalReferenceXform };
@@ -1,6 +1,9 @@
1
1
  import { BaseXform } from "../base-xform.js";
2
2
  interface CalcPropertiesModel {
3
3
  fullCalcOnLoad?: boolean;
4
+ iterate?: boolean;
5
+ iterateCount?: number;
6
+ iterateDelta?: number;
4
7
  }
5
8
  declare class WorkbookCalcPropertiesXform extends BaseXform {
6
9
  render(xmlStream: any, model: CalcPropertiesModel): void;
@@ -3,12 +3,21 @@ class WorkbookCalcPropertiesXform extends BaseXform {
3
3
  render(xmlStream, model) {
4
4
  xmlStream.leafNode("calcPr", {
5
5
  calcId: 171027,
6
- fullCalcOnLoad: model.fullCalcOnLoad ? 1 : undefined
6
+ fullCalcOnLoad: model.fullCalcOnLoad ? 1 : undefined,
7
+ iterate: model.iterate ? 1 : undefined,
8
+ iterateCount: model.iterateCount !== undefined ? model.iterateCount : undefined,
9
+ iterateDelta: model.iterateDelta !== undefined ? model.iterateDelta : undefined
7
10
  });
8
11
  }
9
12
  parseOpen(node) {
10
13
  if (node.name === "calcPr") {
11
- this.model = {};
14
+ const attrs = node.attributes ?? {};
15
+ this.model = {
16
+ fullCalcOnLoad: attrs.fullCalcOnLoad === "1",
17
+ iterate: attrs.iterate === "1" ? true : undefined,
18
+ iterateCount: attrs.iterateCount !== undefined ? parseInt(attrs.iterateCount, 10) : undefined,
19
+ iterateDelta: attrs.iterateDelta !== undefined ? parseFloat(attrs.iterateDelta) : undefined
20
+ };
12
21
  return true;
13
22
  }
14
23
  return false;
@@ -0,0 +1,20 @@
1
+ import { BaseXform } from "../base-xform.js";
2
+ interface WorkbookProtectionModel {
3
+ lockStructure?: boolean;
4
+ lockWindows?: boolean;
5
+ lockRevision?: boolean;
6
+ workbookPassword?: string;
7
+ revisionsPassword?: string;
8
+ algorithmName?: string;
9
+ hashValue?: string;
10
+ saltValue?: string;
11
+ spinCount?: number;
12
+ }
13
+ declare class WorkbookProtectionXform extends BaseXform {
14
+ get tag(): string;
15
+ render(xmlStream: any, model?: WorkbookProtectionModel): void;
16
+ parseOpen(node: any): boolean;
17
+ parseText(): void;
18
+ parseClose(): boolean;
19
+ }
20
+ export { WorkbookProtectionXform };