@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
@@ -18,12 +18,14 @@ const drawing_utils_1 = require("../utils/drawing-utils.js");
18
18
  const ooxml_paths_1 = require("../utils/ooxml-paths.js");
19
19
  const shared_strings_1 = require("../utils/shared-strings.js");
20
20
  const stream_buf_1 = require("../utils/stream-buf.js");
21
+ const workbook_protection_1 = require("../utils/workbook-protection.js");
21
22
  const rel_type_1 = require("../xlsx/rel-type.js");
22
23
  const workbook_xform_1 = require("../xlsx/xform/book/workbook-xform.js");
23
24
  const app_xform_1 = require("../xlsx/xform/core/app-xform.js");
24
25
  const content_types_xform_1 = require("../xlsx/xform/core/content-types-xform.js");
25
26
  const core_xform_1 = require("../xlsx/xform/core/core-xform.js");
26
27
  const feature_property_bag_xform_1 = require("../xlsx/xform/core/feature-property-bag-xform.js");
28
+ const metadata_xform_1 = require("../xlsx/xform/core/metadata-xform.js");
27
29
  const relationships_xform_1 = require("../xlsx/xform/core/relationships-xform.js");
28
30
  const drawing_xform_1 = require("../xlsx/xform/drawing/drawing-xform.js");
29
31
  const shared_strings_xform_1 = require("../xlsx/xform/strings/shared-strings-xform.js");
