@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,16 +15,19 @@ const zip_parser_1 = require("../../archive/unzip/zip-parser.js");
|
|
|
15
15
|
const stream_1 = require("../../archive/zip/stream.js");
|
|
16
16
|
const errors_1 = require("../errors.js");
|
|
17
17
|
const drawing_utils_1 = require("../utils/drawing-utils.js");
|
|
18
|
+
const external_link_formula_1 = require("../utils/external-link-formula.js");
|
|
18
19
|
const ooxml_paths_1 = require("../utils/ooxml-paths.js");
|
|
19
20
|
const passthrough_manager_1 = require("../utils/passthrough-manager.js");
|
|
20
21
|
const stream_buf_1 = require("../utils/stream-buf.js");
|
|
21
22
|
const rel_type_1 = require("./rel-type.js");
|
|
23
|
+
const external_link_xform_1 = require("./xform/book/external-link-xform.js");
|
|
22
24
|
const workbook_xform_1 = require("./xform/book/workbook-xform.js");
|
|
23
25
|
const comments_xform_1 = require("./xform/comment/comments-xform.js");
|
|
24
26
|
const app_xform_1 = require("./xform/core/app-xform.js");
|
|
25
27
|
const content_types_xform_1 = require("./xform/core/content-types-xform.js");
|
|
26
28
|
const core_xform_1 = require("./xform/core/core-xform.js");
|
|
27
29
|
const feature_property_bag_xform_1 = require("./xform/core/feature-property-bag-xform.js");
|
|
30
|
+
const metadata_xform_1 = require("./xform/core/metadata-xform.js");
|
|
28
31
|
const relationships_xform_1 = require("./xform/core/relationships-xform.js");
|
|
29
32
|
const ctrl_prop_xform_1 = require("./xform/drawing/ctrl-prop-xform.js");
|
|
30
33
|
const drawing_xform_1 = require("./xform/drawing/drawing-xform.js");
|
|
@@ -245,6 +248,31 @@ class StreamingZipWriterAdapter {
|
|
|
245
248
|
}
|
|
246
249
|
}
|
|
247
250
|
StreamingZipWriterAdapter.textEncoder = new TextEncoder();
|
|
251
|
+
/**
|
|
252
|
+
* Extract the trailing integer from a workbook-rels Target like
|
|
253
|
+
* `"externalLinks/externalLink12.xml"` (a path relative to `xl/`). Mirror
|
|
254
|
+
* of {@link getExternalLinkIndexFromPath} which takes the full
|
|
255
|
+
* `xl/externalLinks/…` form. Used during reconcile to bridge the
|
|
256
|
+
* workbook.xml.rels entry to the parsed externalLinkN.xml part.
|
|
257
|
+
*/
|
|
258
|
+
function externalLinkIndexFromRelTarget(target) {
|
|
259
|
+
const match = /(?:^|\/)externalLink(\d+)[.]xml$/.exec(target);
|
|
260
|
+
return match ? parseInt(match[1], 10) : undefined;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Add `sheetName` to an ExternalLinkModel's `sheetNames` list if it isn't
|
|
264
|
+
* already present. Ordering is preserved — the first-seen sheet wins
|
|
265
|
+
* position 0, which matches what Excel does when writing externalLinks
|
|
266
|
+
* itself.
|
|
267
|
+
*/
|
|
268
|
+
function upsertSheet(link, sheetName) {
|
|
269
|
+
if (!sheetName) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
if (!link.sheetNames.includes(sheetName)) {
|
|
273
|
+
link.sheetNames.push(sheetName);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
248
276
|
/**
|
|
249
277
|
* XLSX class - handles Excel file operations
|
|
250
278
|
* Works in both Node.js and Browser environments
|
|
@@ -313,10 +341,12 @@ class XLSX {
|
|
|
313
341
|
await this.addDrawings(zip, model);
|
|
314
342
|
await this.addTables(zip, model);
|
|
315
343
|
await this.addPivotTables(zip, model);
|
|
344
|
+
await this.addExternalLinks(zip, model);
|
|
316
345
|
this.addPassthrough(zip, model);
|
|
317
346
|
await this.addThemes(zip, model);
|
|
318
347
|
await this.addStyles(zip, model);
|
|
319
348
|
await this.addFeaturePropertyBag(zip, model);
|
|
349
|
+
await this.addMetadata(zip, model);
|
|
320
350
|
await this.addMedia(zip, model);
|
|
321
351
|
await this.addApp(zip, model);
|
|
322
352
|
await this.addCore(zip, model);
|
|
@@ -366,32 +396,44 @@ class XLSX {
|
|
|
366
396
|
return this._finalize(zip);
|
|
367
397
|
}
|
|
368
398
|
/**
|
|
369
|
-
* Load workbook from
|
|
399
|
+
* Load a workbook from binary data.
|
|
400
|
+
*
|
|
401
|
+
* Accepted inputs:
|
|
402
|
+
* - `Uint8Array` (and `Buffer`, which is a Uint8Array at runtime)
|
|
403
|
+
* - `ArrayBuffer` / `SharedArrayBuffer`
|
|
404
|
+
* - Any `ArrayBufferView` (DataView, Int8Array, Float32Array, …) — the
|
|
405
|
+
* underlying bytes are reinterpreted as a zip archive
|
|
406
|
+
* - `string` — treated as base64-encoded data when `options.base64 === true`;
|
|
407
|
+
* raw binary cannot be round-tripped through a JS string and is rejected
|
|
408
|
+
* to prevent silent corruption.
|
|
370
409
|
*/
|
|
371
410
|
async load(data, options) {
|
|
372
|
-
|
|
373
|
-
// Validate input
|
|
374
|
-
const isBuffer = typeof Buffer !== "undefined" ? Buffer.isBuffer(data) : false;
|
|
375
|
-
if (!data ||
|
|
376
|
-
(typeof data === "object" &&
|
|
377
|
-
!isBuffer &&
|
|
378
|
-
!(data instanceof Uint8Array) &&
|
|
379
|
-
!(data instanceof ArrayBuffer))) {
|
|
411
|
+
if (data === null || data === undefined) {
|
|
380
412
|
throw new errors_1.ExcelFileError("<input>", "read", "Can't read the data of 'the loaded zip file'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?");
|
|
381
413
|
}
|
|
382
|
-
|
|
383
|
-
if (
|
|
384
|
-
|
|
414
|
+
let buffer;
|
|
415
|
+
if (typeof data === "string") {
|
|
416
|
+
// Strings must be base64-encoded — binary zip bytes cannot be round-tripped
|
|
417
|
+
// through a JS string without corruption. Require the explicit opt-in.
|
|
418
|
+
if (!options?.base64) {
|
|
419
|
+
throw new errors_1.ExcelFileError("<input>", "read", "Can't read the data of 'the loaded zip file'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ? " +
|
|
420
|
+
"String input requires options.base64 === true (base64-encoded zip archive).");
|
|
421
|
+
}
|
|
422
|
+
buffer = (0, utils_1.base64ToUint8Array)(data);
|
|
423
|
+
}
|
|
424
|
+
else if (data instanceof Uint8Array) {
|
|
425
|
+
// Covers Buffer (Node) and any typed-array view whose element size is 1.
|
|
426
|
+
buffer = data;
|
|
385
427
|
}
|
|
386
428
|
else if (data instanceof ArrayBuffer) {
|
|
387
429
|
buffer = new Uint8Array(data);
|
|
388
430
|
}
|
|
389
|
-
else if (data
|
|
390
|
-
|
|
431
|
+
else if (ArrayBuffer.isView(data)) {
|
|
432
|
+
// DataView, Int8Array, Float32Array, … — view onto an underlying buffer.
|
|
433
|
+
buffer = new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
|
|
391
434
|
}
|
|
392
435
|
else {
|
|
393
|
-
|
|
394
|
-
buffer = new Uint8Array(data);
|
|
436
|
+
throw new errors_1.ExcelFileError("<input>", "read", "Can't read the data of 'the loaded zip file'. Is it in a supported JavaScript type (String, Blob, ArrayBuffer, etc) ?");
|
|
395
437
|
}
|
|
396
438
|
return this.loadBuffer(buffer, options);
|
|
397
439
|
}
|
|
@@ -438,7 +480,15 @@ class XLSX {
|
|
|
438
480
|
pivotCacheDefinitions: {},
|
|
439
481
|
pivotCacheRecords: {},
|
|
440
482
|
// Passthrough storage for unknown/unsupported files (charts, etc.)
|
|
441
|
-
passthrough: {}
|
|
483
|
+
passthrough: {},
|
|
484
|
+
// External workbook links — parsed from xl/externalLinks/externalLinkN.xml
|
|
485
|
+
// during _processDefaultEntry, then reconciled into a dense
|
|
486
|
+
// ExternalLinkModel[] by reconcile() using workbookRels + <externalReferences>.
|
|
487
|
+
externalLinksByIndex: {},
|
|
488
|
+
// Raw rels from each externalLinkN.rels file, keyed by index.
|
|
489
|
+
// Contains the actual Target path (e.g. "测试.xlsx", "file:///...")
|
|
490
|
+
// and TargetMode ("External" / "Internal").
|
|
491
|
+
externalLinkRelsByIndex: {}
|
|
442
492
|
};
|
|
443
493
|
}
|
|
444
494
|
/**
|
|
@@ -498,8 +548,12 @@ class XLSX {
|
|
|
498
548
|
model.definedNames = workbook.definedNames;
|
|
499
549
|
model.views = workbook.views;
|
|
500
550
|
model.properties = workbook.properties;
|
|
551
|
+
model.protection = workbook.protection;
|
|
501
552
|
model.calcProperties = workbook.calcProperties;
|
|
502
553
|
model.pivotCaches = workbook.pivotCaches;
|
|
554
|
+
// Pass-through the ordered list of <externalReference> rIds. These
|
|
555
|
+
// get resolved into a dense externalLinks[] during reconcile().
|
|
556
|
+
model.externalReferences = workbook.externalReferences;
|
|
503
557
|
return true;
|
|
504
558
|
}
|
|
505
559
|
case ooxml_paths_1.OOXML_PATHS.xlSharedStrings:
|
|
@@ -528,6 +582,14 @@ class XLSX {
|
|
|
528
582
|
model.styles = new styles_xform_1.StylesXform();
|
|
529
583
|
await model.styles.parseStream(stream);
|
|
530
584
|
return true;
|
|
585
|
+
case ooxml_paths_1.OOXML_PATHS.xlMetadata: {
|
|
586
|
+
const metadataXform = new metadata_xform_1.MetadataXform();
|
|
587
|
+
const metadataResult = await metadataXform.parseStream(stream);
|
|
588
|
+
if (metadataResult) {
|
|
589
|
+
model.metadata = metadataResult;
|
|
590
|
+
}
|
|
591
|
+
return true;
|
|
592
|
+
}
|
|
531
593
|
default:
|
|
532
594
|
return false;
|
|
533
595
|
}
|
|
@@ -698,12 +760,21 @@ class XLSX {
|
|
|
698
760
|
comments: model.comments,
|
|
699
761
|
tables: model.tables,
|
|
700
762
|
vmlDrawings: model.vmlDrawings,
|
|
701
|
-
pivotTables: model.pivotTablesIndexed
|
|
763
|
+
pivotTables: model.pivotTablesIndexed,
|
|
764
|
+
hasDynamicArrayMetadata: !!model.metadata?.hasDynamicArrays,
|
|
765
|
+
dynamicArrayCmIndices: model.metadata?.dynamicArrayCmIndices
|
|
702
766
|
};
|
|
703
767
|
model.worksheets.forEach((worksheet) => {
|
|
704
768
|
worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
|
|
705
769
|
worksheetXform.reconcile(worksheet, sheetOptions);
|
|
706
770
|
});
|
|
771
|
+
// Reconcile external workbook links before workbookRels / externalReferences
|
|
772
|
+
// are dropped. Joins 3 sources:
|
|
773
|
+
// 1. model.externalReferences — ordered list of { rId } from workbook.xml
|
|
774
|
+
// 2. model.workbookRels — maps rId → target path (inside xl/)
|
|
775
|
+
// 3. model.externalLinksByIndex — parsed externalLinkN.xml parts
|
|
776
|
+
// 4. model.externalLinkRelsByIndex — parsed externalLinkN.xml.rels parts
|
|
777
|
+
this._reconcileExternalLinks(model);
|
|
707
778
|
// delete unnecessary parts
|
|
708
779
|
delete model.worksheetHash;
|
|
709
780
|
delete model.worksheetRels;
|
|
@@ -719,6 +790,180 @@ class XLSX {
|
|
|
719
790
|
delete model.drawingRels;
|
|
720
791
|
delete model.vmlDrawings;
|
|
721
792
|
delete model.pivotTableRels;
|
|
793
|
+
delete model.metadata;
|
|
794
|
+
// Internal-only scratch fields consumed by _reconcileExternalLinks.
|
|
795
|
+
delete model.externalReferences;
|
|
796
|
+
delete model.externalLinksByIndex;
|
|
797
|
+
delete model.externalLinkRelsByIndex;
|
|
798
|
+
}
|
|
799
|
+
/**
|
|
800
|
+
* Join the three on-disk sources that together describe external workbook
|
|
801
|
+
* references into a single dense `model.externalLinks: ExternalLinkModel[]`.
|
|
802
|
+
*
|
|
803
|
+
* Sources:
|
|
804
|
+
* - `<externalReferences>` list in workbook.xml (declaration order)
|
|
805
|
+
* - `xl/_rels/workbook.xml.rels` (rId → internal path)
|
|
806
|
+
* - `xl/externalLinks/externalLink{N}.xml` (sheet names, cached values)
|
|
807
|
+
* - `xl/externalLinks/_rels/externalLink{N}.xml.rels` (target, TargetMode)
|
|
808
|
+
*
|
|
809
|
+
* The 1-based index of each resulting ExternalLinkModel matches the `[N]`
|
|
810
|
+
* used in formula strings — this is the single source of truth formula
|
|
811
|
+
* code should rely on.
|
|
812
|
+
*/
|
|
813
|
+
_reconcileExternalLinks(model) {
|
|
814
|
+
const refs = model.externalReferences;
|
|
815
|
+
if (!refs || refs.length === 0) {
|
|
816
|
+
// Even when workbook.xml has no <externalReferences>, we may still
|
|
817
|
+
// have parsed externalLink parts (e.g. orphaned files); those are
|
|
818
|
+
// dropped silently rather than generating synthesised indices.
|
|
819
|
+
if (!model.externalLinks) {
|
|
820
|
+
model.externalLinks = [];
|
|
821
|
+
}
|
|
822
|
+
return;
|
|
823
|
+
}
|
|
824
|
+
const rels = (model.workbookRels ?? []);
|
|
825
|
+
const relById = new Map();
|
|
826
|
+
for (const rel of rels) {
|
|
827
|
+
if (rel.Type === rel_type_1.RelType.ExternalLink) {
|
|
828
|
+
relById.set(rel.Id, rel);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
const externalLinks = [];
|
|
832
|
+
for (let i = 0; i < refs.length; i++) {
|
|
833
|
+
const ref = refs[i];
|
|
834
|
+
const rel = relById.get(ref.rId);
|
|
835
|
+
if (!rel) {
|
|
836
|
+
// Broken reference — <externalReference> points at an rId that is
|
|
837
|
+
// not of type ExternalLink. We skip silently; the formula engine
|
|
838
|
+
// will see the now-missing index and fall back to #REF! as before.
|
|
839
|
+
continue;
|
|
840
|
+
}
|
|
841
|
+
// The rel Target is a path inside xl/ like "externalLinks/externalLink1.xml".
|
|
842
|
+
// Extract the trailing index to look up the parsed part.
|
|
843
|
+
const partIndex = externalLinkIndexFromRelTarget(rel.Target);
|
|
844
|
+
if (partIndex === undefined) {
|
|
845
|
+
continue;
|
|
846
|
+
}
|
|
847
|
+
const parsed = model.externalLinksByIndex[partIndex];
|
|
848
|
+
const partRels = (model.externalLinkRelsByIndex[partIndex] ?? []);
|
|
849
|
+
// Locate the externalLinkPath rel (should be unique within a part).
|
|
850
|
+
const pathRel = partRels.find(r => r.Type === rel_type_1.RelType.ExternalLinkPath) ??
|
|
851
|
+
partRels.find(r => r.TargetMode === "External");
|
|
852
|
+
externalLinks.push({
|
|
853
|
+
index: i + 1,
|
|
854
|
+
rId: ref.rId,
|
|
855
|
+
target: pathRel?.Target ?? "",
|
|
856
|
+
targetMode: pathRel?.TargetMode ?? "External",
|
|
857
|
+
sheetNames: parsed?.sheetNames ?? [],
|
|
858
|
+
cachedValues: parsed?.cachedValues ?? {}
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
model.externalLinks = externalLinks;
|
|
862
|
+
}
|
|
863
|
+
/**
|
|
864
|
+
* Write-time pass that brings the workbook model into a shape the writer
|
|
865
|
+
* can serialise cleanly. Two concerns:
|
|
866
|
+
*
|
|
867
|
+
* 1. Build the final external-link list for this write, combining
|
|
868
|
+
* user-declared links (`wb.externalLinks`) with auto-discovered
|
|
869
|
+
* ones from previous writes (cached on the Workbook). The result
|
|
870
|
+
* is assigned to `model.externalLinks` and consumed by the writer;
|
|
871
|
+
* `wb.externalLinks` is **not** modified.
|
|
872
|
+
*
|
|
873
|
+
* 2. Scan every formula cell for `[Book]Sheet!` prefixes. Filename-form
|
|
874
|
+
* references that don't match an existing link trigger
|
|
875
|
+
* `_recordAutoExternalLink()` on the Workbook, which adds the target
|
|
876
|
+
* to the private writer cache (so subsequent writes are fixed-point
|
|
877
|
+
* stable) but leaves `wb.externalLinks` untouched.
|
|
878
|
+
*
|
|
879
|
+
* 3. Rewrite every external-ref formula so it uses the numeric `[N]`
|
|
880
|
+
* form, the canonical OOXML storage form. This mutation lands on
|
|
881
|
+
* the cell's model object — matching the library's existing
|
|
882
|
+
* write-time pattern for `ssId`, `styleId`, `si`, and `cm`.
|
|
883
|
+
* Subsequent writes see the `[N]` form directly and resolve it
|
|
884
|
+
* against `model.externalLinks`, giving idempotent output.
|
|
885
|
+
*/
|
|
886
|
+
_normaliseExternalLinks(model) {
|
|
887
|
+
// Start from user-declared links, honouring their declaration order.
|
|
888
|
+
const links = this.workbook._collectExternalLinksForWrite();
|
|
889
|
+
// Fast lookup: case-insensitive target → link object in `links`.
|
|
890
|
+
const byTarget = new Map();
|
|
891
|
+
for (const link of links) {
|
|
892
|
+
if (link.target) {
|
|
893
|
+
byTarget.set(link.target.toLowerCase(), link);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
const scratch = { links, byTarget, workbook: this.workbook };
|
|
897
|
+
for (const worksheet of model.worksheets ?? []) {
|
|
898
|
+
for (const row of worksheet.rows ?? []) {
|
|
899
|
+
for (const cell of row.cells ?? []) {
|
|
900
|
+
if (typeof cell?.formula === "string" && cell.formula.length > 0) {
|
|
901
|
+
cell.formula = this._normaliseFormulaExternalRefs(cell.formula, scratch);
|
|
902
|
+
}
|
|
903
|
+
if (typeof cell?.sharedFormula === "string" && cell.sharedFormula.length > 0) {
|
|
904
|
+
// Shared-formula clones typically carry the master's *address*
|
|
905
|
+
// here, not a formula body — they won't match the ref regex.
|
|
906
|
+
// Masters carry the formula on `.formula` (handled above).
|
|
907
|
+
// We rewrite defensively in case a caller stored an actual
|
|
908
|
+
// formula string here.
|
|
909
|
+
cell.sharedFormula = this._normaliseFormulaExternalRefs(cell.sharedFormula, scratch);
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
model.externalLinks = links;
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Rewrite a single formula so every external-ref prefix uses the numeric
|
|
918
|
+
* `[N]` form. When an unknown filename-form reference is found we record
|
|
919
|
+
* it on the workbook's private writer cache (so the next write can still
|
|
920
|
+
* resolve it) and append a local link to `scratch.links` so subsequent
|
|
921
|
+
* refs in the same formula see the freshly-assigned index.
|
|
922
|
+
*/
|
|
923
|
+
_normaliseFormulaExternalRefs(formula, scratch) {
|
|
924
|
+
// rewriteExternalRefs internally calls findExternalRefs and returns
|
|
925
|
+
// the original string unchanged when there are no matches — no need
|
|
926
|
+
// for a separate guard scan here.
|
|
927
|
+
return (0, external_link_formula_1.rewriteExternalRefs)(formula, ref => {
|
|
928
|
+
// Numeric ref: accept if it resolves, otherwise preserve verbatim so
|
|
929
|
+
// Excel surfaces `#REF!` at load time — same as the old behaviour
|
|
930
|
+
// for truly broken references.
|
|
931
|
+
if (ref.numeric) {
|
|
932
|
+
if (ref.index !== null && ref.index >= 1 && ref.index <= scratch.links.length) {
|
|
933
|
+
upsertSheet(scratch.links[ref.index - 1], ref.sheet);
|
|
934
|
+
return ref.index;
|
|
935
|
+
}
|
|
936
|
+
return null;
|
|
937
|
+
}
|
|
938
|
+
// Filename form — look up or auto-register.
|
|
939
|
+
const key = ref.workbook.toLowerCase();
|
|
940
|
+
let link = scratch.byTarget.get(key);
|
|
941
|
+
if (!link) {
|
|
942
|
+
const index = scratch.workbook._recordAutoExternalLink(ref.workbook, ref.sheet);
|
|
943
|
+
link = {
|
|
944
|
+
index,
|
|
945
|
+
target: ref.workbook,
|
|
946
|
+
targetMode: "External",
|
|
947
|
+
sheetNames: ref.sheet ? [ref.sheet] : [],
|
|
948
|
+
cachedValues: {}
|
|
949
|
+
};
|
|
950
|
+
// Keep the local writer list dense: insert at its future position.
|
|
951
|
+
// `_recordAutoExternalLink` guarantees `index` is user.length + cache.size
|
|
952
|
+
// at the time of insertion, which equals `scratch.links.length + 1`
|
|
953
|
+
// whenever we walk formulas sequentially.
|
|
954
|
+
scratch.links.push(link);
|
|
955
|
+
scratch.byTarget.set(key, link);
|
|
956
|
+
}
|
|
957
|
+
else {
|
|
958
|
+
upsertSheet(link, ref.sheet);
|
|
959
|
+
// Keep the workbook cache's sheetNames in sync so subsequent
|
|
960
|
+
// writes see the accumulated set.
|
|
961
|
+
if (ref.sheet) {
|
|
962
|
+
scratch.workbook._recordAutoExternalLink(ref.workbook, ref.sheet);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
return link.index;
|
|
966
|
+
});
|
|
722
967
|
}
|
|
723
968
|
/**
|
|
724
969
|
* Reconcile pivot tables by linking them to worksheets and their cache data.
|
|
@@ -974,6 +1219,29 @@ class XLSX {
|
|
|
974
1219
|
model.pivotCacheRecords[name] = cacheRecords;
|
|
975
1220
|
}
|
|
976
1221
|
}
|
|
1222
|
+
/**
|
|
1223
|
+
* Parse `xl/externalLinks/externalLink{N}.xml` into the intermediate
|
|
1224
|
+
* ParsedExternalLink shape. Reconciliation (joining with the rels file
|
|
1225
|
+
* and the workbook's `<externalReferences>` list) happens later in
|
|
1226
|
+
* {@link reconcile}.
|
|
1227
|
+
*/
|
|
1228
|
+
async _processExternalLinkEntry(stream, model, index) {
|
|
1229
|
+
const xform = new external_link_xform_1.ExternalLinkXform();
|
|
1230
|
+
const parsed = await xform.parseStream(stream);
|
|
1231
|
+
if (parsed) {
|
|
1232
|
+
model.externalLinksByIndex[index] = parsed;
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Parse `xl/externalLinks/_rels/externalLink{N}.xml.rels`. The Target /
|
|
1237
|
+
* TargetMode carried here is what Excel uses to locate the actual external
|
|
1238
|
+
* file at open time, so we must preserve it verbatim (including relative
|
|
1239
|
+
* paths like `"测试.xlsx"`).
|
|
1240
|
+
*/
|
|
1241
|
+
async _processExternalLinkRelsEntry(stream, model, index) {
|
|
1242
|
+
const relationships = await this.parseRels(stream);
|
|
1243
|
+
model.externalLinkRelsByIndex[index] = relationships ?? [];
|
|
1244
|
+
}
|
|
977
1245
|
// ===========================================================================
|
|
978
1246
|
// loadFromFiles - shared logic for loading from pre-extracted ZIP data
|
|
979
1247
|
// ===========================================================================
|
|
@@ -1085,6 +1353,20 @@ class XLSX {
|
|
|
1085
1353
|
await this._processPivotCacheRecordsEntry(stream, model, pivotCacheRecordsName);
|
|
1086
1354
|
return true;
|
|
1087
1355
|
}
|
|
1356
|
+
// External workbook links: xl/externalLinks/externalLinkN.xml and its
|
|
1357
|
+
// sibling _rels file. Both parts are required to reconstruct the
|
|
1358
|
+
// ExternalLinkModel (the .xml carries sheet names + cached values; the
|
|
1359
|
+
// .rels carries the target path and TargetMode).
|
|
1360
|
+
const externalLinkIndex = (0, ooxml_paths_1.getExternalLinkIndexFromPath)(entryName);
|
|
1361
|
+
if (externalLinkIndex !== undefined) {
|
|
1362
|
+
await this._processExternalLinkEntry(stream, model, externalLinkIndex);
|
|
1363
|
+
return true;
|
|
1364
|
+
}
|
|
1365
|
+
const externalLinkRelsIndex = (0, ooxml_paths_1.getExternalLinkIndexFromRelsPath)(entryName);
|
|
1366
|
+
if (externalLinkRelsIndex !== undefined) {
|
|
1367
|
+
await this._processExternalLinkRelsEntry(stream, model, externalLinkRelsIndex);
|
|
1368
|
+
return true;
|
|
1369
|
+
}
|
|
1088
1370
|
// Store passthrough files (charts, etc.) for preservation
|
|
1089
1371
|
if (passthrough_manager_1.PassthroughManager.isPassthroughPath(entryName)) {
|
|
1090
1372
|
// If raw data is available (loadFromFiles path), use it directly
|
|
@@ -1166,6 +1448,14 @@ class XLSX {
|
|
|
1166
1448
|
Target: ooxml_paths_1.OOXML_REL_TARGETS.workbookFeaturePropertyBag
|
|
1167
1449
|
});
|
|
1168
1450
|
}
|
|
1451
|
+
// Add metadata relationship for dynamic array formulas
|
|
1452
|
+
if (model.hasDynamicArrayFormulas) {
|
|
1453
|
+
relationships.push({
|
|
1454
|
+
Id: `rId${count++}`,
|
|
1455
|
+
Type: XLSX.RelType.SheetMetadata,
|
|
1456
|
+
Target: ooxml_paths_1.OOXML_REL_TARGETS.workbookMetadata
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1169
1459
|
// R9-B6: Deduplicate pivot cache relationships by cacheId. When multiple pivot
|
|
1170
1460
|
// tables share the same cache, only one workbook relationship should be created.
|
|
1171
1461
|
// Also assigns rId to each pivot table (R9-B7: typed on PivotTable interface).
|
|
@@ -1195,6 +1485,26 @@ class XLSX {
|
|
|
1195
1485
|
Target: (0, ooxml_paths_1.worksheetRelTarget)(worksheet.fileIndex)
|
|
1196
1486
|
});
|
|
1197
1487
|
});
|
|
1488
|
+
// External workbook link rels are written AFTER worksheets on purpose:
|
|
1489
|
+
// Excel tolerates either order, but stable ordering (worksheets then
|
|
1490
|
+
// externalLinks) keeps the emitted workbook.xml.rels diff-friendly for
|
|
1491
|
+
// round-trip tests. Each external link becomes a regular Relationship
|
|
1492
|
+
// entry targeting `externalLinks/externalLinkN.xml` inside `xl/`; the
|
|
1493
|
+
// actual external file path is pointed at by the nested
|
|
1494
|
+
// externalLinkN.xml.rels part written by addExternalLinks().
|
|
1495
|
+
//
|
|
1496
|
+
// The list items here are the deep-copies produced by
|
|
1497
|
+
// `_normaliseExternalLinks` — assigning `link.rId` is safe and does not
|
|
1498
|
+
// leak into the user's Workbook.externalLinks.
|
|
1499
|
+
const externalLinks = (model.externalLinks ?? []);
|
|
1500
|
+
for (const link of externalLinks) {
|
|
1501
|
+
link.rId = `rId${count++}`;
|
|
1502
|
+
relationships.push({
|
|
1503
|
+
Id: link.rId,
|
|
1504
|
+
Type: XLSX.RelType.ExternalLink,
|
|
1505
|
+
Target: (0, ooxml_paths_1.externalLinkRelTargetFromWorkbook)(link.index)
|
|
1506
|
+
});
|
|
1507
|
+
}
|
|
1198
1508
|
const xform = new relationships_xform_1.RelationshipsXform();
|
|
1199
1509
|
await this._renderToZip(zip, ooxml_paths_1.OOXML_PATHS.xlWorkbookRels, xform, relationships);
|
|
1200
1510
|
}
|
|
@@ -1204,6 +1514,14 @@ class XLSX {
|
|
|
1204
1514
|
}
|
|
1205
1515
|
await this._renderToZip(zip, ooxml_paths_1.OOXML_PATHS.xlFeaturePropertyBag, new feature_property_bag_xform_1.FeaturePropertyBagXform(), {});
|
|
1206
1516
|
}
|
|
1517
|
+
async addMetadata(zip, model) {
|
|
1518
|
+
if (!model.hasDynamicArrayFormulas) {
|
|
1519
|
+
return;
|
|
1520
|
+
}
|
|
1521
|
+
await this._renderToZip(zip, ooxml_paths_1.OOXML_PATHS.xlMetadata, new metadata_xform_1.MetadataXform(), {
|
|
1522
|
+
dynamicArrayCount: model.dynamicArrayCount
|
|
1523
|
+
});
|
|
1524
|
+
}
|
|
1207
1525
|
async addSharedStrings(zip, model) {
|
|
1208
1526
|
if (model.sharedStrings && model.sharedStrings.count) {
|
|
1209
1527
|
await this._renderToZip(zip, ooxml_paths_1.OOXML_PATHS.xlSharedStrings, model.sharedStrings, model.sharedStrings.model);
|
|
@@ -1319,6 +1637,41 @@ class XLSX {
|
|
|
1319
1637
|
}
|
|
1320
1638
|
}
|
|
1321
1639
|
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Write every external workbook reference into the archive. For each
|
|
1642
|
+
* {@link ExternalLinkModel} in `model.externalLinks` we emit two files:
|
|
1643
|
+
*
|
|
1644
|
+
* xl/externalLinks/externalLink{index}.xml — sheet names + cache
|
|
1645
|
+
* xl/externalLinks/_rels/externalLink{index}.xml.rels — target path
|
|
1646
|
+
*
|
|
1647
|
+
* The target-path rel carries `TargetMode="External"` with a **bare
|
|
1648
|
+
* relative** `Target` whenever the user supplied one. This is the single
|
|
1649
|
+
* line that makes Office / WPS resolve the referenced workbook relative
|
|
1650
|
+
* to the current file's directory (not the `%USERPROFILE%\Documents`
|
|
1651
|
+
* fallback) — the root of the behaviour reported in exceljs#3039.
|
|
1652
|
+
*/
|
|
1653
|
+
async addExternalLinks(zip, model) {
|
|
1654
|
+
const externalLinks = (model.externalLinks ?? []);
|
|
1655
|
+
if (externalLinks.length === 0) {
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
const externalLinkXform = new external_link_xform_1.ExternalLinkXform();
|
|
1659
|
+
const relsXform = new relationships_xform_1.RelationshipsXform();
|
|
1660
|
+
for (const link of externalLinks) {
|
|
1661
|
+
await this._renderToZip(zip, (0, ooxml_paths_1.externalLinkPath)(link.index), externalLinkXform, link);
|
|
1662
|
+
// Always rId1 — the externalLink part only ever has a single rel.
|
|
1663
|
+
// `TargetMode="External"` is what flags Office to look the file up
|
|
1664
|
+
// at workbook-open time rather than embed it.
|
|
1665
|
+
await this._renderToZip(zip, (0, ooxml_paths_1.externalLinkRelsPath)(link.index), relsXform, [
|
|
1666
|
+
{
|
|
1667
|
+
Id: "rId1",
|
|
1668
|
+
Type: XLSX.RelType.ExternalLinkPath,
|
|
1669
|
+
Target: link.target,
|
|
1670
|
+
TargetMode: link.targetMode ?? "External"
|
|
1671
|
+
}
|
|
1672
|
+
]);
|
|
1673
|
+
}
|
|
1674
|
+
}
|
|
1322
1675
|
/**
|
|
1323
1676
|
* Write passthrough files (charts, etc.) that were preserved during read.
|
|
1324
1677
|
* These files are written back unchanged to preserve unsupported features.
|
|
@@ -1412,6 +1765,18 @@ class XLSX {
|
|
|
1412
1765
|
const workbookXform = new workbook_xform_1.WorkbookXform();
|
|
1413
1766
|
const worksheetXform = new worksheet_xform_1.WorkSheetXform();
|
|
1414
1767
|
workbookXform.prepare(model);
|
|
1768
|
+
// Normalise external-workbook references before any formula rendering.
|
|
1769
|
+
// Two jobs:
|
|
1770
|
+
// 1. Scan every formula cell and make sure each referenced workbook
|
|
1771
|
+
// has a matching ExternalLinkModel in `model.externalLinks`, with
|
|
1772
|
+
// a stable 1-based index.
|
|
1773
|
+
// 2. Rewrite formula strings from `[filename.xlsx]Sheet!A1` to
|
|
1774
|
+
// `[N]Sheet!A1`, which is the canonical on-disk form Excel
|
|
1775
|
+
// expects inside `<f>` elements.
|
|
1776
|
+
//
|
|
1777
|
+
// Done once up-front (not per cell) so the index assignment is
|
|
1778
|
+
// deterministic and every cell sees the final externalLinks list.
|
|
1779
|
+
this._normaliseExternalLinks(model);
|
|
1415
1780
|
const worksheetOptions = {
|
|
1416
1781
|
sharedStrings: model.sharedStrings,
|
|
1417
1782
|
styles: model.styles,
|
|
@@ -1425,6 +1790,7 @@ class XLSX {
|
|
|
1425
1790
|
model.hasHeaderWatermark = false;
|
|
1426
1791
|
let tableCount = 0;
|
|
1427
1792
|
model.tables = [];
|
|
1793
|
+
const tableNameMap = new Map(); // name (lowercase) → worksheet name
|
|
1428
1794
|
model.worksheets.forEach((worksheet, index) => {
|
|
1429
1795
|
// Assign fileIndex early so that worksheet-xform.prepare() can use it
|
|
1430
1796
|
// for comment/VML relationship targets and content type names.
|
|
@@ -1432,6 +1798,16 @@ class XLSX {
|
|
|
1432
1798
|
// using the same fileIndex.
|
|
1433
1799
|
worksheet.fileIndex = index + 1;
|
|
1434
1800
|
worksheet.tables.forEach((table) => {
|
|
1801
|
+
// OOXML requires table names to be unique across the entire workbook
|
|
1802
|
+
// (case-insensitive). Detect duplicates early to produce a clear error
|
|
1803
|
+
// instead of generating a corrupt file that Excel must repair.
|
|
1804
|
+
const nameKey = table.name.toLowerCase();
|
|
1805
|
+
const existingSheet = tableNameMap.get(nameKey);
|
|
1806
|
+
if (existingSheet !== undefined) {
|
|
1807
|
+
throw new errors_1.TableError(`Duplicate table name "${table.name}": already used in worksheet "${existingSheet}". ` +
|
|
1808
|
+
`Table names must be unique across the entire workbook (case-insensitive).`);
|
|
1809
|
+
}
|
|
1810
|
+
tableNameMap.set(nameKey, worksheet.name);
|
|
1435
1811
|
tableCount++;
|
|
1436
1812
|
table.target = `table${tableCount}.xml`;
|
|
1437
1813
|
table.id = tableCount;
|
|
@@ -1441,6 +1817,20 @@ class XLSX {
|
|
|
1441
1817
|
});
|
|
1442
1818
|
// ContentTypesXform expects this flag
|
|
1443
1819
|
model.hasCheckboxes = model.styles.hasCheckboxes;
|
|
1820
|
+
// Scan all worksheets for dynamic array formulas.
|
|
1821
|
+
// cm=1 is assigned later by cell-xform.prepare() during worksheet rendering.
|
|
1822
|
+
let dynamicArrayCount = 0;
|
|
1823
|
+
model.worksheets.forEach((worksheet) => {
|
|
1824
|
+
(worksheet.rows ?? []).forEach((row) => {
|
|
1825
|
+
(row.cells ?? []).forEach((cell) => {
|
|
1826
|
+
if (cell.isDynamicArray) {
|
|
1827
|
+
dynamicArrayCount++;
|
|
1828
|
+
}
|
|
1829
|
+
});
|
|
1830
|
+
});
|
|
1831
|
+
});
|
|
1832
|
+
model.hasDynamicArrayFormulas = dynamicArrayCount > 0;
|
|
1833
|
+
model.dynamicArrayCount = dynamicArrayCount;
|
|
1444
1834
|
// Propagate header watermark flag from worksheet prepare options
|
|
1445
1835
|
if (worksheetOptions.hasHeaderWatermark) {
|
|
1446
1836
|
model.hasHeaderWatermark = true;
|
|
@@ -103,7 +103,7 @@ class XLSX extends xlsx_browser_1.XLSX {
|
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
105
|
catch (e) {
|
|
106
|
-
callback(e);
|
|
106
|
+
callback((0, errors_2.toError)(e));
|
|
107
107
|
}
|
|
108
108
|
},
|
|
109
109
|
final(callback) {
|
|
@@ -112,13 +112,13 @@ class XLSX extends xlsx_browser_1.XLSX {
|
|
|
112
112
|
callback();
|
|
113
113
|
}
|
|
114
114
|
catch (e) {
|
|
115
|
-
callback(e);
|
|
115
|
+
callback((0, errors_2.toError)(e));
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
});
|
|
119
119
|
const onParserError = (err) => {
|
|
120
120
|
try {
|
|
121
|
-
sink.destroy(err);
|
|
121
|
+
sink.destroy((0, errors_2.toError)(err));
|
|
122
122
|
}
|
|
123
123
|
catch {
|
|
124
124
|
// ignore
|
|
@@ -130,8 +130,7 @@ class XLSX extends xlsx_browser_1.XLSX {
|
|
|
130
130
|
for await (const entry of XLSX.iterateZipEntries(parser)) {
|
|
131
131
|
entry.on("error", swallowError);
|
|
132
132
|
const drain = async () => {
|
|
133
|
-
|
|
134
|
-
if (anyEntry?.readableEnded || anyEntry?.destroyed) {
|
|
133
|
+
if (entry.readableEnded || entry.destroyed) {
|
|
135
134
|
return;
|
|
136
135
|
}
|
|
137
136
|
const draining = entry.autodrain();
|