@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,6 +1,24 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SharedStrings = void 0;
4
+ /**
5
+ * Canonical JSON serializer with sorted object keys.
6
+ *
7
+ * Used to derive an insertion-order-independent dedupe key for rich-text
8
+ * shared-string entries. Two semantically identical run/font objects must
9
+ * map to the same key regardless of the order their properties were assigned.
10
+ */
11
+ function canonicalStringify(value) {
12
+ if (value === null || typeof value !== "object") {
13
+ return JSON.stringify(value);
14
+ }
15
+ if (Array.isArray(value)) {
16
+ return `[${value.map(canonicalStringify).join(",")}]`;
17
+ }
18
+ const keys = Object.keys(value).sort();
19
+ const obj = value;
20
+ return `{${keys.map(k => `${JSON.stringify(k)}:${canonicalStringify(obj[k])}`).join(",")}}`;
21
+ }
4
22
  class SharedStrings {
5
23
  constructor() {
6
24
  this._values = [];
@@ -20,9 +38,10 @@ class SharedStrings {
20
38
  return this._values[index];
21
39
  }
22
40
  add(value) {
23
- let index = this._hash[value];
41
+ const key = typeof value === "string" ? `s:${value}` : `r:${canonicalStringify(value.richText)}`;
42
+ let index = this._hash[key];
24
43
  if (index === undefined) {
25
- index = this._hash[value] = this._values.length;
44
+ index = this._hash[key] = this._values.length;
26
45
  this._values.push(value);
27
46
  }
28
47
  this._totalRefs++;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildWorkbookProtection = buildWorkbookProtection;
4
+ const encryptor_1 = require("./encryptor.js");
5
+ const utils_1 = require("../../../utils/utils.js");
6
+ /**
7
+ * Build a workbook-protection object with optional password hashing.
8
+ *
9
+ * This is the shared implementation used by both `Workbook.protect()` and
10
+ * `WorkbookWriter.protect()`. The caller is responsible for assigning the
11
+ * result to its own `protection` field.
12
+ *
13
+ * @param password - Optional password to hash
14
+ * @param options - Optional protection flags (lockStructure, lockWindows, lockRevision, spinCount)
15
+ * @returns A fully-populated workbook-protection object
16
+ */
17
+ async function buildWorkbookProtection(password, options) {
18
+ const protection = {
19
+ lockStructure: options?.lockStructure ?? true,
20
+ lockWindows: options?.lockWindows,
21
+ lockRevision: options?.lockRevision
22
+ };
23
+ if (password) {
24
+ protection.algorithmName = "SHA-512";
25
+ protection.saltValue = (0, utils_1.uint8ArrayToBase64)(encryptor_1.Encryptor.randomBytes(16));
26
+ protection.spinCount =
27
+ options?.spinCount != null && Number.isFinite(options.spinCount)
28
+ ? Math.round(Math.max(0, options.spinCount))
29
+ : 100000;
30
+ protection.hashValue = await encryptor_1.Encryptor.convertPasswordToHash(password, "SHA-512", protection.saltValue, protection.spinCount);
31
+ }
32
+ return protection;
33
+ }
@@ -20,8 +20,10 @@ const defined_names_1 = require("./defined-names.js");
20
20
  const errors_1 = require("./errors.js");
21
21
  const workbook_reader_1 = require("./stream/workbook-reader.js");
22
22
  const workbook_writer_1 = require("./stream/workbook-writer.js");
23
+ const workbook_protection_1 = require("./utils/workbook-protection.js");
23
24
  const worksheet_1 = require("./worksheet.js");
24
25
  const xlsx_1 = require("./xlsx/xlsx.js");
26
+ const host_registry_1 = require("../formula/host-registry.js");
25
27
  const index_1 = require("../markdown/format/index.js");
26
28
  const index_2 = require("../markdown/parse/index.js");
27
29
  const _stream_1 = require("../stream/index.js");
@@ -73,48 +75,80 @@ function createDefaultValueMapper(dateFormats, options) {
73
75
  return datumNumber;
74
76
  }
75
77
  }
76
- const date = dateParser.parse(datum);
77
- if (date) {
78
- return date;
79
- }
80
- const special = SpecialValues[datum];
81
- if (special !== undefined) {
82
- return special;
78
+ if (typeof datum === "string") {
79
+ const date = dateParser.parse(datum);
80
+ if (date) {
81
+ return date;
82
+ }
83
+ const special = SpecialValues[datum];
84
+ if (special !== undefined) {
85
+ return special;
86
+ }
83
87
  }
84
88
  return datum;
85
89
  };
86
90
  }
87
91
  /**
88
92
  * Create a value mapper for writing Excel values to CSV format.
89
- * Handles hyperlinks, formulas, rich text, dates, errors, and objects.
93
+ *
94
+ * Branches below correspond to each member of the `CellValue` union, in an
95
+ * order that prefers the most specific shape:
96
+ * 1. Hyperlink — emit the URL (falling back to display text)
97
+ * 2. Formula / SharedFormula / ArrayFormula — emit the evaluated `result`
98
+ * 3. RichText — flatten runs to plain text
99
+ * 4. Checkbox — emit the boolean state
100
+ * 5. Error — emit the Excel error token (e.g. "#N/A")
101
+ * 6. Date — format via the configured DateFormatter
102
+ * 7. Primitive — pass through (`string | number | boolean | null | undefined`)
103
+ *
104
+ * An object that does not match any of the above is stringified as JSON so
105
+ * the CSV remains round-trippable rather than producing `[object Object]`.
90
106
  */
91
107
  function createDefaultWriteMapper(dateFormat, dateUTC) {
92
108
  const formatter = dateFormat
93
109
  ? datetime_1.DateFormatter.create(dateFormat, { utc: dateUTC })
94
110
  : datetime_1.DateFormatter.iso(dateUTC);
95
111
  return function mapValue(value) {
96
- if (value) {
97
- if (value.text || value.hyperlink) {
98
- return value.hyperlink || value.text || "";
99
- }
100
- if (value.formula || value.result) {
101
- return value.result || "";
102
- }
103
- // Handle rich text - extract and concatenate all text fragments
104
- if (value.richText && Array.isArray(value.richText)) {
105
- return value.richText.map((r) => r.text).join("");
106
- }
107
- if (value instanceof Date) {
108
- return formatter.format(value);
109
- }
110
- if (value.error) {
111
- return value.error;
112
- }
113
- if (typeof value === "object") {
114
- return JSON.stringify(value);
115
- }
112
+ if (value === null || value === undefined) {
113
+ return value;
114
+ }
115
+ if (value instanceof Date) {
116
+ return formatter.format(value);
117
+ }
118
+ if (typeof value !== "object") {
119
+ // string | number | boolean
120
+ return value;
121
+ }
122
+ // --- Object variants of CellValue ---
123
+ // Hyperlink: prefer URL, fall back to display text.
124
+ // Accepts objects carrying either `hyperlink` or just `text` — the latter
125
+ // is a historical input shape some callers use to denote a "link-like"
126
+ // cell value without an actual URL; preserving it maintains backward
127
+ // compatibility with pre-existing CSV output.
128
+ const maybeLink = value;
129
+ if (typeof maybeLink.hyperlink === "string" || typeof maybeLink.text === "string") {
130
+ const url = typeof maybeLink.hyperlink === "string" ? maybeLink.hyperlink : "";
131
+ const text = typeof maybeLink.text === "string" ? maybeLink.text : "";
132
+ return url || text || "";
133
+ }
134
+ // Formula / SharedFormula / ArrayFormula — all carry an evaluated `result`
135
+ if ("formula" in value || "sharedFormula" in value) {
136
+ return value.result ?? "";
137
+ }
138
+ // Rich text — flatten runs
139
+ if ("richText" in value && Array.isArray(value.richText)) {
140
+ return value.richText.map(r => r.text).join("");
141
+ }
142
+ // Checkbox
143
+ if ("checkbox" in value && typeof value.checkbox === "boolean") {
144
+ return value.checkbox;
116
145
  }
117
- return value;
146
+ // Error
147
+ if ("error" in value && typeof value.error === "string") {
148
+ return value.error;
149
+ }
150
+ // Unknown object shape — round-trippable fallback
151
+ return JSON.stringify(value);
118
152
  };
119
153
  }
120
154
  // =============================================================================
@@ -241,7 +275,18 @@ class Workbook {
241
275
  // ===========================================================================
242
276
  // Constructor
243
277
  // ===========================================================================
244
- constructor() {
278
+ /**
279
+ * @param options Optional construction options.
280
+ * - `formulaSyntaxProbe`: An explicit tokenizer+parser probe used to
281
+ * classify defined-name text during XLSX load. Providing this makes
282
+ * classification deterministic for *this* workbook regardless of
283
+ * whether `installFormulaEngine()` has been called. Most callers
284
+ * don't need it — `installFormulaEngine()` registers a
285
+ * process-wide default probe that is picked up automatically.
286
+ */
287
+ constructor(options) {
288
+ /** Global registry of table names (lowercase) for cross-worksheet uniqueness checks. */
289
+ this._tableNames = new Set();
245
290
  this.category = "";
246
291
  this.company = "";
247
292
  this.created = new Date();
@@ -257,9 +302,33 @@ class Workbook {
257
302
  this.views = [];
258
303
  this.media = [];
259
304
  this.pivotTables = [];
305
+ this.externalLinks = [];
260
306
  this._passthrough = {};
261
307
  this._rawDrawings = {};
262
- this._definedNames = new defined_names_1.DefinedNames();
308
+ this._writerExternalLinkCache = new Map();
309
+ this._definedNames = new defined_names_1.DefinedNames(options?.formulaSyntaxProbe);
310
+ }
311
+ // ===========================================================================
312
+ // Default Font
313
+ // ===========================================================================
314
+ /**
315
+ * The default font for the workbook (fontId=0 / "Normal" style).
316
+ * Cells without explicit font styles will inherit this font in Excel.
317
+ *
318
+ * @example
319
+ * ```ts
320
+ * wb.defaultFont = { name: "Arial", size: 12 };
321
+ * ```
322
+ *
323
+ * When reading an existing XLSX file, this preserves the original default font
324
+ * for round-trip fidelity. Setting it on a new workbook changes the default
325
+ * from Calibri 11 to your chosen font.
326
+ */
327
+ get defaultFont() {
328
+ return this._defaultFont;
329
+ }
330
+ set defaultFont(font) {
331
+ this._defaultFont = font;
263
332
  }
264
333
  // ===========================================================================
265
334
  // Sheet Import
@@ -288,6 +357,25 @@ class Workbook {
288
357
  return newWs;
289
358
  }
290
359
  // ===========================================================================
360
+ // Workbook Protection
361
+ // ===========================================================================
362
+ /**
363
+ * Protect the workbook structure with an optional password.
364
+ * Prevents users from adding, deleting, renaming, moving, or copying worksheets.
365
+ *
366
+ * @param password - Optional password to protect the structure
367
+ * @param options - Optional protection flags (lockStructure, lockWindows, lockRevision)
368
+ */
369
+ async protect(password, options) {
370
+ this.protection = await (0, workbook_protection_1.buildWorkbookProtection)(password, options);
371
+ }
372
+ /**
373
+ * Remove workbook structure protection.
374
+ */
375
+ unprotect() {
376
+ this.protection = undefined;
377
+ }
378
+ // ===========================================================================
291
379
  // Format Operations (xlsx)
292
380
  // ===========================================================================
293
381
  /**
@@ -434,7 +522,10 @@ class Workbook {
434
522
  });
435
523
  }
436
524
  parser.on("data", (row) => {
437
- // When headers: true, CsvParserStream emits objects; otherwise arrays
525
+ // When headers: true, CsvParserStream emits objects; otherwise arrays.
526
+ // The CSV parser only ever emits primitive CellValue-compatible shapes
527
+ // (string/number/boolean/Date/null). Narrow once here so the rest of
528
+ // the pipeline — including the user-supplied `map` — sees CellValue.
438
529
  if (useHeaders && headerRow && row && typeof row === "object" && !Array.isArray(row)) {
439
530
  // Convert object row to array using header order
440
531
  const rowObj = row;
@@ -501,7 +592,8 @@ class Workbook {
501
592
  });
502
593
  }
503
594
  parser.on("data", (row) => {
504
- // When headers: true, CsvParserStream emits objects; otherwise arrays
595
+ // When headers: true, CsvParserStream emits objects; otherwise arrays.
596
+ // See createCsvReadStream for the rationale on narrowing to CellValue.
505
597
  if (useHeaders && headerRow && row && typeof row === "object" && !Array.isArray(row)) {
506
598
  // Convert object row to array using header order
507
599
  const rowObj = row;
@@ -928,6 +1020,50 @@ class Workbook {
928
1020
  return this._definedNames;
929
1021
  }
930
1022
  // ===========================================================================
1023
+ // Formula Calculation
1024
+ // ===========================================================================
1025
+ /**
1026
+ * Recalculate all formula cells in this workbook.
1027
+ *
1028
+ * Evaluates every formula cell using the built-in calculation engine and updates
1029
+ * each cell's cached `result` value in-place. Formulas are evaluated with
1030
+ * recursive dependency resolution, memoization, and circular reference detection.
1031
+ *
1032
+ * Call this after programmatically modifying cell values that are referenced by
1033
+ * formulas, to ensure formula results reflect the latest data.
1034
+ *
1035
+ * Unsupported functions preserve their original cached result if one exists.
1036
+ *
1037
+ * ## Tree-shaking note
1038
+ *
1039
+ * The formula engine ships ~200KB of code (433 Excel functions, parser,
1040
+ * evaluator, dependency graph, spill materialiser). To keep it out of
1041
+ * bundles that don't need it, the engine is registered at runtime
1042
+ * rather than imported by the core `Workbook` module. Call
1043
+ * {@link installFormulaEngine} once at startup before the first call
1044
+ * to this method, or a clear error will be thrown explaining what to do.
1045
+ *
1046
+ * ```ts
1047
+ * import { installFormulaEngine } from "@cj-tech-master/excelts/formula";
1048
+ *
1049
+ * installFormulaEngine(); // once, at startup
1050
+ *
1051
+ * sheet.getCell("A1").value = 100;
1052
+ * workbook.calculateFormulas(); // now works
1053
+ * ```
1054
+ *
1055
+ * Callers who prefer a zero-side-effect, tree-shakeable surface can
1056
+ * use the functional equivalent directly:
1057
+ *
1058
+ * ```ts
1059
+ * import { calculateFormulas } from "@cj-tech-master/excelts/formula";
1060
+ * calculateFormulas(workbook);
1061
+ * ```
1062
+ */
1063
+ calculateFormulas() {
1064
+ (0, host_registry_1.invokeFormulaEngine)(this);
1065
+ }
1066
+ // ===========================================================================
931
1067
  // Themes
932
1068
  // ===========================================================================
933
1069
  clearThemes() {
@@ -949,6 +1085,145 @@ class Workbook {
949
1085
  return this.media[Number(id)];
950
1086
  }
951
1087
  // ===========================================================================
1088
+ // External Workbook Links
1089
+ // ===========================================================================
1090
+ /**
1091
+ * Declare that formulas in this workbook may reference an external
1092
+ * workbook. Registers the target so the output file contains the required
1093
+ * `xl/externalLinks/externalLink{N}.xml` part plus its `.rels` sibling
1094
+ * and Office/WPS can resolve the reference correctly.
1095
+ *
1096
+ * When Office opens the file, it resolves a relative `target` like
1097
+ * `"测试.xlsx"` **relative to the current workbook's directory** — which
1098
+ * is the exact behaviour the user expects when they write
1099
+ * `=[测试.xlsx]Sheet1!A1`. Absolute `file:///…` or `http(s)://…` URIs
1100
+ * are accepted and written through unchanged.
1101
+ *
1102
+ * @returns the registered {@link ExternalLinkModel}. Its `index` field is
1103
+ * the 1-based number used inside the `[N]` prefix of on-disk formula
1104
+ * strings (the library rewrites `[target]` forms to `[index]` at write
1105
+ * time automatically).
1106
+ *
1107
+ * @example
1108
+ * ```ts
1109
+ * const wb = new Workbook();
1110
+ * const ws = wb.addWorksheet("Main");
1111
+ *
1112
+ * // Declare the link once — sheet names and cached values are optional
1113
+ * // but improve interoperability (Excel displays cached values when the
1114
+ * // external file is unavailable).
1115
+ * wb.addExternalLink({
1116
+ * target: "测试.xlsx",
1117
+ * sheetNames: ["Sheet1"],
1118
+ * cachedValues: { Sheet1: { A1: 42 } }
1119
+ * });
1120
+ *
1121
+ * // Write the formula using either the target name OR the numeric index;
1122
+ * // the library normalises both to the on-disk `[N]` form.
1123
+ * ws.getCell("A1").value = { formula: "=[测试.xlsx]Sheet1!A1", result: 42 };
1124
+ * ```
1125
+ */
1126
+ addExternalLink(input) {
1127
+ const link = {
1128
+ index: this.externalLinks.length + 1,
1129
+ target: input.target,
1130
+ targetMode: input.targetMode ?? "External",
1131
+ sheetNames: input.sheetNames ? [...input.sheetNames] : [],
1132
+ cachedValues: input.cachedValues ? { ...input.cachedValues } : {}
1133
+ };
1134
+ this.externalLinks.push(link);
1135
+ return link;
1136
+ }
1137
+ /**
1138
+ * Retrieve an external link by its 1-based on-disk index (the number
1139
+ * inside the `[N]` formula prefix) or by matching target path.
1140
+ */
1141
+ getExternalLink(indexOrTarget) {
1142
+ if (typeof indexOrTarget === "number") {
1143
+ return this.externalLinks[indexOrTarget - 1];
1144
+ }
1145
+ const lower = indexOrTarget.toLowerCase();
1146
+ return this.externalLinks.find(link => link.target.toLowerCase() === lower);
1147
+ }
1148
+ /**
1149
+ * @internal — used by the writer to obtain the full list of external
1150
+ * links to serialise, including entries auto-discovered from formula
1151
+ * strings during earlier writes. User-visible `externalLinks` always
1152
+ * comes first (in declaration order) so explicit `addExternalLink()`
1153
+ * indices are stable across writes.
1154
+ */
1155
+ _collectExternalLinksForWrite() {
1156
+ const userLower = new Set(this.externalLinks.map(l => l.target.toLowerCase()));
1157
+ const combined = this.externalLinks.map((link, i) => ({
1158
+ ...link,
1159
+ index: i + 1,
1160
+ sheetNames: [...(link.sheetNames ?? [])],
1161
+ cachedValues: { ...(link.cachedValues ?? {}) },
1162
+ targetMode: link.targetMode ?? "External"
1163
+ }));
1164
+ for (const cached of this._writerExternalLinkCache.values()) {
1165
+ if (userLower.has(cached.target.toLowerCase())) {
1166
+ // User explicitly added a link with the same target after an
1167
+ // auto-discovery pass — prefer the user's definition, drop the
1168
+ // cached one.
1169
+ continue;
1170
+ }
1171
+ combined.push({
1172
+ ...cached,
1173
+ index: combined.length + 1,
1174
+ sheetNames: [...cached.sheetNames],
1175
+ cachedValues: { ...cached.cachedValues }
1176
+ });
1177
+ }
1178
+ return combined;
1179
+ }
1180
+ /**
1181
+ * @internal — record an auto-discovered external link (seen in a
1182
+ * formula but not explicitly declared). Idempotent by target; the
1183
+ * sheet name is upserted onto the existing cached entry when present.
1184
+ * Returns the 1-based index the link will carry in the output file.
1185
+ */
1186
+ _recordAutoExternalLink(target, sheetName) {
1187
+ const lower = target.toLowerCase();
1188
+ // If the user explicitly declared a link with this target, we respect
1189
+ // their definition verbatim: no sheetName upserts, no cache entry.
1190
+ // Excel needs the user-declared sheetNames to match the refs, and
1191
+ // augmenting them on the user's behalf could silently hide a typo.
1192
+ const existingUserIdx = this.externalLinks.findIndex(l => l.target.toLowerCase() === lower);
1193
+ if (existingUserIdx !== -1) {
1194
+ return existingUserIdx + 1;
1195
+ }
1196
+ let cached = this._writerExternalLinkCache.get(lower);
1197
+ if (!cached) {
1198
+ cached = {
1199
+ // Index is provisional — the real on-disk index is recomputed by
1200
+ // `_collectExternalLinksForWrite()` at serialisation time.
1201
+ index: 0,
1202
+ target,
1203
+ targetMode: "External",
1204
+ sheetNames: [],
1205
+ cachedValues: {}
1206
+ };
1207
+ this._writerExternalLinkCache.set(lower, cached);
1208
+ }
1209
+ if (sheetName && !cached.sheetNames.includes(sheetName)) {
1210
+ cached.sheetNames.push(sheetName);
1211
+ }
1212
+ // Recompute final index: user entries first, then cache entries in
1213
+ // insertion order. The caller needs the *on-disk* index so that the
1214
+ // formula it's rewriting matches the link that will be serialised.
1215
+ const userCount = this.externalLinks.length;
1216
+ let cacheIdx = 0;
1217
+ for (const key of this._writerExternalLinkCache.keys()) {
1218
+ cacheIdx++;
1219
+ if (key === lower) {
1220
+ return userCount + cacheIdx;
1221
+ }
1222
+ }
1223
+ // Unreachable — we just inserted.
1224
+ return userCount + this._writerExternalLinkCache.size;
1225
+ }
1226
+ // ===========================================================================
952
1227
  // Model (Serialization)
953
1228
  // ===========================================================================
954
1229
  get model() {
@@ -959,6 +1234,7 @@ class Workbook {
959
1234
  created: this.created,
960
1235
  modified: this.modified,
961
1236
  properties: this.properties,
1237
+ protection: this.protection,
962
1238
  worksheets: this.worksheets.map(worksheet => worksheet.model),
963
1239
  sheets: this.worksheets.map(ws => ws.model).filter(Boolean),
964
1240
  definedNames: this._definedNames.model,
@@ -979,7 +1255,8 @@ class Workbook {
979
1255
  calcProperties: this.calcProperties,
980
1256
  passthrough: this._passthrough,
981
1257
  rawDrawings: this._rawDrawings,
982
- defaultFont: this._defaultFont
1258
+ defaultFont: this._defaultFont,
1259
+ externalLinks: this.externalLinks
983
1260
  };
984
1261
  }
985
1262
  set model(value) {
@@ -999,8 +1276,10 @@ class Workbook {
999
1276
  this.revision = value.revision;
1000
1277
  this.contentStatus = value.contentStatus;
1001
1278
  this.properties = value.properties;
1279
+ this.protection = value.protection;
1002
1280
  this.calcProperties = value.calcProperties;
1003
1281
  this._worksheets = [];
1282
+ this._tableNames.clear();
1004
1283
  value.worksheets.forEach(worksheetModel => {
1005
1284
  const { id, name, state } = worksheetModel;
1006
1285
  const orderNo = value.sheets && value.sheets.findIndex(ws => ws.id === id);
@@ -1026,6 +1305,11 @@ class Workbook {
1026
1305
  this._rawDrawings = value.rawDrawings || {};
1027
1306
  // Preserve default font for round-trip fidelity
1028
1307
  this._defaultFont = value.defaultFont;
1308
+ // Preserve external workbook references (empty array if none)
1309
+ this.externalLinks = value.externalLinks ? [...value.externalLinks] : [];
1310
+ // Reset the writer-scoped auto-discovery cache — loading a fresh
1311
+ // workbook replaces any accumulated state from previous writes.
1312
+ this._writerExternalLinkCache = new Map();
1029
1313
  }
1030
1314
  }
1031
1315
  exports.Workbook = Workbook;
@@ -107,6 +107,8 @@ class Worksheet {
107
107
  this.conditionalFormattings = [];
108
108
  // for form controls (legacy checkboxes, etc.)
109
109
  this.formControls = [];
110
+ // ignored errors (suppress green triangles in Excel)
111
+ this.ignoredErrors = [];
110
112
  // watermark configuration
111
113
  this._watermark = null;
112
114
  }
@@ -1110,8 +1112,19 @@ class Worksheet {
1110
1112
  */
1111
1113
  addTable(model) {
1112
1114
  const table = new table_1.Table(this, model);
1113
- // Use table.name (sanitized by Table.validate()) as the key
1115
+ // table.name is sanitized by Table.validate() check against the
1116
+ // sanitized name so that e.g. "My Table" and "My_Table" (which both
1117
+ // sanitize to "My_Table") are correctly detected as duplicates.
1118
+ const nameKey = table.name.toLowerCase();
1119
+ if (this.tables[table.name]) {
1120
+ throw new errors_1.TableError(`Table name "${table.name}" already exists in worksheet "${this.name}".`);
1121
+ }
1122
+ if (this.workbook._tableNames.has(nameKey)) {
1123
+ throw new errors_1.TableError(`Table name "${table.name}" already exists in another worksheet. ` +
1124
+ `Table names must be unique across the entire workbook (case-insensitive).`);
1125
+ }
1114
1126
  this.tables[table.name] = table;
1127
+ this.workbook._tableNames.add(nameKey);
1115
1128
  return table;
1116
1129
  }
1117
1130
  /**
@@ -1124,6 +1137,9 @@ class Worksheet {
1124
1137
  * Delete table by name
1125
1138
  */
1126
1139
  removeTable(name) {
1140
+ if (this.tables[name]) {
1141
+ this.workbook._tableNames.delete(name.toLowerCase());
1142
+ }
1127
1143
  delete this.tables[name];
1128
1144
  }
1129
1145
  /**
@@ -1371,6 +1387,7 @@ class Worksheet {
1371
1387
  pivotTables: this.pivotTables,
1372
1388
  conditionalFormattings: this.conditionalFormattings,
1373
1389
  formControls: this.formControls.map(fc => fc.model),
1390
+ ignoredErrors: this.ignoredErrors,
1374
1391
  watermark: this._watermark,
1375
1392
  drawing: this._drawing
1376
1393
  };
@@ -1455,10 +1472,12 @@ class Worksheet {
1455
1472
  const t = new table_1.Table(this, table);
1456
1473
  t.model = table;
1457
1474
  tables[table.name] = t;
1475
+ this.workbook._tableNames.add(table.name.toLowerCase());
1458
1476
  return tables;
1459
1477
  }, {});
1460
1478
  this.pivotTables = value.pivotTables;
1461
1479
  this.conditionalFormattings = value.conditionalFormattings;
1480
+ this.ignoredErrors = value.ignoredErrors ?? [];
1462
1481
  // Form controls are currently write-only (not parsed from XLSX)
1463
1482
  this.formControls = [];
1464
1483
  // Preserve loaded drawing data (charts, etc.)
@@ -19,6 +19,21 @@ const RelType = {
19
19
  PivotCacheRecords: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotCacheRecords",
20
20
  PivotTable: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/pivotTable",
21
21
  FeaturePropertyBag: "http://schemas.microsoft.com/office/2022/11/relationships/FeaturePropertyBag",
22
- CtrlProp: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp"
22
+ CtrlProp: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp",
23
+ SheetMetadata: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
24
+ /**
25
+ * Relationship type for the externalLink part referenced from
26
+ * xl/_rels/workbook.xml.rels. Target is an internal path like
27
+ * `externalLinks/externalLink1.xml`.
28
+ */
29
+ ExternalLink: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
30
+ /**
31
+ * Relationship type used *inside* xl/externalLinks/_rels/externalLinkN.xml.rels
32
+ * to point at the actual external workbook. When `TargetMode="External"` and
33
+ * `Target` is a bare relative path (e.g. `"测试.xlsx"`), Office resolves it
34
+ * relative to the current workbook's directory — exactly the behaviour users
35
+ * expect from `=[测试.xlsx]Sheet1!A1`.
36
+ */
37
+ ExternalLinkPath: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath"
23
38
  };
24
39
  exports.RelType = RelType;