@@ -56,6 +58,7 @@ class WorkbookWriterBase {
56
58
  this.compressionLevel = Math.max(0, Math.min(9, level));
57
59
  this.media = [];
58
60
  this.commentRefs = [];
61
+ this.dynamicArrayCount = 0;
59
62
  this._trueStreaming = options.trueStreaming ?? false;
60
63
  // Create Zip instance
61
64
  this.zip = new stream_1.Zip((err, data, final) => {
@@ -90,6 +93,18 @@ class WorkbookWriterBase {
90
93
  get definedNames() {
91
94
  return this._definedNames;
92
95
  }
96
+ /**
97
+ * The default font for the workbook (fontId=0 / "Normal" style).
98
+ * Must be set before any worksheet rows are committed.
99
+ */
100
+ get defaultFont() {
101
+ return this.styles.defaultFont;
102
+ }
103
+ set defaultFont(font) {
104
+ if (this.styles.setDefaultFont) {
105
+ this.styles.setDefaultFont(font);
106
+ }
107
+ }
93
108
  /** @internal */
94
109
  _openStream(path) {
95
110
  const stream = new stream_buf_1.StreamBuf({
@@ -150,6 +165,7 @@ class WorkbookWriterBase {
150
165
  this.addSharedStrings(),
151
166
  this.addStyles(),
152
167
  this.addFeaturePropertyBag(),
168
+ this.addMetadata(),
153
169
  this.addWorkbookRels()
154
170
  ]);
155
171
  await this.addWorkbook();
@@ -176,6 +192,19 @@ class WorkbookWriterBase {
176
192
  getImage(id) {
177
193
  return this.media[id];
178
194
  }
195
+ /**
196
+ * Protect the workbook structure with an optional password.
197
+ * Prevents users from adding, deleting, renaming, moving, or copying worksheets.
198
+ */
199
+ async protect(password, options) {
200
+ this.protection = await (0, workbook_protection_1.buildWorkbookProtection)(password, options);
201
+ }
202
+ /**
203
+ * Remove workbook structure protection.
204
+ */
205
+ unprotect() {
206
+ this.protection = undefined;
207
+ }
179
208
  addWorksheet(name, options) {
180
209
  const opts = options || {};
181
210
  const useSharedStrings = opts.useSharedStrings !== undefined ? opts.useSharedStrings : this.useSharedStrings;
@@ -253,7 +282,8 @@ class WorkbookWriterBase {
253
282
  commentRefs: this.commentRefs,
254
283
  media: this.media,
255
284
  drawings,
256
- hasCheckboxes: this.styles.hasCheckboxes
285
+ hasCheckboxes: this.styles.hasCheckboxes,
286
+ hasDynamicArrayFormulas: this.dynamicArrayCount > 0
257
287
  };
258
288
  const xform = new content_types_xform_1.ContentTypesXform();
259
289
  this._addFile(xform.toXml(model), ooxml_paths_1.OOXML_PATHS.contentTypes);
@@ -339,6 +369,14 @@ class WorkbookWriterBase {
339
369
  }
340
370
  return Promise.resolve();
341
371
  }
372
+ addMetadata() {
373
+ if (this.dynamicArrayCount <= 0) {
374
+ return Promise.resolve();
375
+ }
376
+ const xform = new metadata_xform_1.MetadataXform();
377
+ this._addFile(xform.toXml({ dynamicArrayCount: this.dynamicArrayCount }), ooxml_paths_1.OOXML_PATHS.xlMetadata);
378
+ return Promise.resolve();
379
+ }
342
380
  addWorkbookRels() {
343
381
  let count = 1;
344
382
  const relationships = [
@@ -360,6 +398,14 @@ class WorkbookWriterBase {
360
398
  Target: ooxml_paths_1.OOXML_REL_TARGETS.workbookFeaturePropertyBag
361
399
  });
362
400
  }
401
+ // Add metadata relationship for dynamic array formulas
402
+ if (this.dynamicArrayCount > 0) {
403
+ relationships.push({
404
+ Id: `rId${count++}`,
405
+ Type: rel_type_1.RelType.SheetMetadata,
406
+ Target: ooxml_paths_1.OOXML_REL_TARGETS.workbookMetadata
407
+ });
408
+ }
363
409
  this._worksheets.forEach(ws => {
364
410
  if (ws) {
365
411
  ws.rId = `rId${count++}`;
@@ -382,6 +428,7 @@ class WorkbookWriterBase {
382
428
  definedNames: this._definedNames.model,
383
429
  views: this.views,
384
430
  properties: {},
431
+ protection: this.protection,
385
432
  calcProperties: {}
386
433
  };
387
434
  return new Promise(resolve => {
@@ -190,10 +190,12 @@ class WorksheetReader extends event_emitter_1.EventEmitter {
190
190
  case "c":
191
191
  if (row) {
192
192
  const styleAttr = node.attributes.s;
193
+ const cmAttr = node.attributes.cm;
193
194
  c = {
194
195
  ref: node.attributes.r,
195
196
  s: styleAttr !== undefined ? parseInt(styleAttr, 10) : undefined,
196
- t: node.attributes.t
197
+ t: node.attributes.t,
198
+ cm: cmAttr !== undefined ? parseInt(cmAttr, 10) : undefined
197
199
  };
198
200
  }
199
201
  break;
@@ -298,6 +300,20 @@ class WorksheetReader extends event_emitter_1.EventEmitter {
298
300
  cellValue.result = parseFloat(c.v.text);
299
301
  }
300
302
  }
303
+ // Check if this cell is a dynamic array formula via cm → metadata mapping.
304
+ // Uses the precise dynamicArrayCmIndices set from WorkbookReaderBase,
305
+ // falling back to the coarser hasDynamicArrayMetadata boolean.
306
+ if (c.cm !== undefined) {
307
+ const { workbook: wb } = this;
308
+ if (wb.dynamicArrayCmIndices) {
309
+ if (wb.dynamicArrayCmIndices.has(c.cm)) {
310
+ cellValue.isDynamicArray = true;
311
+ }
312
+ }
313
+ else if (wb.hasDynamicArrayMetadata) {
314
+ cellValue.isDynamicArray = true;
315
+ }
316
+ }
301
317
  cell.value = cellValue;
302
318
  }
303
319
  else if (c.v) {
@@ -29,6 +29,7 @@ const drawing_xform_1 = require("../xlsx/xform/sheet/drawing-xform.js");
29
29
  const ext_lst_xform_1 = require("../xlsx/xform/sheet/ext-lst-xform.js");
30
30
  const header_footer_xform_1 = require("../xlsx/xform/sheet/header-footer-xform.js");
31
31
  const hyperlink_xform_1 = require("../xlsx/xform/sheet/hyperlink-xform.js");
32
+ const ignored_errors_xform_1 = require("../xlsx/xform/sheet/ignored-errors-xform.js");
32
33
  const page_margins_xform_1 = require("../xlsx/xform/sheet/page-margins-xform.js");
33
34
  const page_setup_xform_1 = require("../xlsx/xform/sheet/page-setup-xform.js");
34
35
  const picture_xform_1 = require("../xlsx/xform/sheet/picture-xform.js");
@@ -63,6 +64,7 @@ const xform = {
63
64
  drawing: new drawing_xform_1.DrawingXform(),
64
65
  conditionalFormattings: new conditional_formattings_xform_1.ConditionalFormattingsXform(),
65
66
  extLst: new ext_lst_xform_1.ExtLstXform(),
67
+ ignoredErrors: new ignored_errors_xform_1.IgnoredErrorsXform(),
66
68
  headerFooter: new header_footer_xform_1.HeaderFooterXform(),
67
69
  rowBreaks: new row_breaks_xform_1.RowBreaksXform(),
68
70
  colBreaks: new col_breaks_xform_1.ColBreaksXform()
@@ -103,6 +105,8 @@ class WorksheetWriter {
103
105
  this._siFormulae = 0;
104
106
  // keep a record of conditionalFormattings
105
107
  this.conditionalFormatting = [];
108
+ // ignored errors (suppress green triangles in Excel)
109
+ this.ignoredErrors = [];
106
110
  // keep a record of all row and column pageBreaks
107
111
  this.rowBreaks = [];
108
112
  this.colBreaks = [];
@@ -215,6 +219,8 @@ class WorksheetWriter {
215
219
  this._writeBackground(); // Note: must be after drawing
216
220
  // Legacy Data tag for comments
217
221
  this._writeLegacyData();
222
+ // ignoredErrors must be before extLst
223
+ this._writeIgnoredErrors();
218
224
  // extLst must be the last child element before </worksheet>
219
225
  this._writeExtLst();
220
226
  this._writeCloseWorksheet();
@@ -532,18 +538,33 @@ class WorksheetWriter {
532
538
  }
533
539
  throw new Error(`Invalid image range: "${range}". Expected a range like "A1:C3".`);
534
540
  }
535
- const tl = new anchor_1.Anchor(this, range.tl, 0).model;
536
- const br = range.br ? new anchor_1.Anchor(this, range.br, 0).model : undefined;
541
+ // Absolute positioning (pos + ext, no cell anchors)
542
+ if ("pos" in range && range.pos) {
543
+ return {
544
+ type: "image",
545
+ imageId,
546
+ range: {
547
+ tl: { nativeCol: 0, nativeColOff: 0, nativeRow: 0, nativeRowOff: 0 },
548
+ ext: range.ext,
549
+ pos: range.pos
550
+ },
551
+ hyperlinks: range.hyperlinks
552
+ };
553
+ }
554
+ // Cell-based positioning (tl/br anchors)
555
+ const cellRange = range;
556
+ const tl = new anchor_1.Anchor(this, cellRange.tl, 0).model;
557
+ const br = cellRange.br ? new anchor_1.Anchor(this, cellRange.br, 0).model : undefined;
537
558
  return {
538
559
  type: "image",
539
560
  imageId,
540
561
  range: {
541
562
  tl,
542
563
  br,
543
- ext: range.ext,
544
- editAs: range.editAs
564
+ ext: cellRange.ext,
565
+ editAs: cellRange.editAs
545
566
  },
546
- hyperlinks: range.hyperlinks
567
+ hyperlinks: cellRange.hyperlinks
547
568
  };
548
569
  }
549
570
  // =========================================================================
@@ -620,6 +641,9 @@ class WorksheetWriter {
620
641
  }
621
642
  if (row.hasValues || row.height != null) {
622
643
  const { model } = row;
644
+ if (!model) {
645
+ return;
646
+ }
623
647
  const options = {
624
648
  styles: this._workbook.styles,
625
649
  sharedStrings: this.useSharedStrings ? this._workbook.sharedStrings : undefined,
@@ -631,6 +655,14 @@ class WorksheetWriter {
631
655
  };
632
656
  xform.row.prepare(model, options);
633
657
  this.stream.write(xform.row.toXml(model));
658
+ // Count dynamic array formula cells for metadata generation
659
+ if (model.cells) {
660
+ for (const cell of model.cells) {
661
+ if (cell && cell.isDynamicArray) {
662
+ this._workbook.dynamicArrayCount++;
663
+ }
664
+ }
665
+ }
634
666
  if (options.comments.length) {
635
667
  this.hasComments = true;
636
668
  this._sheetCommentsWriter.addComments(options.comments);
@@ -683,6 +715,11 @@ class WorksheetWriter {
683
715
  const model = { conditionalFormattings: this.conditionalFormatting };
684
716
  this.stream.write(xform.extLst.toXml(model));
685
717
  }
718
+ _writeIgnoredErrors() {
719
+ if (this.ignoredErrors.length > 0) {
720
+ this.stream.write(xform.ignoredErrors.toXml(this.ignoredErrors));
721
+ }
722
+ }
686
723
  _writeRowBreaks() {
687
724
  this.stream.write(xform.rowBreaks.toXml(this.rowBreaks));
688
725
  }
@@ -756,6 +793,9 @@ class WorksheetWriter {
756
793
  if (this._background) {
757
794
  if (this._background.imageId !== undefined) {
758
795
  const image = this._workbook.getImage(this._background.imageId);
796
+ if (!image) {
797
+ return;
798
+ }
759
799
  const pictureId = this._sheetRelsWriter.addMedia({
760
800
  Target: (0, ooxml_paths_1.mediaRelTargetFromRels)(image.name),
761
801
  Type: rel_type_1.RelType.Image
@@ -540,13 +540,26 @@ class Table {
540
540
  }
541
541
  }
542
542
  exports.Table = Table;
543
+ // SUBTOTAL function codes per OOXML/Excel:
544
+ // 1/101=AVERAGE, 2/102=COUNT, 3/103=COUNTA, 4/104=MAX, 5/105=MIN,
545
+ // 6/106=PRODUCT, 7/107=STDEV, 8/108=STDEVP, 9/109=SUM, 10/110=VAR, 11/111=VARP.
546
+ // The 1xx variants also ignore manually hidden rows — Excel always uses
547
+ // these for totals-row injection. OOXML totalsRowFunction names map to:
548
+ // average → 1 (AVERAGE)
549
+ // countNums → 2 (COUNT, numeric-only)
550
+ // count → 3 (COUNTA)
551
+ // max → 4
552
+ // min → 5
553
+ // stdDev → 7 (sample std dev, per Excel's totals UI)
554
+ // var → 10 (sample variance, per Excel's totals UI)
555
+ // sum → 9
543
556
  Table.SUBTOTAL_FUNCTIONS = {
544
557
  average: 101,
545
558
  countNums: 102,
546
559
  count: 103,
547
560
  max: 104,
548
561
  min: 105,
549
- stdDev: 106,
550
- var: 107,
562
+ stdDev: 107,
563
+ var: 110,
551
564
  sum: 109
552
565
  };
@@ -302,6 +302,21 @@ const colCache = {
302
302
  throw new errors_1.InvalidAddressError(String(args.length), "Can only encode with 2 or 4 arguments");
303
303
  }
304
304
  },
305
+ /**
306
+ * Compare two cell addresses by column then row (numeric order).
307
+ *
308
+ * Returns a negative number if `a` should come before `b`,
309
+ * a positive number if `a` should come after `b`, or zero if equal.
310
+ *
311
+ * This avoids the pitfalls of `localeCompare` which treats addresses
312
+ * as strings (e.g. "C10" < "C2") instead of comparing their numeric
313
+ * column and row components.
314
+ */
315
+ compareAddress(a, b) {
316
+ const addrA = colCache.decodeAddress(a);
317
+ const addrB = colCache.decodeAddress(b);
318
+ return addrA.col - addrB.col || addrA.row - addrB.row;
319
+ },
305
320
  // return true if address is contained within range
306
321
  inRange(range, address) {
307
322
  const [left, top, , right, bottom] = range;
@@ -106,6 +106,10 @@ function filterDrawingAnchors(anchors) {
106
106
  if (a == null) {
107
107
  return false;
108
108
  }
109
+ // Absolute anchors need a valid picture
110
+ if (a.range?.pos !== undefined) {
111
+ return !!a.picture;
112
+ }
109
113
  // Form controls have range.br and shape properties
110
114
  if (a.range?.br && a.shape) {
111
115
  return true;
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+ /**
3
+ * Utilities for manipulating the external-workbook prefix in formula strings.
4
+ *
5
+ * Excel formula strings containing external workbook references have the
6
+ * shape `[<workbook>]Sheet!Ref` where `<workbook>` is either
7
+ *
8
+ * - a 1-based numeric index — `[1]Sheet1!A1` (the canonical on-disk form
9
+ * stored inside `<f>` elements of worksheet XML), or
10
+ * - a filename / relative path — `[测试.xlsx]Sheet1!A1` (what Excel
11
+ * displays in the formula bar; not part of the OOXML storage contract,
12
+ * but produced by hand-written formulas and some older tools).
13
+ *
14
+ * When writing, excelts always emits the numeric form — indices map
15
+ * positionally into the workbook's `<externalReferences>` list. When a
16
+ * formula arrives with the filename form, the writer assigns (or reuses) an
17
+ * ExternalLinkModel with that filename as its `target` and rewrites the
18
+ * formula to the numeric form. This matches how Excel itself stores formulas
19
+ * and makes them round-trippable.
20
+ *
21
+ * The quoted variant `'[file.xlsx]Sheet with space'!A1` is handled too — Excel
22
+ * wraps the `[name]Sheet` segment in single quotes when the sheet name needs
23
+ * quoting. The matching logic here recognises both the unquoted and quoted
24
+ * forms, rewriting inside the quotes when needed.
25
+ *
26
+ * Edge cases we explicitly *do not* treat as external refs:
27
+ * - `[@Column]`, `[#Headers]`, `[Column Name]` — table structured refs
28
+ * (no `]Sheet!` tail). The regex requires the `]<sheet>!` follow-up,
29
+ * which structured refs never have.
30
+ * - Array literals `{1,2;3,4}` use `{}`, not `[]`.
31
+ * - String literals `"[Book]Sheet!A1"` — handled by scanning only outside
32
+ * string literal regions.
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.findExternalRefs = findExternalRefs;
36
+ exports.rewriteExternalRefs = rewriteExternalRefs;
37
+ // Matches an external-ref prefix in a formula:
38
+ // Group 1 captures the workbook token inside [...], which is either
39
+ // digits-only (numeric form) or a filename that may include path separators
40
+ // when the whole prefix is single-quoted.
41
+ //
42
+ // Two variants:
43
+ // 1. Unquoted: [Book]Sheet!A1 — Windows-filename-safe chars only in
44
+ // workbook token, then identifier sheet name, then !
45
+ // 2. Quoted: '[path/to/Book]Sheet name'!A1 — quoted segment allows
46
+ // paths / spaces / most punctuation inside the brackets; the sheet
47
+ // name inside the quotes can contain anything except `'` (escaped as '')
48
+ //
49
+ // The regex matches through and including the trailing `!` so callers don't
50
+ // have to re-parse the A1/range part.
51
+ // Unquoted form: workbook token must not contain characters that would
52
+ // make the formula string ambiguous ( ] / \ space). This matches what Excel
53
+ // itself writes for the bare-filename case — anything more exotic is
54
+ // written in the quoted form by Excel.
55
+ const UNQUOTED_EXTERNAL_REF = /\[([^\]\\/:*?"<>|\s]+)\]([A-Za-z_\u00A1-\uFFFF][A-Za-z0-9_\u00A1-\uFFFF.]*)!/g;
56
+ // Quoted form: everything inside [] is permissive (any char except `]`),
57
+ // since the outer `'..'` quotes absorb the surrounding formula
58
+ // delimiters. Sheet name inside quotes is likewise permissive (any char
59
+ // except `'`, with `''` representing an escaped quote).
60
+ const QUOTED_EXTERNAL_REF = /'\[([^\]]+)\]((?:''|[^'])+)'!/g;
61
+ /**
62
+ * Scan a formula string for all external-workbook references. String
63
+ * literals (inside `"..."`) are skipped so that a string value like
64
+ * `"[Book]Sheet!A1"` is not misidentified as a ref.
65
+ *
66
+ * The returned matches are in source order. If a formula contains no
67
+ * external refs, the array is empty.
68
+ */
69
+ function findExternalRefs(formula) {
70
+ // Fast-fail: external refs always include a `[`. Skipping the
71
+ // string-literal scan + two regex passes for plain cell refs (A1+B1,
72
+ // SUM(A1:A5), 99% of real workbooks) saves noticeable time on large
73
+ // sheets with thousands of formulas.
74
+ if (formula.indexOf("[") === -1) {
75
+ return [];
76
+ }
77
+ const matches = [];
78
+ const safeRegions = stringLiteralRegions(formula);
79
+ const addMatch = (start, end, workbook, sheet, quoted, match) => {
80
+ if (insideAnyRegion(start, safeRegions)) {
81
+ return;
82
+ }
83
+ const numeric = /^\d+$/.test(workbook);
84
+ matches.push({
85
+ match,
86
+ workbook,
87
+ numeric,
88
+ index: numeric ? parseInt(workbook, 10) : null,
89
+ sheet: unquoteSheetName(sheet),
90
+ quoted,
91
+ start,
92
+ end
93
+ });
94
+ };
95
+ UNQUOTED_EXTERNAL_REF.lastIndex = 0;
96
+ let m;
97
+ while ((m = UNQUOTED_EXTERNAL_REF.exec(formula)) !== null) {
98
+ addMatch(m.index, m.index + m[0].length, m[1], m[2], false, m[0]);
99
+ }
100
+ QUOTED_EXTERNAL_REF.lastIndex = 0;
101
+ while ((m = QUOTED_EXTERNAL_REF.exec(formula)) !== null) {
102
+ addMatch(m.index, m.index + m[0].length, m[1], m[2], true, m[0]);
103
+ }
104
+ // Sort matches by start offset so callers can process them in source
105
+ // order (needed when rewriting with offset bookkeeping).
106
+ matches.sort((a, b) => a.start - b.start);
107
+ // Deduplicate overlapping matches (the unquoted regex can technically
108
+ // match a prefix of a quoted sheet name in pathological inputs). Take
109
+ // the first of any overlap.
110
+ const out = [];
111
+ let lastEnd = -1;
112
+ for (const ref of matches) {
113
+ if (ref.start >= lastEnd) {
114
+ out.push(ref);
115
+ lastEnd = ref.end;
116
+ }
117
+ }
118
+ return out;
119
+ }
120
+ /**
121
+ * Replace every external-workbook token in `formula` using the supplied
122
+ * resolver. The resolver is called once per match and returns the numeric
123
+ * index to substitute; returning `null` leaves the match unchanged (useful
124
+ * when the caller cannot resolve a particular filename).
125
+ *
126
+ * Returns the rewritten formula. Offsets inside the original formula are
127
+ * adjusted correctly even when multiple rewrites change the total length.
128
+ */
129
+ function rewriteExternalRefs(formula, resolve) {
130
+ const refs = findExternalRefs(formula);
131
+ if (refs.length === 0) {
132
+ return formula;
133
+ }
134
+ let out = "";
135
+ let cursor = 0;
136
+ for (const ref of refs) {
137
+ const index = resolve(ref);
138
+ if (index === null) {
139
+ continue; // leave this ref alone; cursor stays put
140
+ }
141
+ out += formula.slice(cursor, ref.start);
142
+ // Construct the replacement: keep the quoted/unquoted shape, swap the
143
+ // workbook token for [N], preserve the sheet segment exactly.
144
+ if (ref.quoted) {
145
+ // The quoted variant surrounds `[Book]Sheet` with single quotes,
146
+ // followed by `!`. We swap the [Book] part for [N] and keep the
147
+ // rest (including the closing `'!`) unchanged so sheet-name
148
+ // quoting is preserved exactly.
149
+ const inner = formula.slice(ref.start + 1, ref.end - 2); // between quotes, excluding trailing '!
150
+ out += "'" + inner.replace(/^\[[^\]]*\]/, `[${index}]`) + "'!";
151
+ }
152
+ else {
153
+ out += `[${index}]${ref.match.slice(ref.match.indexOf("]") + 1)}`;
154
+ }
155
+ cursor = ref.end;
156
+ }
157
+ out += formula.slice(cursor);
158
+ return out;
159
+ }
160
+ // ===========================================================================
161
+ // Internal helpers
162
+ // ===========================================================================
163
+ /**
164
+ * Return the spans of string literal regions in a formula, as half-open
165
+ * [start, end) intervals (exclusive of the surrounding quotes themselves).
166
+ * Used to skip external-ref matches that fall inside a string value.
167
+ */
168
+ function stringLiteralRegions(formula) {
169
+ // Fast-fail when the formula has no double-quote at all — very common
170
+ // for pure arithmetic / reference formulas.
171
+ if (formula.indexOf('"') === -1) {
172
+ return [];
173
+ }
174
+ const regions = [];
175
+ const len = formula.length;
176
+ let i = 0;
177
+ while (i < len) {
178
+ if (formula[i] === '"') {
179
+ const start = i;
180
+ i++;
181
+ while (i < len) {
182
+ if (formula[i] === '"') {
183
+ if (i + 1 < len && formula[i + 1] === '"') {
184
+ i += 2; // escaped quote inside string — keep scanning
185
+ continue;
186
+ }
187
+ i++;
188
+ break;
189
+ }
190
+ i++;
191
+ }
192
+ regions.push([start, i]);
193
+ }
194
+ else {
195
+ i++;
196
+ }
197
+ }
198
+ return regions;
199
+ }
200
+ function insideAnyRegion(pos, regions) {
201
+ for (const [a, b] of regions) {
202
+ if (pos >= a && pos < b) {
203
+ return true;
204
+ }
205
+ }
206
+ return false;
207
+ }
208
+ function unquoteSheetName(sheet) {
209
+ // The quoted form captured inside `'..'` may have doubled single quotes
210
+ // that represent a single quote in the logical sheet name.
211
+ return sheet.replace(/''/g, "'");
212
+ }
@@ -42,7 +42,9 @@ async function* iterateStream(stream) {
42
42
  else {
43
43
  stream.pause();
44
44
  const data = contents.shift();
45
- yield data;
45
+ if (data !== undefined) {
46
+ yield data;
47
+ }
46
48
  }
47
49
  if (error) {
48
50
  throw (0, errors_1.toError)(error);
@@ -20,6 +20,8 @@ exports.getPivotTableNameFromRelsPath = getPivotTableNameFromRelsPath;
20
20
  exports.getPivotCacheDefinitionNameFromPath = getPivotCacheDefinitionNameFromPath;
21
21
  exports.getPivotCacheDefinitionNameFromRelsPath = getPivotCacheDefinitionNameFromRelsPath;
22
22
  exports.getPivotCacheRecordsNameFromPath = getPivotCacheRecordsNameFromPath;
23
+ exports.getExternalLinkIndexFromPath = getExternalLinkIndexFromPath;
24
+ exports.getExternalLinkIndexFromRelsPath = getExternalLinkIndexFromRelsPath;
23
25
  exports.toContentTypesPartName = toContentTypesPartName;
24
26
  exports.themePath = themePath;
25
27
  exports.mediaPath = mediaPath;
@@ -40,6 +42,9 @@ exports.pivotCacheRecordsPath = pivotCacheRecordsPath;
40
42
  exports.pivotCacheRecordsRelTarget = pivotCacheRecordsRelTarget;
41
43
  exports.pivotTablePath = pivotTablePath;
42
44
  exports.pivotTableRelsPath = pivotTableRelsPath;
45
+ exports.externalLinkPath = externalLinkPath;
46
+ exports.externalLinkRelsPath = externalLinkRelsPath;
47
+ exports.externalLinkRelTargetFromWorkbook = externalLinkRelTargetFromWorkbook;
43
48
  exports.pivotCacheDefinitionRelTargetFromPivotTable = pivotCacheDefinitionRelTargetFromPivotTable;
44
49
  exports.pivotCacheDefinitionRelTargetFromWorkbook = pivotCacheDefinitionRelTargetFromWorkbook;
45
50
  exports.commentsRelTargetFromWorksheet = commentsRelTargetFromWorksheet;
@@ -65,7 +70,8 @@ exports.OOXML_PATHS = {
65
70
  xlSharedStrings: "xl/sharedStrings.xml",
66
71
  xlStyles: "xl/styles.xml",
67
72
  xlTheme1: "xl/theme/theme1.xml",
68
- xlFeaturePropertyBag: "xl/featurePropertyBag/featurePropertyBag.xml"
73
+ xlFeaturePropertyBag: "xl/featurePropertyBag/featurePropertyBag.xml",
74
+ xlMetadata: "xl/metadata.xml"
69
75
  };
70
76
  const worksheetXmlRegex = /^xl\/worksheets\/sheet(\d+)[.]xml$/;
71
77
  const worksheetRelsXmlRegex = /^xl\/worksheets\/_rels\/sheet(\d+)[.]xml[.]rels$/;
@@ -82,6 +88,9 @@ const pivotTableRelsXmlRegex = /^xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.
82
88
  const pivotCacheDefinitionXmlRegex = /^xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml$/;
83
89
  const pivotCacheDefinitionRelsXmlRegex = /^xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels$/;
84
90
  const pivotCacheRecordsXmlRegex = /^xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml$/;
91
+ // External workbook links (xl/externalLinks/externalLink{n}.xml and its rels)
92
+ const externalLinkXmlRegex = /^xl\/externalLinks\/externalLink(\d+)[.]xml$/;
93
+ const externalLinkRelsXmlRegex = /^xl\/externalLinks\/_rels\/externalLink(\d+)[.]xml[.]rels$/;
85
94
  function normalizeZipPath(path) {
86
95
  return path.startsWith("/") ? path.slice(1) : path;
87
96
  }
@@ -162,6 +171,22 @@ function getPivotCacheRecordsNameFromPath(path) {
162
171
  const match = pivotCacheRecordsXmlRegex.exec(path);
163
172
  return match ? match[1] : undefined;
164
173
  }
174
+ /**
175
+ * Extract the 1-based index `N` from `xl/externalLinks/externalLink{N}.xml`.
176
+ * Returns the raw integer (e.g. `1` for externalLink1.xml) or undefined.
177
+ */
178
+ function getExternalLinkIndexFromPath(path) {
179
+ const match = externalLinkXmlRegex.exec(path);
180
+ return match ? parseInt(match[1], 10) : undefined;
181
+ }
182
+ /**
183
+ * Extract the 1-based index `N` from
184
+ * `xl/externalLinks/_rels/externalLink{N}.xml.rels`.
185
+ */
186
+ function getExternalLinkIndexFromRelsPath(path) {
187
+ const match = externalLinkRelsXmlRegex.exec(path);
188
+ return match ? parseInt(match[1], 10) : undefined;
189
+ }
165
190
  function toContentTypesPartName(zipPath) {
166
191
  // ContentTypes uses leading slash PartName (e.g. "/xl/workbook.xml").
167
192
  return zipPath.startsWith("/") ? zipPath : `/${zipPath}`;
@@ -224,6 +249,20 @@ function pivotTablePath(n) {
224
249
  function pivotTableRelsPath(n) {
225
250
  return `xl/pivotTables/_rels/pivotTable${n}.xml.rels`;
226
251
  }
252
+ // -------- External links --------
253
+ function externalLinkPath(n) {
254
+ return `xl/externalLinks/externalLink${n}.xml`;
255
+ }
256
+ function externalLinkRelsPath(n) {
257
+ return `xl/externalLinks/_rels/externalLink${n}.xml.rels`;
258
+ }
259
+ /**
260
+ * Build the `Target` value for an externalLink relationship inside
261
+ * `xl/_rels/workbook.xml.rels` (base: `xl/`).
262
+ */
263
+ function externalLinkRelTargetFromWorkbook(n) {
264
+ return `externalLinks/externalLink${n}.xml`;
265
+ }
227
266
  function pivotCacheDefinitionRelTargetFromPivotTable(n) {
228
267
  return `../pivotCache/pivotCacheDefinition${n}.xml`;
229
268
  }
@@ -232,7 +271,8 @@ exports.OOXML_REL_TARGETS = {
232
271
  workbookStyles: "styles.xml",
233
272
  workbookSharedStrings: "sharedStrings.xml",
234
273
  workbookTheme1: "theme/theme1.xml",
235
- workbookFeaturePropertyBag: "featurePropertyBag/featurePropertyBag.xml"
274
+ workbookFeaturePropertyBag: "featurePropertyBag/featurePropertyBag.xml",
275
+ workbookMetadata: "metadata.xml"
236
276
  };
237
277
  function pivotCacheDefinitionRelTargetFromWorkbook(n) {
238
278
  // Target inside xl/_rels/workbook.xml.rels (base: xl/)