@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.
- package/README.md +25 -2
- package/README_zh.md +29 -6
- package/dist/browser/index.browser.d.ts +1 -1
- package/dist/browser/index.browser.js +4 -0
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/index.js +4 -0
- package/dist/browser/modules/excel/cell.d.ts +17 -3
- package/dist/browser/modules/excel/cell.js +170 -22
- package/dist/browser/modules/excel/defined-names.d.ts +96 -1
- package/dist/browser/modules/excel/defined-names.js +411 -21
- package/dist/browser/modules/excel/image.d.ts +11 -0
- package/dist/browser/modules/excel/image.js +24 -1
- package/dist/browser/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/browser/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/browser/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/browser/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/browser/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/browser/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/browser/modules/excel/table.js +15 -2
- package/dist/browser/modules/excel/types.d.ts +133 -2
- package/dist/browser/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/browser/modules/excel/utils/col-cache.js +15 -0
- package/dist/browser/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/browser/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/browser/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/browser/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/browser/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/browser/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/browser/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/browser/modules/excel/utils/shared-strings.js +21 -2
- package/dist/browser/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/browser/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/browser/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/browser/modules/excel/workbook.browser.js +318 -34
- package/dist/browser/modules/excel/workbook.d.ts +1 -1
- package/dist/browser/modules/excel/worksheet.d.ts +3 -1
- package/dist/browser/modules/excel/worksheet.js +21 -2
- package/dist/browser/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/browser/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/browser/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/browser/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/browser/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/browser/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/browser/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/browser/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/browser/modules/formula/compile/address-utils.js +83 -0
- package/dist/browser/modules/formula/compile/binder.d.ts +42 -0
- package/dist/browser/modules/formula/compile/binder.js +487 -0
- package/dist/browser/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/browser/modules/formula/compile/bound-ast.js +80 -0
- package/dist/browser/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/browser/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/browser/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/browser/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/browser/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/browser/modules/formula/default-syntax-probe.js +83 -0
- package/dist/browser/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/browser/modules/formula/functions/_date-context.js +29 -0
- package/dist/browser/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/browser/modules/formula/functions/_shared.js +381 -0
- package/dist/browser/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/browser/modules/formula/functions/conditional.js +343 -0
- package/dist/browser/modules/formula/functions/database.d.ts +37 -0
- package/dist/browser/modules/formula/functions/database.js +274 -0
- package/dist/browser/modules/formula/functions/date.d.ts +61 -0
- package/dist/browser/modules/formula/functions/date.js +855 -0
- package/dist/browser/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/browser/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/browser/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/browser/modules/formula/functions/engineering.js +1128 -0
- package/dist/browser/modules/formula/functions/financial.d.ts +202 -0
- package/dist/browser/modules/formula/functions/financial.js +2296 -0
- package/dist/browser/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/browser/modules/formula/functions/lookup.js +886 -0
- package/dist/browser/modules/formula/functions/math.d.ts +114 -0
- package/dist/browser/modules/formula/functions/math.js +1406 -0
- package/dist/browser/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/browser/modules/formula/functions/statistical.js +3390 -0
- package/dist/browser/modules/formula/functions/text.d.ts +86 -0
- package/dist/browser/modules/formula/functions/text.js +1845 -0
- package/dist/browser/modules/formula/host-registry.d.ts +53 -0
- package/dist/browser/modules/formula/host-registry.js +69 -0
- package/dist/browser/modules/formula/index.d.ts +39 -0
- package/dist/browser/modules/formula/index.js +49 -0
- package/dist/browser/modules/formula/install.d.ts +62 -0
- package/dist/browser/modules/formula/install.js +88 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/browser/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/browser/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/browser/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/browser/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/browser/modules/formula/integration/formula-instance.js +79 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/browser/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/browser/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/browser/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/browser/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/browser/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/browser/modules/formula/materialize/types.d.ts +179 -0
- package/dist/browser/modules/formula/materialize/types.js +29 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/browser/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/browser/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/browser/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/browser/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/browser/modules/formula/runtime/function-registry.js +840 -0
- package/dist/browser/modules/formula/runtime/values.d.ts +211 -0
- package/dist/browser/modules/formula/runtime/values.js +385 -0
- package/dist/browser/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/browser/modules/formula/syntax/ast.js +28 -0
- package/dist/browser/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/browser/modules/formula/syntax/parser.js +439 -0
- package/dist/browser/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/browser/modules/formula/syntax/token-types.js +59 -0
- package/dist/browser/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/dist/browser/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/browser/modules/pdf/excel-bridge.js +9 -0
- package/dist/cjs/index.js +4 -0
- package/dist/cjs/modules/excel/cell.js +170 -22
- package/dist/cjs/modules/excel/defined-names.js +411 -21
- package/dist/cjs/modules/excel/image.js +24 -1
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/cjs/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/cjs/modules/excel/table.js +15 -2
- package/dist/cjs/modules/excel/utils/col-cache.js +15 -0
- package/dist/cjs/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/cjs/modules/excel/utils/external-link-formula.js +212 -0
- package/dist/cjs/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/cjs/modules/excel/utils/ooxml-paths.js +42 -2
- package/dist/cjs/modules/excel/utils/shared-strings.js +21 -2
- package/dist/cjs/modules/excel/utils/workbook-protection.js +33 -0
- package/dist/cjs/modules/excel/workbook.browser.js +318 -34
- package/dist/cjs/modules/excel/worksheet.js +20 -1
- package/dist/cjs/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +333 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/external-reference-xform.js +27 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-protection-xform.js +69 -0
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +18 -0
- package/dist/cjs/modules/excel/xlsx/xform/core/metadata-xform.js +161 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +108 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +83 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/cjs/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +408 -18
- package/dist/cjs/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/cjs/modules/formula/compile/address-utils.js +89 -0
- package/dist/cjs/modules/formula/compile/binder.js +489 -0
- package/dist/cjs/modules/formula/compile/bound-ast.js +68 -0
- package/dist/cjs/modules/formula/compile/compiled-formula.js +387 -0
- package/dist/cjs/modules/formula/compile/dependency-analysis.js +437 -0
- package/dist/cjs/modules/formula/compile/structured-ref-utils.js +141 -0
- package/dist/cjs/modules/formula/default-syntax-probe.js +87 -0
- package/dist/cjs/modules/formula/functions/_date-context.js +33 -0
- package/dist/cjs/modules/formula/functions/_shared.js +396 -0
- package/dist/cjs/modules/formula/functions/conditional.js +354 -0
- package/dist/cjs/modules/formula/functions/database.js +288 -0
- package/dist/cjs/modules/formula/functions/date.js +883 -0
- package/dist/cjs/modules/formula/functions/dynamic-array.js +881 -0
- package/dist/cjs/modules/formula/functions/engineering.js +1183 -0
- package/dist/cjs/modules/formula/functions/financial.js +2348 -0
- package/dist/cjs/modules/formula/functions/lookup.js +902 -0
- package/dist/cjs/modules/formula/functions/math.js +1487 -0
- package/dist/cjs/modules/formula/functions/statistical.js +3488 -0
- package/dist/cjs/modules/formula/functions/text.js +1889 -0
- package/dist/cjs/modules/formula/host-registry.js +75 -0
- package/dist/cjs/modules/formula/index.js +58 -0
- package/dist/cjs/modules/formula/install.js +93 -0
- package/dist/cjs/modules/formula/integration/apply-writeback-plan.js +213 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas-impl.js +619 -0
- package/dist/cjs/modules/formula/integration/calculate-formulas.js +71 -0
- package/dist/cjs/modules/formula/integration/formula-instance.js +82 -0
- package/dist/cjs/modules/formula/integration/workbook-adapter.js +327 -0
- package/dist/cjs/modules/formula/integration/workbook-snapshot.js +84 -0
- package/dist/cjs/modules/formula/materialize/build-writeback-plan.js +475 -0
- package/dist/cjs/modules/formula/materialize/spill-engine.js +42 -0
- package/dist/cjs/modules/formula/materialize/types.js +32 -0
- package/dist/cjs/modules/formula/materialize/writeback-plan.js +28 -0
- package/dist/cjs/modules/formula/runtime/evaluator.js +2298 -0
- package/dist/cjs/modules/formula/runtime/function-registry.js +846 -0
- package/dist/cjs/modules/formula/runtime/values.js +385 -0
- package/dist/cjs/modules/formula/syntax/ast.js +8 -0
- package/dist/cjs/modules/formula/syntax/parser.js +440 -0
- package/dist/cjs/modules/formula/syntax/token-types.js +32 -0
- package/dist/cjs/modules/formula/syntax/tokenizer.js +1076 -0
- package/dist/cjs/modules/pdf/excel-bridge.js +9 -0
- package/dist/esm/index.browser.js +4 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/modules/excel/cell.js +170 -22
- package/dist/esm/modules/excel/defined-names.js +411 -21
- package/dist/esm/modules/excel/image.js +24 -1
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +14 -0
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +48 -1
- package/dist/esm/modules/excel/stream/worksheet-reader.js +17 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +45 -5
- package/dist/esm/modules/excel/table.js +15 -2
- package/dist/esm/modules/excel/utils/col-cache.js +15 -0
- package/dist/esm/modules/excel/utils/drawing-utils.js +4 -0
- package/dist/esm/modules/excel/utils/external-link-formula.js +208 -0
- package/dist/esm/modules/excel/utils/iterate-stream.js +3 -1
- package/dist/esm/modules/excel/utils/ooxml-paths.js +37 -2
- package/dist/esm/modules/excel/utils/shared-strings.js +21 -2
- package/dist/esm/modules/excel/utils/workbook-protection.js +30 -0
- package/dist/esm/modules/excel/workbook.browser.js +318 -34
- package/dist/esm/modules/excel/worksheet.js +21 -2
- package/dist/esm/modules/excel/xlsx/rel-type.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +21 -86
- package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +330 -0
- package/dist/esm/modules/excel/xlsx/xform/book/external-reference-xform.js +24 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.js +11 -2
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-protection-xform.js +66 -0
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +38 -5
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +19 -1
- package/dist/esm/modules/excel/xlsx/xform/core/metadata-xform.js +158 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +105 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +3 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +10 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +166 -8
- package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/ignored-errors-xform.js +80 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +9 -4
- package/dist/esm/modules/excel/xlsx/xform/style/border-xform.js +4 -1
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +410 -20
- package/dist/esm/modules/excel/xlsx/xlsx.js +4 -5
- package/dist/esm/modules/formula/compile/address-utils.js +83 -0
- package/dist/esm/modules/formula/compile/binder.js +487 -0
- package/dist/esm/modules/formula/compile/bound-ast.js +80 -0
- package/dist/esm/modules/formula/compile/compiled-formula.js +383 -0
- package/dist/esm/modules/formula/compile/dependency-analysis.js +432 -0
- package/dist/esm/modules/formula/compile/structured-ref-utils.js +136 -0
- package/dist/esm/modules/formula/default-syntax-probe.js +83 -0
- package/dist/esm/modules/formula/functions/_date-context.js +29 -0
- package/dist/esm/modules/formula/functions/_shared.js +381 -0
- package/dist/esm/modules/formula/functions/conditional.js +343 -0
- package/dist/esm/modules/formula/functions/database.js +274 -0
- package/dist/esm/modules/formula/functions/date.js +855 -0
- package/dist/esm/modules/formula/functions/dynamic-array.js +860 -0
- package/dist/esm/modules/formula/functions/engineering.js +1128 -0
- package/dist/esm/modules/formula/functions/financial.js +2296 -0
- package/dist/esm/modules/formula/functions/lookup.js +886 -0
- package/dist/esm/modules/formula/functions/math.js +1406 -0
- package/dist/esm/modules/formula/functions/statistical.js +3390 -0
- package/dist/esm/modules/formula/functions/text.js +1845 -0
- package/dist/esm/modules/formula/host-registry.js +69 -0
- package/dist/esm/modules/formula/index.js +49 -0
- package/dist/esm/modules/formula/install.js +88 -0
- package/dist/esm/modules/formula/integration/apply-writeback-plan.js +210 -0
- package/dist/esm/modules/formula/integration/calculate-formulas-impl.js +616 -0
- package/dist/esm/modules/formula/integration/calculate-formulas.js +68 -0
- package/dist/esm/modules/formula/integration/formula-instance.js +79 -0
- package/dist/esm/modules/formula/integration/workbook-adapter.js +324 -0
- package/dist/esm/modules/formula/integration/workbook-snapshot.js +77 -0
- package/dist/esm/modules/formula/materialize/build-writeback-plan.js +473 -0
- package/dist/esm/modules/formula/materialize/spill-engine.js +38 -0
- package/dist/esm/modules/formula/materialize/types.js +29 -0
- package/dist/esm/modules/formula/materialize/writeback-plan.js +27 -0
- package/dist/esm/modules/formula/runtime/evaluator.js +2291 -0
- package/dist/esm/modules/formula/runtime/function-registry.js +840 -0
- package/dist/esm/modules/formula/runtime/values.js +385 -0
- package/dist/esm/modules/formula/syntax/ast.js +28 -0
- package/dist/esm/modules/formula/syntax/parser.js +439 -0
- package/dist/esm/modules/formula/syntax/token-types.js +59 -0
- package/dist/esm/modules/formula/syntax/tokenizer.js +1074 -0
- package/dist/esm/modules/pdf/excel-bridge.js +9 -0
- package/dist/iife/excelts.iife.js +2302 -373
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +34 -34
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/modules/excel/cell.d.ts +17 -3
- package/dist/types/modules/excel/defined-names.d.ts +96 -1
- package/dist/types/modules/excel/image.d.ts +11 -0
- package/dist/types/modules/excel/stream/workbook-reader.browser.d.ts +9 -3
- package/dist/types/modules/excel/stream/workbook-reader.d.ts +2 -1
- package/dist/types/modules/excel/stream/workbook-writer.browser.d.ts +39 -5
- package/dist/types/modules/excel/stream/workbook-writer.d.ts +3 -2
- package/dist/types/modules/excel/stream/worksheet-writer.d.ts +39 -6
- package/dist/types/modules/excel/types.d.ts +133 -2
- package/dist/types/modules/excel/utils/col-cache.d.ts +1 -0
- package/dist/types/modules/excel/utils/drawing-utils.d.ts +3 -3
- package/dist/types/modules/excel/utils/external-link-formula.d.ts +76 -0
- package/dist/types/modules/excel/utils/iterate-stream.d.ts +9 -3
- package/dist/types/modules/excel/utils/ooxml-paths.d.ts +19 -0
- package/dist/types/modules/excel/utils/shared-strings.d.ts +8 -3
- package/dist/types/modules/excel/utils/workbook-protection.d.ts +30 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +257 -6
- package/dist/types/modules/excel/workbook.d.ts +1 -1
- package/dist/types/modules/excel/worksheet.d.ts +3 -1
- package/dist/types/modules/excel/xlsx/rel-type.d.ts +15 -0
- package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +6 -5
- package/dist/types/modules/excel/xlsx/xform/book/external-link-xform.d.ts +84 -0
- package/dist/types/modules/excel/xlsx/xform/book/external-reference-xform.d.ts +17 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-calc-properties-xform.d.ts +3 -0
- package/dist/types/modules/excel/xlsx/xform/book/workbook-protection-xform.d.ts +20 -0
- package/dist/types/modules/excel/xlsx/xform/core/metadata-xform.d.ts +56 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.d.ts +26 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/types/modules/excel/xlsx/xform/sheet/ignored-errors-xform.d.ts +21 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +172 -13
- package/dist/types/modules/excel/xlsx/xlsx.d.ts +7 -4
- package/dist/types/modules/formula/compile/address-utils.d.ts +62 -0
- package/dist/types/modules/formula/compile/binder.d.ts +42 -0
- package/dist/types/modules/formula/compile/bound-ast.d.ts +230 -0
- package/dist/types/modules/formula/compile/compiled-formula.d.ts +137 -0
- package/dist/types/modules/formula/compile/dependency-analysis.d.ts +93 -0
- package/dist/types/modules/formula/compile/structured-ref-utils.d.ts +93 -0
- package/dist/types/modules/formula/default-syntax-probe.d.ts +79 -0
- package/dist/types/modules/formula/functions/_date-context.d.ts +4 -0
- package/dist/types/modules/formula/functions/_shared.d.ts +121 -0
- package/dist/types/modules/formula/functions/conditional.d.ts +27 -0
- package/dist/types/modules/formula/functions/database.d.ts +37 -0
- package/dist/types/modules/formula/functions/date.d.ts +61 -0
- package/dist/types/modules/formula/functions/dynamic-array.d.ts +23 -0
- package/dist/types/modules/formula/functions/engineering.d.ts +57 -0
- package/dist/types/modules/formula/functions/financial.d.ts +202 -0
- package/dist/types/modules/formula/functions/lookup.d.ts +18 -0
- package/dist/types/modules/formula/functions/math.d.ts +114 -0
- package/dist/types/modules/formula/functions/statistical.d.ts +193 -0
- package/dist/types/modules/formula/functions/text.d.ts +86 -0
- package/dist/types/modules/formula/host-registry.d.ts +53 -0
- package/dist/types/modules/formula/index.d.ts +39 -0
- package/dist/types/modules/formula/install.d.ts +62 -0
- package/dist/types/modules/formula/integration/apply-writeback-plan.d.ts +26 -0
- package/dist/types/modules/formula/integration/calculate-formulas-impl.d.ts +30 -0
- package/dist/types/modules/formula/integration/calculate-formulas.d.ts +67 -0
- package/dist/types/modules/formula/integration/formula-instance.d.ts +64 -0
- package/dist/types/modules/formula/integration/workbook-adapter.d.ts +26 -0
- package/dist/types/modules/formula/integration/workbook-snapshot.d.ts +267 -0
- package/dist/types/modules/formula/materialize/build-writeback-plan.d.ts +34 -0
- package/dist/types/modules/formula/materialize/spill-engine.d.ts +9 -0
- package/dist/types/modules/formula/materialize/types.d.ts +179 -0
- package/dist/types/modules/formula/materialize/writeback-plan.d.ts +167 -0
- package/dist/types/modules/formula/runtime/evaluator.d.ts +151 -0
- package/dist/types/modules/formula/runtime/function-registry.d.ts +47 -0
- package/dist/types/modules/formula/runtime/values.d.ts +211 -0
- package/dist/types/modules/formula/syntax/ast.d.ts +129 -0
- package/dist/types/modules/formula/syntax/parser.d.ts +18 -0
- package/dist/types/modules/formula/syntax/token-types.d.ts +153 -0
- package/dist/types/modules/formula/syntax/tokenizer.d.ts +10 -0
- package/package.json +28 -28
|
@@ -15,12 +15,14 @@ import { filterDrawingAnchors } from "../utils/drawing-utils.js";
|
|
|
15
15
|
import { drawingPath, drawingRelsPath, mediaPath, OOXML_PATHS, OOXML_REL_TARGETS, worksheetRelTarget } from "../utils/ooxml-paths.js";
|
|
16
16
|
import { SharedStrings } from "../utils/shared-strings.js";
|
|
17
17
|
import { StreamBuf } from "../utils/stream-buf.js";
|
|
18
|
+
import { buildWorkbookProtection } from "../utils/workbook-protection.js";
|
|
18
19
|
import { RelType } from "../xlsx/rel-type.js";
|
|
19
20
|
import { WorkbookXform } from "../xlsx/xform/book/workbook-xform.js";
|
|
20
21
|
import { AppXform } from "../xlsx/xform/core/app-xform.js";
|
|
21
22
|
import { ContentTypesXform } from "../xlsx/xform/core/content-types-xform.js";
|
|
22
23
|
import { CoreXform } from "../xlsx/xform/core/core-xform.js";
|
|
23
24
|
import { FeaturePropertyBagXform } from "../xlsx/xform/core/feature-property-bag-xform.js";
|
|
25
|
+
import { MetadataXform } from "../xlsx/xform/core/metadata-xform.js";
|
|
24
26
|
import { RelationshipsXform } from "../xlsx/xform/core/relationships-xform.js";
|
|
25
27
|
import { DrawingXform } from "../xlsx/xform/drawing/drawing-xform.js";
|
|
26
28
|
import { SharedStringsXform } from "../xlsx/xform/strings/shared-strings-xform.js";
|
|
@@ -53,6 +55,7 @@ export class WorkbookWriterBase {
|
|
|
53
55
|
this.compressionLevel = Math.max(0, Math.min(9, level));
|
|
54
56
|
this.media = [];
|
|
55
57
|
this.commentRefs = [];
|
|
58
|
+
this.dynamicArrayCount = 0;
|
|
56
59
|
this._trueStreaming = options.trueStreaming ?? false;
|
|
57
60
|
// Create Zip instance
|
|
58
61
|
this.zip = new Zip((err, data, final) => {
|
|
@@ -87,6 +90,18 @@ export class WorkbookWriterBase {
|
|
|
87
90
|
get definedNames() {
|
|
88
91
|
return this._definedNames;
|
|
89
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* The default font for the workbook (fontId=0 / "Normal" style).
|
|
95
|
+
* Must be set before any worksheet rows are committed.
|
|
96
|
+
*/
|
|
97
|
+
get defaultFont() {
|
|
98
|
+
return this.styles.defaultFont;
|
|
99
|
+
}
|
|
100
|
+
set defaultFont(font) {
|
|
101
|
+
if (this.styles.setDefaultFont) {
|
|
102
|
+
this.styles.setDefaultFont(font);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
90
105
|
/** @internal */
|
|
91
106
|
_openStream(path) {
|
|
92
107
|
const stream = new StreamBuf({
|
|
@@ -147,6 +162,7 @@ export class WorkbookWriterBase {
|
|
|
147
162
|
this.addSharedStrings(),
|
|
148
163
|
this.addStyles(),
|
|
149
164
|
this.addFeaturePropertyBag(),
|
|
165
|
+
this.addMetadata(),
|
|
150
166
|
this.addWorkbookRels()
|
|
151
167
|
]);
|
|
152
168
|
await this.addWorkbook();
|
|
@@ -173,6 +189,19 @@ export class WorkbookWriterBase {
|
|
|
173
189
|
getImage(id) {
|
|
174
190
|
return this.media[id];
|
|
175
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Protect the workbook structure with an optional password.
|
|
194
|
+
* Prevents users from adding, deleting, renaming, moving, or copying worksheets.
|
|
195
|
+
*/
|
|
196
|
+
async protect(password, options) {
|
|
197
|
+
this.protection = await buildWorkbookProtection(password, options);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Remove workbook structure protection.
|
|
201
|
+
*/
|
|
202
|
+
unprotect() {
|
|
203
|
+
this.protection = undefined;
|
|
204
|
+
}
|
|
176
205
|
addWorksheet(name, options) {
|
|
177
206
|
const opts = options || {};
|
|
178
207
|
const useSharedStrings = opts.useSharedStrings !== undefined ? opts.useSharedStrings : this.useSharedStrings;
|
|
@@ -250,7 +279,8 @@ export class WorkbookWriterBase {
|
|
|
250
279
|
commentRefs: this.commentRefs,
|
|
251
280
|
media: this.media,
|
|
252
281
|
drawings,
|
|
253
|
-
hasCheckboxes: this.styles.hasCheckboxes
|
|
282
|
+
hasCheckboxes: this.styles.hasCheckboxes,
|
|
283
|
+
hasDynamicArrayFormulas: this.dynamicArrayCount > 0
|
|
254
284
|
};
|
|
255
285
|
const xform = new ContentTypesXform();
|
|
256
286
|
this._addFile(xform.toXml(model), OOXML_PATHS.contentTypes);
|
|
@@ -336,6 +366,14 @@ export class WorkbookWriterBase {
|
|
|
336
366
|
}
|
|
337
367
|
return Promise.resolve();
|
|
338
368
|
}
|
|
369
|
+
addMetadata() {
|
|
370
|
+
if (this.dynamicArrayCount <= 0) {
|
|
371
|
+
return Promise.resolve();
|
|
372
|
+
}
|
|
373
|
+
const xform = new MetadataXform();
|
|
374
|
+
this._addFile(xform.toXml({ dynamicArrayCount: this.dynamicArrayCount }), OOXML_PATHS.xlMetadata);
|
|
375
|
+
return Promise.resolve();
|
|
376
|
+
}
|
|
339
377
|
addWorkbookRels() {
|
|
340
378
|
let count = 1;
|
|
341
379
|
const relationships = [
|
|
@@ -357,6 +395,14 @@ export class WorkbookWriterBase {
|
|
|
357
395
|
Target: OOXML_REL_TARGETS.workbookFeaturePropertyBag
|
|
358
396
|
});
|
|
359
397
|
}
|
|
398
|
+
// Add metadata relationship for dynamic array formulas
|
|
399
|
+
if (this.dynamicArrayCount > 0) {
|
|
400
|
+
relationships.push({
|
|
401
|
+
Id: `rId${count++}`,
|
|
402
|
+
Type: RelType.SheetMetadata,
|
|
403
|
+
Target: OOXML_REL_TARGETS.workbookMetadata
|
|
404
|
+
});
|
|
405
|
+
}
|
|
360
406
|
this._worksheets.forEach(ws => {
|
|
361
407
|
if (ws) {
|
|
362
408
|
ws.rId = `rId${count++}`;
|
|
@@ -379,6 +425,7 @@ export class WorkbookWriterBase {
|
|
|
379
425
|
definedNames: this._definedNames.model,
|
|
380
426
|
views: this.views,
|
|
381
427
|
properties: {},
|
|
428
|
+
protection: this.protection,
|
|
382
429
|
calcProperties: {}
|
|
383
430
|
};
|
|
384
431
|
return new Promise(resolve => {
|
|
@@ -187,10 +187,12 @@ class WorksheetReader extends EventEmitter {
|
|
|
187
187
|
case "c":
|
|
188
188
|
if (row) {
|
|
189
189
|
const styleAttr = node.attributes.s;
|
|
190
|
+
const cmAttr = node.attributes.cm;
|
|
190
191
|
c = {
|
|
191
192
|
ref: node.attributes.r,
|
|
192
193
|
s: styleAttr !== undefined ? parseInt(styleAttr, 10) : undefined,
|
|
193
|
-
t: node.attributes.t
|
|
194
|
+
t: node.attributes.t,
|
|
195
|
+
cm: cmAttr !== undefined ? parseInt(cmAttr, 10) : undefined
|
|
194
196
|
};
|
|
195
197
|
}
|
|
196
198
|
break;
|
|
@@ -295,6 +297,20 @@ class WorksheetReader extends EventEmitter {
|
|
|
295
297
|
cellValue.result = parseFloat(c.v.text);
|
|
296
298
|
}
|
|
297
299
|
}
|
|
300
|
+
// Check if this cell is a dynamic array formula via cm → metadata mapping.
|
|
301
|
+
// Uses the precise dynamicArrayCmIndices set from WorkbookReaderBase,
|
|
302
|
+
// falling back to the coarser hasDynamicArrayMetadata boolean.
|
|
303
|
+
if (c.cm !== undefined) {
|
|
304
|
+
const { workbook: wb } = this;
|
|
305
|
+
if (wb.dynamicArrayCmIndices) {
|
|
306
|
+
if (wb.dynamicArrayCmIndices.has(c.cm)) {
|
|
307
|
+
cellValue.isDynamicArray = true;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
else if (wb.hasDynamicArrayMetadata) {
|
|
311
|
+
cellValue.isDynamicArray = true;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
298
314
|
cell.value = cellValue;
|
|
299
315
|
}
|
|
300
316
|
else if (c.v) {
|
|
@@ -26,6 +26,7 @@ import { DrawingXform as DrawingPartXform } from "../xlsx/xform/sheet/drawing-xf
|
|
|
26
26
|
import { ExtLstXform } from "../xlsx/xform/sheet/ext-lst-xform.js";
|
|
27
27
|
import { HeaderFooterXform } from "../xlsx/xform/sheet/header-footer-xform.js";
|
|
28
28
|
import { HyperlinkXform } from "../xlsx/xform/sheet/hyperlink-xform.js";
|
|
29
|
+
import { IgnoredErrorsXform } from "../xlsx/xform/sheet/ignored-errors-xform.js";
|
|
29
30
|
import { PageMarginsXform } from "../xlsx/xform/sheet/page-margins-xform.js";
|
|
30
31
|
import { PageSetupXform } from "../xlsx/xform/sheet/page-setup-xform.js";
|
|
31
32
|
import { PictureXform } from "../xlsx/xform/sheet/picture-xform.js";
|
|
@@ -60,6 +61,7 @@ const xform = {
|
|
|
60
61
|
drawing: new DrawingPartXform(),
|
|
61
62
|
conditionalFormattings: new ConditionalFormattingsXform(),
|
|
62
63
|
extLst: new ExtLstXform(),
|
|
64
|
+
ignoredErrors: new IgnoredErrorsXform(),
|
|
63
65
|
headerFooter: new HeaderFooterXform(),
|
|
64
66
|
rowBreaks: new RowBreaksXform(),
|
|
65
67
|
colBreaks: new ColBreaksXform()
|
|
@@ -100,6 +102,8 @@ class WorksheetWriter {
|
|
|
100
102
|
this._siFormulae = 0;
|
|
101
103
|
// keep a record of conditionalFormattings
|
|
102
104
|
this.conditionalFormatting = [];
|
|
105
|
+
// ignored errors (suppress green triangles in Excel)
|
|
106
|
+
this.ignoredErrors = [];
|
|
103
107
|
// keep a record of all row and column pageBreaks
|
|
104
108
|
this.rowBreaks = [];
|
|
105
109
|
this.colBreaks = [];
|
|
@@ -212,6 +216,8 @@ class WorksheetWriter {
|
|
|
212
216
|
this._writeBackground(); // Note: must be after drawing
|
|
213
217
|
// Legacy Data tag for comments
|
|
214
218
|
this._writeLegacyData();
|
|
219
|
+
// ignoredErrors must be before extLst
|
|
220
|
+
this._writeIgnoredErrors();
|
|
215
221
|
// extLst must be the last child element before </worksheet>
|
|
216
222
|
this._writeExtLst();
|
|
217
223
|
this._writeCloseWorksheet();
|
|
@@ -529,18 +535,33 @@ class WorksheetWriter {
|
|
|
529
535
|
}
|
|
530
536
|
throw new Error(`Invalid image range: "${range}". Expected a range like "A1:C3".`);
|
|
531
537
|
}
|
|
532
|
-
|
|
533
|
-
|
|
538
|
+
// Absolute positioning (pos + ext, no cell anchors)
|
|
539
|
+
if ("pos" in range && range.pos) {
|
|
540
|
+
return {
|
|
541
|
+
type: "image",
|
|
542
|
+
imageId,
|
|
543
|
+
range: {
|
|
544
|
+
tl: { nativeCol: 0, nativeColOff: 0, nativeRow: 0, nativeRowOff: 0 },
|
|
545
|
+
ext: range.ext,
|
|
546
|
+
pos: range.pos
|
|
547
|
+
},
|
|
548
|
+
hyperlinks: range.hyperlinks
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
// Cell-based positioning (tl/br anchors)
|
|
552
|
+
const cellRange = range;
|
|
553
|
+
const tl = new Anchor(this, cellRange.tl, 0).model;
|
|
554
|
+
const br = cellRange.br ? new Anchor(this, cellRange.br, 0).model : undefined;
|
|
534
555
|
return {
|
|
535
556
|
type: "image",
|
|
536
557
|
imageId,
|
|
537
558
|
range: {
|
|
538
559
|
tl,
|
|
539
560
|
br,
|
|
540
|
-
ext:
|
|
541
|
-
editAs:
|
|
561
|
+
ext: cellRange.ext,
|
|
562
|
+
editAs: cellRange.editAs
|
|
542
563
|
},
|
|
543
|
-
hyperlinks:
|
|
564
|
+
hyperlinks: cellRange.hyperlinks
|
|
544
565
|
};
|
|
545
566
|
}
|
|
546
567
|
// =========================================================================
|
|
@@ -617,6 +638,9 @@ class WorksheetWriter {
|
|
|
617
638
|
}
|
|
618
639
|
if (row.hasValues || row.height != null) {
|
|
619
640
|
const { model } = row;
|
|
641
|
+
if (!model) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
620
644
|
const options = {
|
|
621
645
|
styles: this._workbook.styles,
|
|
622
646
|
sharedStrings: this.useSharedStrings ? this._workbook.sharedStrings : undefined,
|
|
@@ -628,6 +652,14 @@ class WorksheetWriter {
|
|
|
628
652
|
};
|
|
629
653
|
xform.row.prepare(model, options);
|
|
630
654
|
this.stream.write(xform.row.toXml(model));
|
|
655
|
+
// Count dynamic array formula cells for metadata generation
|
|
656
|
+
if (model.cells) {
|
|
657
|
+
for (const cell of model.cells) {
|
|
658
|
+
if (cell && cell.isDynamicArray) {
|
|
659
|
+
this._workbook.dynamicArrayCount++;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
631
663
|
if (options.comments.length) {
|
|
632
664
|
this.hasComments = true;
|
|
633
665
|
this._sheetCommentsWriter.addComments(options.comments);
|
|
@@ -680,6 +712,11 @@ class WorksheetWriter {
|
|
|
680
712
|
const model = { conditionalFormattings: this.conditionalFormatting };
|
|
681
713
|
this.stream.write(xform.extLst.toXml(model));
|
|
682
714
|
}
|
|
715
|
+
_writeIgnoredErrors() {
|
|
716
|
+
if (this.ignoredErrors.length > 0) {
|
|
717
|
+
this.stream.write(xform.ignoredErrors.toXml(this.ignoredErrors));
|
|
718
|
+
}
|
|
719
|
+
}
|
|
683
720
|
_writeRowBreaks() {
|
|
684
721
|
this.stream.write(xform.rowBreaks.toXml(this.rowBreaks));
|
|
685
722
|
}
|
|
@@ -753,6 +790,9 @@ class WorksheetWriter {
|
|
|
753
790
|
if (this._background) {
|
|
754
791
|
if (this._background.imageId !== undefined) {
|
|
755
792
|
const image = this._workbook.getImage(this._background.imageId);
|
|
793
|
+
if (!image) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
756
796
|
const pictureId = this._sheetRelsWriter.addMedia({
|
|
757
797
|
Target: mediaRelTargetFromRels(image.name),
|
|
758
798
|
Type: RelType.Image
|
|
@@ -535,14 +535,27 @@ class Table {
|
|
|
535
535
|
this._ensureStyle().showColumnStripes = value;
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
|
+
// SUBTOTAL function codes per OOXML/Excel:
|
|
539
|
+
// 1/101=AVERAGE, 2/102=COUNT, 3/103=COUNTA, 4/104=MAX, 5/105=MIN,
|
|
540
|
+
// 6/106=PRODUCT, 7/107=STDEV, 8/108=STDEVP, 9/109=SUM, 10/110=VAR, 11/111=VARP.
|
|
541
|
+
// The 1xx variants also ignore manually hidden rows — Excel always uses
|
|
542
|
+
// these for totals-row injection. OOXML totalsRowFunction names map to:
|
|
543
|
+
// average → 1 (AVERAGE)
|
|
544
|
+
// countNums → 2 (COUNT, numeric-only)
|
|
545
|
+
// count → 3 (COUNTA)
|
|
546
|
+
// max → 4
|
|
547
|
+
// min → 5
|
|
548
|
+
// stdDev → 7 (sample std dev, per Excel's totals UI)
|
|
549
|
+
// var → 10 (sample variance, per Excel's totals UI)
|
|
550
|
+
// sum → 9
|
|
538
551
|
Table.SUBTOTAL_FUNCTIONS = {
|
|
539
552
|
average: 101,
|
|
540
553
|
countNums: 102,
|
|
541
554
|
count: 103,
|
|
542
555
|
max: 104,
|
|
543
556
|
min: 105,
|
|
544
|
-
stdDev:
|
|
545
|
-
var:
|
|
557
|
+
stdDev: 107,
|
|
558
|
+
var: 110,
|
|
546
559
|
sum: 109
|
|
547
560
|
};
|
|
548
561
|
export { Table, sanitizeTableName };
|
|
@@ -299,6 +299,21 @@ const colCache = {
|
|
|
299
299
|
throw new InvalidAddressError(String(args.length), "Can only encode with 2 or 4 arguments");
|
|
300
300
|
}
|
|
301
301
|
},
|
|
302
|
+
/**
|
|
303
|
+
* Compare two cell addresses by column then row (numeric order).
|
|
304
|
+
*
|
|
305
|
+
* Returns a negative number if `a` should come before `b`,
|
|
306
|
+
* a positive number if `a` should come after `b`, or zero if equal.
|
|
307
|
+
*
|
|
308
|
+
* This avoids the pitfalls of `localeCompare` which treats addresses
|
|
309
|
+
* as strings (e.g. "C10" < "C2") instead of comparing their numeric
|
|
310
|
+
* column and row components.
|
|
311
|
+
*/
|
|
312
|
+
compareAddress(a, b) {
|
|
313
|
+
const addrA = colCache.decodeAddress(a);
|
|
314
|
+
const addrB = colCache.decodeAddress(b);
|
|
315
|
+
return addrA.col - addrB.col || addrA.row - addrB.row;
|
|
316
|
+
},
|
|
302
317
|
// return true if address is contained within range
|
|
303
318
|
inRange(range, address) {
|
|
304
319
|
const [left, top, , right, bottom] = range;
|
|
@@ -101,6 +101,10 @@ export function filterDrawingAnchors(anchors) {
|
|
|
101
101
|
if (a == null) {
|
|
102
102
|
return false;
|
|
103
103
|
}
|
|
104
|
+
// Absolute anchors need a valid picture
|
|
105
|
+
if (a.range?.pos !== undefined) {
|
|
106
|
+
return !!a.picture;
|
|
107
|
+
}
|
|
104
108
|
// Form controls have range.br and shape properties
|
|
105
109
|
if (a.range?.br && a.shape) {
|
|
106
110
|
return true;
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for manipulating the external-workbook prefix in formula strings.
|
|
3
|
+
*
|
|
4
|
+
* Excel formula strings containing external workbook references have the
|
|
5
|
+
* shape `[<workbook>]Sheet!Ref` where `<workbook>` is either
|
|
6
|
+
*
|
|
7
|
+
* - a 1-based numeric index — `[1]Sheet1!A1` (the canonical on-disk form
|
|
8
|
+
* stored inside `<f>` elements of worksheet XML), or
|
|
9
|
+
* - a filename / relative path — `[测试.xlsx]Sheet1!A1` (what Excel
|
|
10
|
+
* displays in the formula bar; not part of the OOXML storage contract,
|
|
11
|
+
* but produced by hand-written formulas and some older tools).
|
|
12
|
+
*
|
|
13
|
+
* When writing, excelts always emits the numeric form — indices map
|
|
14
|
+
* positionally into the workbook's `<externalReferences>` list. When a
|
|
15
|
+
* formula arrives with the filename form, the writer assigns (or reuses) an
|
|
16
|
+
* ExternalLinkModel with that filename as its `target` and rewrites the
|
|
17
|
+
* formula to the numeric form. This matches how Excel itself stores formulas
|
|
18
|
+
* and makes them round-trippable.
|
|
19
|
+
*
|
|
20
|
+
* The quoted variant `'[file.xlsx]Sheet with space'!A1` is handled too — Excel
|
|
21
|
+
* wraps the `[name]Sheet` segment in single quotes when the sheet name needs
|
|
22
|
+
* quoting. The matching logic here recognises both the unquoted and quoted
|
|
23
|
+
* forms, rewriting inside the quotes when needed.
|
|
24
|
+
*
|
|
25
|
+
* Edge cases we explicitly *do not* treat as external refs:
|
|
26
|
+
* - `[@Column]`, `[#Headers]`, `[Column Name]` — table structured refs
|
|
27
|
+
* (no `]Sheet!` tail). The regex requires the `]<sheet>!` follow-up,
|
|
28
|
+
* which structured refs never have.
|
|
29
|
+
* - Array literals `{1,2;3,4}` use `{}`, not `[]`.
|
|
30
|
+
* - String literals `"[Book]Sheet!A1"` — handled by scanning only outside
|
|
31
|
+
* string literal regions.
|
|
32
|
+
*/
|
|
33
|
+
// Matches an external-ref prefix in a formula:
|
|
34
|
+
// Group 1 captures the workbook token inside [...], which is either
|
|
35
|
+
// digits-only (numeric form) or a filename that may include path separators
|
|
36
|
+
// when the whole prefix is single-quoted.
|
|
37
|
+
//
|
|
38
|
+
// Two variants:
|
|
39
|
+
// 1. Unquoted: [Book]Sheet!A1 — Windows-filename-safe chars only in
|
|
40
|
+
// workbook token, then identifier sheet name, then !
|
|
41
|
+
// 2. Quoted: '[path/to/Book]Sheet name'!A1 — quoted segment allows
|
|
42
|
+
// paths / spaces / most punctuation inside the brackets; the sheet
|
|
43
|
+
// name inside the quotes can contain anything except `'` (escaped as '')
|
|
44
|
+
//
|
|
45
|
+
// The regex matches through and including the trailing `!` so callers don't
|
|
46
|
+
// have to re-parse the A1/range part.
|
|
47
|
+
// Unquoted form: workbook token must not contain characters that would
|
|
48
|
+
// make the formula string ambiguous ( ] / \ space). This matches what Excel
|
|
49
|
+
// itself writes for the bare-filename case — anything more exotic is
|
|
50
|
+
// written in the quoted form by Excel.
|
|
51
|
+
const UNQUOTED_EXTERNAL_REF = /\[([^\]\\/:*?"<>|\s]+)\]([A-Za-z_\u00A1-\uFFFF][A-Za-z0-9_\u00A1-\uFFFF.]*)!/g;
|
|
52
|
+
// Quoted form: everything inside [] is permissive (any char except `]`),
|
|
53
|
+
// since the outer `'..'` quotes absorb the surrounding formula
|
|
54
|
+
// delimiters. Sheet name inside quotes is likewise permissive (any char
|
|
55
|
+
// except `'`, with `''` representing an escaped quote).
|
|
56
|
+
const QUOTED_EXTERNAL_REF = /'\[([^\]]+)\]((?:''|[^'])+)'!/g;
|
|
57
|
+
/**
|
|
58
|
+
* Scan a formula string for all external-workbook references. String
|
|
59
|
+
* literals (inside `"..."`) are skipped so that a string value like
|
|
60
|
+
* `"[Book]Sheet!A1"` is not misidentified as a ref.
|
|
61
|
+
*
|
|
62
|
+
* The returned matches are in source order. If a formula contains no
|
|
63
|
+
* external refs, the array is empty.
|
|
64
|
+
*/
|
|
65
|
+
export function findExternalRefs(formula) {
|
|
66
|
+
// Fast-fail: external refs always include a `[`. Skipping the
|
|
67
|
+
// string-literal scan + two regex passes for plain cell refs (A1+B1,
|
|
68
|
+
// SUM(A1:A5), 99% of real workbooks) saves noticeable time on large
|
|
69
|
+
// sheets with thousands of formulas.
|
|
70
|
+
if (formula.indexOf("[") === -1) {
|
|
71
|
+
return [];
|
|
72
|
+
}
|
|
73
|
+
const matches = [];
|
|
74
|
+
const safeRegions = stringLiteralRegions(formula);
|
|
75
|
+
const addMatch = (start, end, workbook, sheet, quoted, match) => {
|
|
76
|
+
if (insideAnyRegion(start, safeRegions)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const numeric = /^\d+$/.test(workbook);
|
|
80
|
+
matches.push({
|
|
81
|
+
match,
|
|
82
|
+
workbook,
|
|
83
|
+
numeric,
|
|
84
|
+
index: numeric ? parseInt(workbook, 10) : null,
|
|
85
|
+
sheet: unquoteSheetName(sheet),
|
|
86
|
+
quoted,
|
|
87
|
+
start,
|
|
88
|
+
end
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
UNQUOTED_EXTERNAL_REF.lastIndex = 0;
|
|
92
|
+
let m;
|
|
93
|
+
while ((m = UNQUOTED_EXTERNAL_REF.exec(formula)) !== null) {
|
|
94
|
+
addMatch(m.index, m.index + m[0].length, m[1], m[2], false, m[0]);
|
|
95
|
+
}
|
|
96
|
+
QUOTED_EXTERNAL_REF.lastIndex = 0;
|
|
97
|
+
while ((m = QUOTED_EXTERNAL_REF.exec(formula)) !== null) {
|
|
98
|
+
addMatch(m.index, m.index + m[0].length, m[1], m[2], true, m[0]);
|
|
99
|
+
}
|
|
100
|
+
// Sort matches by start offset so callers can process them in source
|
|
101
|
+
// order (needed when rewriting with offset bookkeeping).
|
|
102
|
+
matches.sort((a, b) => a.start - b.start);
|
|
103
|
+
// Deduplicate overlapping matches (the unquoted regex can technically
|
|
104
|
+
// match a prefix of a quoted sheet name in pathological inputs). Take
|
|
105
|
+
// the first of any overlap.
|
|
106
|
+
const out = [];
|
|
107
|
+
let lastEnd = -1;
|
|
108
|
+
for (const ref of matches) {
|
|
109
|
+
if (ref.start >= lastEnd) {
|
|
110
|
+
out.push(ref);
|
|
111
|
+
lastEnd = ref.end;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Replace every external-workbook token in `formula` using the supplied
|
|
118
|
+
* resolver. The resolver is called once per match and returns the numeric
|
|
119
|
+
* index to substitute; returning `null` leaves the match unchanged (useful
|
|
120
|
+
* when the caller cannot resolve a particular filename).
|
|
121
|
+
*
|
|
122
|
+
* Returns the rewritten formula. Offsets inside the original formula are
|
|
123
|
+
* adjusted correctly even when multiple rewrites change the total length.
|
|
124
|
+
*/
|
|
125
|
+
export function rewriteExternalRefs(formula, resolve) {
|
|
126
|
+
const refs = findExternalRefs(formula);
|
|
127
|
+
if (refs.length === 0) {
|
|
128
|
+
return formula;
|
|
129
|
+
}
|
|
130
|
+
let out = "";
|
|
131
|
+
let cursor = 0;
|
|
132
|
+
for (const ref of refs) {
|
|
133
|
+
const index = resolve(ref);
|
|
134
|
+
if (index === null) {
|
|
135
|
+
continue; // leave this ref alone; cursor stays put
|
|
136
|
+
}
|
|
137
|
+
out += formula.slice(cursor, ref.start);
|
|
138
|
+
// Construct the replacement: keep the quoted/unquoted shape, swap the
|
|
139
|
+
// workbook token for [N], preserve the sheet segment exactly.
|
|
140
|
+
if (ref.quoted) {
|
|
141
|
+
// The quoted variant surrounds `[Book]Sheet` with single quotes,
|
|
142
|
+
// followed by `!`. We swap the [Book] part for [N] and keep the
|
|
143
|
+
// rest (including the closing `'!`) unchanged so sheet-name
|
|
144
|
+
// quoting is preserved exactly.
|
|
145
|
+
const inner = formula.slice(ref.start + 1, ref.end - 2); // between quotes, excluding trailing '!
|
|
146
|
+
out += "'" + inner.replace(/^\[[^\]]*\]/, `[${index}]`) + "'!";
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
out += `[${index}]${ref.match.slice(ref.match.indexOf("]") + 1)}`;
|
|
150
|
+
}
|
|
151
|
+
cursor = ref.end;
|
|
152
|
+
}
|
|
153
|
+
out += formula.slice(cursor);
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
// ===========================================================================
|
|
157
|
+
// Internal helpers
|
|
158
|
+
// ===========================================================================
|
|
159
|
+
/**
|
|
160
|
+
* Return the spans of string literal regions in a formula, as half-open
|
|
161
|
+
* [start, end) intervals (exclusive of the surrounding quotes themselves).
|
|
162
|
+
* Used to skip external-ref matches that fall inside a string value.
|
|
163
|
+
*/
|
|
164
|
+
function stringLiteralRegions(formula) {
|
|
165
|
+
// Fast-fail when the formula has no double-quote at all — very common
|
|
166
|
+
// for pure arithmetic / reference formulas.
|
|
167
|
+
if (formula.indexOf('"') === -1) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
const regions = [];
|
|
171
|
+
const len = formula.length;
|
|
172
|
+
let i = 0;
|
|
173
|
+
while (i < len) {
|
|
174
|
+
if (formula[i] === '"') {
|
|
175
|
+
const start = i;
|
|
176
|
+
i++;
|
|
177
|
+
while (i < len) {
|
|
178
|
+
if (formula[i] === '"') {
|
|
179
|
+
if (i + 1 < len && formula[i + 1] === '"') {
|
|
180
|
+
i += 2; // escaped quote inside string — keep scanning
|
|
181
|
+
continue;
|
|
182
|
+
}
|
|
183
|
+
i++;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
i++;
|
|
187
|
+
}
|
|
188
|
+
regions.push([start, i]);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return regions;
|
|
195
|
+
}
|
|
196
|
+
function insideAnyRegion(pos, regions) {
|
|
197
|
+
for (const [a, b] of regions) {
|
|
198
|
+
if (pos >= a && pos < b) {
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
function unquoteSheetName(sheet) {
|
|
205
|
+
// The quoted form captured inside `'..'` may have doubled single quotes
|
|
206
|
+
// that represent a single quote in the logical sheet name.
|
|
207
|
+
return sheet.replace(/''/g, "'");
|
|
208
|
+
}
|
|
@@ -8,7 +8,8 @@ export const OOXML_PATHS = {
|
|
|
8
8
|
xlSharedStrings: "xl/sharedStrings.xml",
|
|
9
9
|
xlStyles: "xl/styles.xml",
|
|
10
10
|
xlTheme1: "xl/theme/theme1.xml",
|
|
11
|
-
xlFeaturePropertyBag: "xl/featurePropertyBag/featurePropertyBag.xml"
|
|
11
|
+
xlFeaturePropertyBag: "xl/featurePropertyBag/featurePropertyBag.xml",
|
|
12
|
+
xlMetadata: "xl/metadata.xml"
|
|
12
13
|
};
|
|
13
14
|
const worksheetXmlRegex = /^xl\/worksheets\/sheet(\d+)[.]xml$/;
|
|
14
15
|
const worksheetRelsXmlRegex = /^xl\/worksheets\/_rels\/sheet(\d+)[.]xml[.]rels$/;
|
|
@@ -25,6 +26,9 @@ const pivotTableRelsXmlRegex = /^xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.
|
|
|
25
26
|
const pivotCacheDefinitionXmlRegex = /^xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml$/;
|
|
26
27
|
const pivotCacheDefinitionRelsXmlRegex = /^xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels$/;
|
|
27
28
|
const pivotCacheRecordsXmlRegex = /^xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml$/;
|
|
29
|
+
// External workbook links (xl/externalLinks/externalLink{n}.xml and its rels)
|
|
30
|
+
const externalLinkXmlRegex = /^xl\/externalLinks\/externalLink(\d+)[.]xml$/;
|
|
31
|
+
const externalLinkRelsXmlRegex = /^xl\/externalLinks\/_rels\/externalLink(\d+)[.]xml[.]rels$/;
|
|
28
32
|
export function normalizeZipPath(path) {
|
|
29
33
|
return path.startsWith("/") ? path.slice(1) : path;
|
|
30
34
|
}
|
|
@@ -105,6 +109,22 @@ export function getPivotCacheRecordsNameFromPath(path) {
|
|
|
105
109
|
const match = pivotCacheRecordsXmlRegex.exec(path);
|
|
106
110
|
return match ? match[1] : undefined;
|
|
107
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* Extract the 1-based index `N` from `xl/externalLinks/externalLink{N}.xml`.
|
|
114
|
+
* Returns the raw integer (e.g. `1` for externalLink1.xml) or undefined.
|
|
115
|
+
*/
|
|
116
|
+
export function getExternalLinkIndexFromPath(path) {
|
|
117
|
+
const match = externalLinkXmlRegex.exec(path);
|
|
118
|
+
return match ? parseInt(match[1], 10) : undefined;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Extract the 1-based index `N` from
|
|
122
|
+
* `xl/externalLinks/_rels/externalLink{N}.xml.rels`.
|
|
123
|
+
*/
|
|
124
|
+
export function getExternalLinkIndexFromRelsPath(path) {
|
|
125
|
+
const match = externalLinkRelsXmlRegex.exec(path);
|
|
126
|
+
return match ? parseInt(match[1], 10) : undefined;
|
|
127
|
+
}
|
|
108
128
|
export function toContentTypesPartName(zipPath) {
|
|
109
129
|
// ContentTypes uses leading slash PartName (e.g. "/xl/workbook.xml").
|
|
110
130
|
return zipPath.startsWith("/") ? zipPath : `/${zipPath}`;
|
|
@@ -167,6 +187,20 @@ export function pivotTablePath(n) {
|
|
|
167
187
|
export function pivotTableRelsPath(n) {
|
|
168
188
|
return `xl/pivotTables/_rels/pivotTable${n}.xml.rels`;
|
|
169
189
|
}
|
|
190
|
+
// -------- External links --------
|
|
191
|
+
export function externalLinkPath(n) {
|
|
192
|
+
return `xl/externalLinks/externalLink${n}.xml`;
|
|
193
|
+
}
|
|
194
|
+
export function externalLinkRelsPath(n) {
|
|
195
|
+
return `xl/externalLinks/_rels/externalLink${n}.xml.rels`;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Build the `Target` value for an externalLink relationship inside
|
|
199
|
+
* `xl/_rels/workbook.xml.rels` (base: `xl/`).
|
|
200
|
+
*/
|
|
201
|
+
export function externalLinkRelTargetFromWorkbook(n) {
|
|
202
|
+
return `externalLinks/externalLink${n}.xml`;
|
|
203
|
+
}
|
|
170
204
|
export function pivotCacheDefinitionRelTargetFromPivotTable(n) {
|
|
171
205
|
return `../pivotCache/pivotCacheDefinition${n}.xml`;
|
|
172
206
|
}
|
|
@@ -175,7 +209,8 @@ export const OOXML_REL_TARGETS = {
|
|
|
175
209
|
workbookStyles: "styles.xml",
|
|
176
210
|
workbookSharedStrings: "sharedStrings.xml",
|
|
177
211
|
workbookTheme1: "theme/theme1.xml",
|
|
178
|
-
workbookFeaturePropertyBag: "featurePropertyBag/featurePropertyBag.xml"
|
|
212
|
+
workbookFeaturePropertyBag: "featurePropertyBag/featurePropertyBag.xml",
|
|
213
|
+
workbookMetadata: "metadata.xml"
|
|
179
214
|
};
|
|
180
215
|
export function pivotCacheDefinitionRelTargetFromWorkbook(n) {
|
|
181
216
|
// Target inside xl/_rels/workbook.xml.rels (base: xl/)
|
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical JSON serializer with sorted object keys.
|
|
3
|
+
*
|
|
4
|
+
* Used to derive an insertion-order-independent dedupe key for rich-text
|
|
5
|
+
* shared-string entries. Two semantically identical run/font objects must
|
|
6
|
+
* map to the same key regardless of the order their properties were assigned.
|
|
7
|
+
*/
|
|
8
|
+
function canonicalStringify(value) {
|
|
9
|
+
if (value === null || typeof value !== "object") {
|
|
10
|
+
return JSON.stringify(value);
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(value)) {
|
|
13
|
+
return `[${value.map(canonicalStringify).join(",")}]`;
|
|
14
|
+
}
|
|
15
|
+
const keys = Object.keys(value).sort();
|
|
16
|
+
const obj = value;
|
|
17
|
+
return `{${keys.map(k => `${JSON.stringify(k)}:${canonicalStringify(obj[k])}`).join(",")}}`;
|
|
18
|
+
}
|
|
1
19
|
class SharedStrings {
|
|
2
20
|
constructor() {
|
|
3
21
|
this._values = [];
|
|
@@ -17,9 +35,10 @@ class SharedStrings {
|
|
|
17
35
|
return this._values[index];
|
|
18
36
|
}
|
|
19
37
|
add(value) {
|
|
20
|
-
|
|
38
|
+
const key = typeof value === "string" ? `s:${value}` : `r:${canonicalStringify(value.richText)}`;
|
|
39
|
+
let index = this._hash[key];
|
|
21
40
|
if (index === undefined) {
|
|
22
|
-
index = this._hash[
|
|
41
|
+
index = this._hash[key] = this._values.length;
|
|
23
42
|
this._values.push(value);
|
|
24
43
|
}
|
|
25
44
|
this._totalRefs++;
|