@cj-tech-master/excelts 9.4.2 → 9.5.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/dist/browser/index.browser.d.ts +8 -5
- package/dist/browser/index.browser.js +19 -1
- package/dist/browser/index.d.ts +4 -2
- package/dist/browser/index.js +9 -1
- package/dist/browser/modules/excel/chart/cache-populator.d.ts +49 -0
- package/dist/browser/modules/excel/chart/cache-populator.js +1171 -0
- package/dist/browser/modules/excel/chart/chart-api.d.ts +92 -0
- package/dist/browser/modules/excel/chart/chart-api.js +364 -0
- package/dist/browser/modules/excel/chart/chart-builder.d.ts +48 -0
- package/dist/browser/modules/excel/chart/chart-builder.js +2432 -0
- package/dist/browser/modules/excel/chart/chart-ex-builder.d.ts +36 -0
- package/dist/browser/modules/excel/chart/chart-ex-builder.js +903 -0
- package/dist/browser/modules/excel/chart/chart-ex-parser.d.ts +8 -0
- package/dist/browser/modules/excel/chart/chart-ex-parser.js +1205 -0
- package/dist/browser/modules/excel/chart/chart-ex-renderer.d.ts +187 -0
- package/dist/browser/modules/excel/chart/chart-ex-renderer.js +5352 -0
- package/dist/browser/modules/excel/chart/chart-ex-types.d.ts +531 -0
- package/dist/browser/modules/excel/chart/chart-ex-types.js +11 -0
- package/dist/browser/modules/excel/chart/chart-images.d.ts +78 -0
- package/dist/browser/modules/excel/chart/chart-images.js +363 -0
- package/dist/browser/modules/excel/chart/chart-presets.d.ts +392 -0
- package/dist/browser/modules/excel/chart/chart-presets.js +179 -0
- package/dist/browser/modules/excel/chart/chart-renderer.d.ts +550 -0
- package/dist/browser/modules/excel/chart/chart-renderer.js +6440 -0
- package/dist/browser/modules/excel/chart/chart-sidecar.d.ts +21 -0
- package/dist/browser/modules/excel/chart/chart-sidecar.js +427 -0
- package/dist/browser/modules/excel/chart/chart-utils.d.ts +306 -0
- package/dist/browser/modules/excel/chart/chart-utils.js +821 -0
- package/dist/browser/modules/excel/chart/chart.d.ts +504 -0
- package/dist/browser/modules/excel/chart/chart.js +1320 -0
- package/dist/browser/modules/excel/chart/glyph-rasterizer.d.ts +62 -0
- package/dist/browser/modules/excel/chart/glyph-rasterizer.js +658 -0
- package/dist/browser/modules/excel/chart/index.d.ts +54 -0
- package/dist/browser/modules/excel/chart/index.js +46 -0
- package/dist/browser/modules/excel/chart/install.d.ts +44 -0
- package/dist/browser/modules/excel/chart/install.js +91 -0
- package/dist/browser/modules/excel/chart/shape-properties.d.ts +156 -0
- package/dist/browser/modules/excel/chart/shape-properties.js +1557 -0
- package/dist/browser/modules/excel/chart/stroke-font.d.ts +36 -0
- package/dist/browser/modules/excel/chart/stroke-font.js +1556 -0
- package/dist/browser/modules/excel/chart/topojson.d.ts +98 -0
- package/dist/browser/modules/excel/chart/topojson.js +236 -0
- package/dist/browser/modules/excel/chart/types.d.ts +2559 -0
- package/dist/browser/modules/excel/chart/types.js +8 -0
- package/dist/browser/modules/excel/chart-host-registry.d.ts +157 -0
- package/dist/browser/modules/excel/chart-host-registry.js +90 -0
- package/dist/browser/modules/excel/chartsheet.d.ts +102 -0
- package/dist/browser/modules/excel/chartsheet.js +196 -0
- package/dist/browser/modules/excel/defined-names.d.ts +35 -0
- package/dist/browser/modules/excel/defined-names.js +44 -4
- package/dist/browser/modules/excel/errors.d.ts +6 -0
- package/dist/browser/modules/excel/errors.js +9 -0
- package/dist/browser/modules/excel/form-control.d.ts +6 -0
- package/dist/browser/modules/excel/form-control.js +17 -0
- package/dist/browser/modules/excel/image.js +12 -2
- package/dist/browser/modules/excel/pivot-chart.d.ts +7 -0
- package/dist/browser/modules/excel/pivot-chart.js +53 -0
- package/dist/browser/modules/excel/pivot-table.d.ts +55 -0
- package/dist/browser/modules/excel/pivot-table.js +35 -0
- package/dist/browser/modules/excel/range.js +5 -1
- package/dist/browser/modules/excel/sparkline/index.d.ts +7 -0
- package/dist/browser/modules/excel/sparkline/index.js +7 -0
- package/dist/browser/modules/excel/sparkline/sparkline.d.ts +206 -0
- package/dist/browser/modules/excel/sparkline/sparkline.js +750 -0
- package/dist/browser/modules/excel/stream/worksheet-writer.js +3 -2
- package/dist/browser/modules/excel/table.js +42 -6
- package/dist/browser/modules/excel/types.d.ts +72 -0
- package/dist/browser/modules/excel/utils/address.d.ts +18 -0
- package/dist/browser/modules/excel/utils/address.js +28 -0
- package/dist/browser/modules/excel/utils/drawing-utils.js +11 -6
- package/dist/browser/modules/excel/utils/guid.d.ts +15 -0
- package/dist/browser/modules/excel/utils/guid.js +35 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.d.ts +74 -0
- package/dist/browser/modules/excel/utils/ooxml-paths.js +206 -9
- package/dist/browser/modules/excel/utils/ooxml-validator/check-chart-sidecar.d.ts +35 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-chart-sidecar.js +101 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-chart.d.ts +32 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-chart.js +2125 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-chartsheet.d.ts +9 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-chartsheet.js +26 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-content-types.d.ts +16 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-content-types.js +181 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-drawing.d.ts +34 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-drawing.js +267 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-pivot.d.ts +14 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-pivot.js +104 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-relationships.d.ts +18 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-relationships.js +184 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-structure.d.ts +21 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-structure.js +56 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-styles.d.ts +15 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-styles.js +89 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-table.d.ts +31 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-table.js +177 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-workbook.d.ts +19 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-workbook.js +163 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-worksheet.d.ts +25 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/check-worksheet.js +569 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/context.d.ts +85 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/context.js +191 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/index.d.ts +31 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/index.js +102 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/path-utils.d.ts +67 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/path-utils.js +156 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/reporter.d.ts +41 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/reporter.js +61 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/types.d.ts +109 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/types.js +12 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/xml-utils.d.ts +38 -0
- package/dist/browser/modules/excel/utils/ooxml-validator/xml-utils.js +100 -0
- package/dist/browser/modules/excel/workbook.browser.d.ts +248 -30
- package/dist/browser/modules/excel/workbook.browser.js +966 -31
- package/dist/browser/modules/excel/workbook.d.ts +43 -0
- package/dist/browser/modules/excel/workbook.js +48 -0
- package/dist/browser/modules/excel/worksheet.d.ts +157 -3
- package/dist/browser/modules/excel/worksheet.js +394 -35
- package/dist/browser/modules/excel/xlsx/rel-type.d.ts +40 -0
- package/dist/browser/modules/excel/xlsx/rel-type.js +41 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +11 -2
- package/dist/browser/modules/excel/xlsx/xform/book/external-link-xform.js +12 -10
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +96 -22
- package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.d.ts +353 -0
- package/dist/browser/modules/excel/xlsx/xform/chart/chart-space-xform.js +6000 -0
- package/dist/browser/modules/excel/xlsx/xform/comment/threaded-comments-xform.d.ts +60 -0
- package/dist/browser/modules/excel/xlsx/xform/comment/threaded-comments-xform.js +213 -0
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +150 -11
- package/dist/browser/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +20 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +30 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.js +109 -5
- package/dist/browser/modules/excel/xlsx/xform/drawing/graphic-frame-xform.d.ts +54 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/graphic-frame-xform.js +225 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +3 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +18 -3
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +46 -0
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +294 -12
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +13 -2
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +32 -6
- package/dist/browser/modules/excel/xlsx/xform/sheet/chartsheet-xform.d.ts +185 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/chartsheet-xform.js +441 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ext-lst-xform.d.ts +1 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/ext-lst-xform.js +51 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +196 -20
- package/dist/browser/modules/excel/xlsx/xform/table/auto-filter-xform.js +16 -1
- package/dist/browser/modules/excel/xlsx/xform/table/table-column-xform.js +17 -2
- package/dist/browser/modules/excel/xlsx/xform/xsd-values.d.ts +63 -0
- package/dist/browser/modules/excel/xlsx/xform/xsd-values.js +101 -0
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +115 -21
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +4422 -78
- package/dist/browser/modules/pdf/builder/document-builder.d.ts +74 -0
- package/dist/browser/modules/pdf/builder/document-builder.js +507 -2
- package/dist/browser/modules/pdf/builder/pdf-editor.js +48 -3
- package/dist/browser/modules/pdf/excel-bridge.d.ts +69 -0
- package/dist/browser/modules/pdf/excel-bridge.js +683 -12
- package/dist/browser/modules/pdf/font/font-manager.d.ts +25 -0
- package/dist/browser/modules/pdf/font/font-manager.js +39 -0
- package/dist/browser/modules/pdf/index.d.ts +5 -2
- package/dist/browser/modules/pdf/index.js +3 -1
- package/dist/browser/modules/pdf/render/chart-surface.d.ts +33 -0
- package/dist/browser/modules/pdf/render/chart-surface.js +200 -0
- package/dist/browser/modules/pdf/render/layout-engine.d.ts +22 -1
- package/dist/browser/modules/pdf/render/layout-engine.js +436 -56
- package/dist/browser/modules/pdf/render/page-renderer.js +169 -28
- package/dist/browser/modules/pdf/render/pdf-exporter.js +117 -7
- package/dist/browser/modules/pdf/types.d.ts +227 -23
- package/dist/browser/modules/pdf/types.js +4 -0
- package/dist/browser/modules/pdf/word-bridge.d.ts +47 -0
- package/dist/browser/modules/pdf/word-bridge.js +304 -0
- package/dist/browser/modules/word/constants.d.ts +179 -0
- package/dist/browser/modules/word/constants.js +231 -0
- package/dist/browser/modules/word/content-types.d.ts +27 -0
- package/dist/browser/modules/word/content-types.js +53 -0
- package/dist/browser/modules/word/digital-signatures.d.ts +87 -0
- package/dist/browser/modules/word/digital-signatures.js +134 -0
- package/dist/browser/modules/word/document.d.ts +728 -0
- package/dist/browser/modules/word/document.js +1795 -0
- package/dist/browser/modules/word/docx-packager.d.ts +14 -0
- package/dist/browser/modules/word/docx-packager.js +822 -0
- package/dist/browser/modules/word/docx-reader.d.ts +11 -0
- package/dist/browser/modules/word/docx-reader.js +4929 -0
- package/dist/browser/modules/word/encryption.d.ts +102 -0
- package/dist/browser/modules/word/encryption.js +274 -0
- package/dist/browser/modules/word/errors.d.ts +49 -0
- package/dist/browser/modules/word/errors.js +68 -0
- package/dist/browser/modules/word/font-obfuscation.d.ts +31 -0
- package/dist/browser/modules/word/font-obfuscation.js +83 -0
- package/dist/browser/modules/word/html-renderer.d.ts +38 -0
- package/dist/browser/modules/word/html-renderer.js +782 -0
- package/dist/browser/modules/word/index.base.d.ts +19 -0
- package/dist/browser/modules/word/index.base.js +51 -0
- package/dist/browser/modules/word/index.browser.d.ts +4 -0
- package/dist/browser/modules/word/index.browser.js +4 -0
- package/dist/browser/modules/word/index.d.ts +4 -0
- package/dist/browser/modules/word/index.js +4 -0
- package/dist/browser/modules/word/internal-utils.d.ts +23 -0
- package/dist/browser/modules/word/internal-utils.js +54 -0
- package/dist/browser/modules/word/relationships.d.ts +31 -0
- package/dist/browser/modules/word/relationships.js +56 -0
- package/dist/browser/modules/word/types.d.ts +2325 -0
- package/dist/browser/modules/word/types.js +10 -0
- package/dist/browser/modules/word/units.d.ts +49 -0
- package/dist/browser/modules/word/units.js +111 -0
- package/dist/browser/modules/word/writers/chart-writer.d.ts +10 -0
- package/dist/browser/modules/word/writers/chart-writer.js +385 -0
- package/dist/browser/modules/word/writers/checkbox-writer.d.ts +9 -0
- package/dist/browser/modules/word/writers/checkbox-writer.js +42 -0
- package/dist/browser/modules/word/writers/comment-writer.d.ts +15 -0
- package/dist/browser/modules/word/writers/comment-writer.js +70 -0
- package/dist/browser/modules/word/writers/document-writer.d.ts +16 -0
- package/dist/browser/modules/word/writers/document-writer.js +461 -0
- package/dist/browser/modules/word/writers/footnote-writer.d.ts +11 -0
- package/dist/browser/modules/word/writers/footnote-writer.js +72 -0
- package/dist/browser/modules/word/writers/header-footer-writer.d.ts +13 -0
- package/dist/browser/modules/word/writers/header-footer-writer.js +129 -0
- package/dist/browser/modules/word/writers/image-writer.d.ts +10 -0
- package/dist/browser/modules/word/writers/image-writer.js +185 -0
- package/dist/browser/modules/word/writers/math-writer.d.ts +9 -0
- package/dist/browser/modules/word/writers/math-writer.js +428 -0
- package/dist/browser/modules/word/writers/numbering-writer.d.ts +10 -0
- package/dist/browser/modules/word/writers/numbering-writer.js +125 -0
- package/dist/browser/modules/word/writers/paragraph-writer.d.ts +13 -0
- package/dist/browser/modules/word/writers/paragraph-writer.js +516 -0
- package/dist/browser/modules/word/writers/parts-writer.d.ts +26 -0
- package/dist/browser/modules/word/writers/parts-writer.js +660 -0
- package/dist/browser/modules/word/writers/run-writer.d.ts +15 -0
- package/dist/browser/modules/word/writers/run-writer.js +649 -0
- package/dist/browser/modules/word/writers/section-writer.d.ts +10 -0
- package/dist/browser/modules/word/writers/section-writer.js +238 -0
- package/dist/browser/modules/word/writers/styles-writer.d.ts +10 -0
- package/dist/browser/modules/word/writers/styles-writer.js +242 -0
- package/dist/browser/modules/word/writers/table-writer.d.ts +10 -0
- package/dist/browser/modules/word/writers/table-writer.js +503 -0
- package/dist/browser/modules/word/writers/textbox-writer.d.ts +9 -0
- package/dist/browser/modules/word/writers/textbox-writer.js +53 -0
- package/dist/browser/modules/word/writers/toc-writer.d.ts +9 -0
- package/dist/browser/modules/word/writers/toc-writer.js +79 -0
- package/dist/browser/modules/xml/encode.d.ts +56 -7
- package/dist/browser/modules/xml/encode.js +157 -11
- package/dist/cjs/index.js +13 -2
- package/dist/cjs/modules/excel/chart/cache-populator.js +1178 -0
- package/dist/cjs/modules/excel/chart/chart-api.js +371 -0
- package/dist/cjs/modules/excel/chart/chart-builder.js +2440 -0
- package/dist/cjs/modules/excel/chart/chart-ex-builder.js +907 -0
- package/dist/cjs/modules/excel/chart/chart-ex-parser.js +1208 -0
- package/dist/cjs/modules/excel/chart/chart-ex-renderer.js +5364 -0
- package/dist/cjs/modules/excel/chart/chart-ex-types.js +12 -0
- package/dist/cjs/modules/excel/chart/chart-images.js +366 -0
- package/dist/cjs/modules/excel/chart/chart-presets.js +184 -0
- package/dist/cjs/modules/excel/chart/chart-renderer.js +6450 -0
- package/dist/cjs/modules/excel/chart/chart-sidecar.js +433 -0
- package/dist/cjs/modules/excel/chart/chart-utils.js +845 -0
- package/dist/cjs/modules/excel/chart/chart.js +1324 -0
- package/dist/cjs/modules/excel/chart/glyph-rasterizer.js +664 -0
- package/dist/cjs/modules/excel/chart/index.js +101 -0
- package/dist/cjs/modules/excel/chart/install.js +95 -0
- package/dist/cjs/modules/excel/chart/shape-properties.js +1577 -0
- package/dist/cjs/modules/excel/chart/stroke-font.js +1559 -0
- package/dist/cjs/modules/excel/chart/topojson.js +239 -0
- package/dist/cjs/modules/excel/chart/types.js +9 -0
- package/dist/cjs/modules/excel/chart-host-registry.js +96 -0
- package/dist/cjs/modules/excel/chartsheet.js +199 -0
- package/dist/cjs/modules/excel/defined-names.js +44 -4
- package/dist/cjs/modules/excel/errors.js +11 -1
- package/dist/cjs/modules/excel/form-control.js +17 -0
- package/dist/cjs/modules/excel/image.js +12 -2
- package/dist/cjs/modules/excel/pivot-chart.js +56 -0
- package/dist/cjs/modules/excel/pivot-table.js +35 -0
- package/dist/cjs/modules/excel/range.js +5 -1
- package/dist/cjs/modules/excel/sparkline/index.js +23 -0
- package/dist/cjs/modules/excel/sparkline/sparkline.js +756 -0
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +3 -2
- package/dist/cjs/modules/excel/table.js +42 -6
- package/dist/cjs/modules/excel/utils/address.js +29 -0
- package/dist/cjs/modules/excel/utils/drawing-utils.js +11 -6
- package/dist/cjs/modules/excel/utils/guid.js +38 -0
- package/dist/cjs/modules/excel/utils/ooxml-paths.js +246 -9
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-chart-sidecar.js +103 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-chart.js +2128 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-chartsheet.js +29 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-content-types.js +184 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-drawing.js +270 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-pivot.js +107 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-relationships.js +188 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-structure.js +60 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-styles.js +92 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-table.js +180 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-workbook.js +166 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/check-worksheet.js +572 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/context.js +196 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/index.js +105 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/path-utils.js +168 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/reporter.js +66 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/types.js +13 -0
- package/dist/cjs/modules/excel/utils/ooxml-validator/xml-utils.js +110 -0
- package/dist/cjs/modules/excel/workbook.browser.js +973 -38
- package/dist/cjs/modules/excel/workbook.js +48 -0
- package/dist/cjs/modules/excel/worksheet.js +393 -34
- package/dist/cjs/modules/excel/xlsx/rel-type.js +41 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +11 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/external-link-xform.js +12 -10
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +96 -22
- package/dist/cjs/modules/excel/xlsx/xform/chart/chart-space-xform.js +6003 -0
- package/dist/cjs/modules/excel/xlsx/xform/comment/threaded-comments-xform.js +219 -0
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +149 -10
- package/dist/cjs/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +20 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/drawing-xform.js +109 -5
- package/dist/cjs/modules/excel/xlsx/xform/drawing/graphic-frame-xform.js +228 -0
- package/dist/cjs/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +18 -3
- package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +294 -12
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +32 -6
- package/dist/cjs/modules/excel/xlsx/xform/sheet/chartsheet-xform.js +444 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/ext-lst-xform.js +51 -2
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +195 -19
- package/dist/cjs/modules/excel/xlsx/xform/table/auto-filter-xform.js +16 -1
- package/dist/cjs/modules/excel/xlsx/xform/table/table-column-xform.js +17 -2
- package/dist/cjs/modules/excel/xlsx/xform/xsd-values.js +106 -0
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +4420 -76
- package/dist/cjs/modules/pdf/builder/document-builder.js +506 -1
- package/dist/cjs/modules/pdf/builder/pdf-editor.js +48 -3
- package/dist/cjs/modules/pdf/excel-bridge.js +684 -12
- package/dist/cjs/modules/pdf/font/font-manager.js +39 -0
- package/dist/cjs/modules/pdf/index.js +5 -1
- package/dist/cjs/modules/pdf/render/chart-surface.js +203 -0
- package/dist/cjs/modules/pdf/render/layout-engine.js +437 -56
- package/dist/cjs/modules/pdf/render/page-renderer.js +169 -28
- package/dist/cjs/modules/pdf/render/pdf-exporter.js +115 -5
- package/dist/cjs/modules/pdf/types.js +5 -0
- package/dist/cjs/modules/pdf/word-bridge.js +307 -0
- package/dist/cjs/modules/word/constants.js +234 -0
- package/dist/cjs/modules/word/content-types.js +57 -0
- package/dist/cjs/modules/word/digital-signatures.js +140 -0
- package/dist/cjs/modules/word/document.js +1909 -0
- package/dist/cjs/modules/word/docx-packager.js +825 -0
- package/dist/cjs/modules/word/docx-reader.js +4932 -0
- package/dist/cjs/modules/word/encryption.js +282 -0
- package/dist/cjs/modules/word/errors.js +88 -0
- package/dist/cjs/modules/word/font-obfuscation.js +88 -0
- package/dist/cjs/modules/word/html-renderer.js +785 -0
- package/dist/cjs/modules/word/index.base.js +199 -0
- package/dist/cjs/modules/word/index.browser.js +20 -0
- package/dist/cjs/modules/word/index.js +20 -0
- package/dist/cjs/modules/word/internal-utils.js +59 -0
- package/dist/cjs/modules/word/relationships.js +60 -0
- package/dist/cjs/modules/word/types.js +11 -0
- package/dist/cjs/modules/word/units.js +135 -0
- package/dist/cjs/modules/word/writers/chart-writer.js +388 -0
- package/dist/cjs/modules/word/writers/checkbox-writer.js +45 -0
- package/dist/cjs/modules/word/writers/comment-writer.js +74 -0
- package/dist/cjs/modules/word/writers/document-writer.js +465 -0
- package/dist/cjs/modules/word/writers/footnote-writer.js +76 -0
- package/dist/cjs/modules/word/writers/header-footer-writer.js +134 -0
- package/dist/cjs/modules/word/writers/image-writer.js +188 -0
- package/dist/cjs/modules/word/writers/math-writer.js +431 -0
- package/dist/cjs/modules/word/writers/numbering-writer.js +128 -0
- package/dist/cjs/modules/word/writers/paragraph-writer.js +521 -0
- package/dist/cjs/modules/word/writers/parts-writer.js +671 -0
- package/dist/cjs/modules/word/writers/run-writer.js +655 -0
- package/dist/cjs/modules/word/writers/section-writer.js +241 -0
- package/dist/cjs/modules/word/writers/styles-writer.js +245 -0
- package/dist/cjs/modules/word/writers/table-writer.js +506 -0
- package/dist/cjs/modules/word/writers/textbox-writer.js +56 -0
- package/dist/cjs/modules/word/writers/toc-writer.js +82 -0
- package/dist/cjs/modules/xml/encode.js +158 -11
- package/dist/esm/index.browser.js +20 -2
- package/dist/esm/index.js +9 -1
- package/dist/esm/modules/excel/chart/cache-populator.js +1171 -0
- package/dist/esm/modules/excel/chart/chart-api.js +364 -0
- package/dist/esm/modules/excel/chart/chart-builder.js +2432 -0
- package/dist/esm/modules/excel/chart/chart-ex-builder.js +903 -0
- package/dist/esm/modules/excel/chart/chart-ex-parser.js +1205 -0
- package/dist/esm/modules/excel/chart/chart-ex-renderer.js +5352 -0
- package/dist/esm/modules/excel/chart/chart-ex-types.js +11 -0
- package/dist/esm/modules/excel/chart/chart-images.js +363 -0
- package/dist/esm/modules/excel/chart/chart-presets.js +179 -0
- package/dist/esm/modules/excel/chart/chart-renderer.js +6440 -0
- package/dist/esm/modules/excel/chart/chart-sidecar.js +427 -0
- package/dist/esm/modules/excel/chart/chart-utils.js +821 -0
- package/dist/esm/modules/excel/chart/chart.js +1320 -0
- package/dist/esm/modules/excel/chart/glyph-rasterizer.js +658 -0
- package/dist/esm/modules/excel/chart/index.js +46 -0
- package/dist/esm/modules/excel/chart/install.js +91 -0
- package/dist/esm/modules/excel/chart/shape-properties.js +1557 -0
- package/dist/esm/modules/excel/chart/stroke-font.js +1556 -0
- package/dist/esm/modules/excel/chart/topojson.js +236 -0
- package/dist/esm/modules/excel/chart/types.js +8 -0
- package/dist/esm/modules/excel/chart-host-registry.js +90 -0
- package/dist/esm/modules/excel/chartsheet.js +196 -0
- package/dist/esm/modules/excel/defined-names.js +44 -4
- package/dist/esm/modules/excel/errors.js +9 -0
- package/dist/esm/modules/excel/form-control.js +17 -0
- package/dist/esm/modules/excel/image.js +12 -2
- package/dist/esm/modules/excel/pivot-chart.js +53 -0
- package/dist/esm/modules/excel/pivot-table.js +35 -0
- package/dist/esm/modules/excel/range.js +5 -1
- package/dist/esm/modules/excel/sparkline/index.js +7 -0
- package/dist/esm/modules/excel/sparkline/sparkline.js +750 -0
- package/dist/esm/modules/excel/stream/worksheet-writer.js +3 -2
- package/dist/esm/modules/excel/table.js +42 -6
- package/dist/esm/modules/excel/utils/address.js +28 -0
- package/dist/esm/modules/excel/utils/drawing-utils.js +11 -6
- package/dist/esm/modules/excel/utils/guid.js +35 -0
- package/dist/esm/modules/excel/utils/ooxml-paths.js +206 -9
- package/dist/esm/modules/excel/utils/ooxml-validator/check-chart-sidecar.js +101 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-chart.js +2125 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-chartsheet.js +26 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-content-types.js +181 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-drawing.js +267 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-pivot.js +104 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-relationships.js +184 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-structure.js +56 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-styles.js +89 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-table.js +177 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-workbook.js +163 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/check-worksheet.js +569 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/context.js +191 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/index.js +102 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/path-utils.js +156 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/reporter.js +61 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/types.js +12 -0
- package/dist/esm/modules/excel/utils/ooxml-validator/xml-utils.js +100 -0
- package/dist/esm/modules/excel/workbook.browser.js +969 -34
- package/dist/esm/modules/excel/workbook.js +48 -0
- package/dist/esm/modules/excel/worksheet.js +394 -35
- package/dist/esm/modules/excel/xlsx/rel-type.js +41 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +11 -2
- package/dist/esm/modules/excel/xlsx/xform/book/external-link-xform.js +12 -10
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +96 -22
- package/dist/esm/modules/excel/xlsx/xform/chart/chart-space-xform.js +6000 -0
- package/dist/esm/modules/excel/xlsx/xform/comment/threaded-comments-xform.js +213 -0
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +150 -11
- package/dist/esm/modules/excel/xlsx/xform/drawing/absolute-anchor-xform.js +20 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/drawing-xform.js +109 -5
- package/dist/esm/modules/excel/xlsx/xform/drawing/graphic-frame-xform.js +225 -0
- package/dist/esm/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +18 -3
- package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +294 -12
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +32 -6
- package/dist/esm/modules/excel/xlsx/xform/sheet/chartsheet-xform.js +441 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/ext-lst-xform.js +51 -2
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +196 -20
- package/dist/esm/modules/excel/xlsx/xform/table/auto-filter-xform.js +16 -1
- package/dist/esm/modules/excel/xlsx/xform/table/table-column-xform.js +17 -2
- package/dist/esm/modules/excel/xlsx/xform/xsd-values.js +101 -0
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +4422 -78
- package/dist/esm/modules/pdf/builder/document-builder.js +507 -2
- package/dist/esm/modules/pdf/builder/pdf-editor.js +48 -3
- package/dist/esm/modules/pdf/excel-bridge.js +683 -12
- package/dist/esm/modules/pdf/font/font-manager.js +39 -0
- package/dist/esm/modules/pdf/index.js +3 -1
- package/dist/esm/modules/pdf/render/chart-surface.js +200 -0
- package/dist/esm/modules/pdf/render/layout-engine.js +436 -56
- package/dist/esm/modules/pdf/render/page-renderer.js +169 -28
- package/dist/esm/modules/pdf/render/pdf-exporter.js +117 -7
- package/dist/esm/modules/pdf/types.js +4 -0
- package/dist/esm/modules/pdf/word-bridge.js +304 -0
- package/dist/esm/modules/word/constants.js +231 -0
- package/dist/esm/modules/word/content-types.js +53 -0
- package/dist/esm/modules/word/digital-signatures.js +134 -0
- package/dist/esm/modules/word/document.js +1795 -0
- package/dist/esm/modules/word/docx-packager.js +822 -0
- package/dist/esm/modules/word/docx-reader.js +4929 -0
- package/dist/esm/modules/word/encryption.js +274 -0
- package/dist/esm/modules/word/errors.js +68 -0
- package/dist/esm/modules/word/font-obfuscation.js +83 -0
- package/dist/esm/modules/word/html-renderer.js +782 -0
- package/dist/esm/modules/word/index.base.js +51 -0
- package/dist/esm/modules/word/index.browser.js +4 -0
- package/dist/esm/modules/word/index.js +4 -0
- package/dist/esm/modules/word/internal-utils.js +54 -0
- package/dist/esm/modules/word/relationships.js +56 -0
- package/dist/esm/modules/word/types.js +10 -0
- package/dist/esm/modules/word/units.js +111 -0
- package/dist/esm/modules/word/writers/chart-writer.js +385 -0
- package/dist/esm/modules/word/writers/checkbox-writer.js +42 -0
- package/dist/esm/modules/word/writers/comment-writer.js +70 -0
- package/dist/esm/modules/word/writers/document-writer.js +461 -0
- package/dist/esm/modules/word/writers/footnote-writer.js +72 -0
- package/dist/esm/modules/word/writers/header-footer-writer.js +129 -0
- package/dist/esm/modules/word/writers/image-writer.js +185 -0
- package/dist/esm/modules/word/writers/math-writer.js +428 -0
- package/dist/esm/modules/word/writers/numbering-writer.js +125 -0
- package/dist/esm/modules/word/writers/paragraph-writer.js +516 -0
- package/dist/esm/modules/word/writers/parts-writer.js +660 -0
- package/dist/esm/modules/word/writers/run-writer.js +649 -0
- package/dist/esm/modules/word/writers/section-writer.js +238 -0
- package/dist/esm/modules/word/writers/styles-writer.js +242 -0
- package/dist/esm/modules/word/writers/table-writer.js +503 -0
- package/dist/esm/modules/word/writers/textbox-writer.js +53 -0
- package/dist/esm/modules/word/writers/toc-writer.js +79 -0
- package/dist/esm/modules/xml/encode.js +157 -11
- package/dist/iife/excelts.iife.js +11789 -687
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +52 -44
- package/dist/types/index.browser.d.ts +8 -5
- package/dist/types/index.d.ts +4 -2
- package/dist/types/modules/excel/chart/cache-populator.d.ts +49 -0
- package/dist/types/modules/excel/chart/chart-api.d.ts +92 -0
- package/dist/types/modules/excel/chart/chart-builder.d.ts +48 -0
- package/dist/types/modules/excel/chart/chart-ex-builder.d.ts +36 -0
- package/dist/types/modules/excel/chart/chart-ex-parser.d.ts +8 -0
- package/dist/types/modules/excel/chart/chart-ex-renderer.d.ts +187 -0
- package/dist/types/modules/excel/chart/chart-ex-types.d.ts +531 -0
- package/dist/types/modules/excel/chart/chart-images.d.ts +78 -0
- package/dist/types/modules/excel/chart/chart-presets.d.ts +392 -0
- package/dist/types/modules/excel/chart/chart-renderer.d.ts +550 -0
- package/dist/types/modules/excel/chart/chart-sidecar.d.ts +21 -0
- package/dist/types/modules/excel/chart/chart-utils.d.ts +306 -0
- package/dist/types/modules/excel/chart/chart.d.ts +504 -0
- package/dist/types/modules/excel/chart/glyph-rasterizer.d.ts +62 -0
- package/dist/types/modules/excel/chart/index.d.ts +54 -0
- package/dist/types/modules/excel/chart/install.d.ts +44 -0
- package/dist/types/modules/excel/chart/shape-properties.d.ts +156 -0
- package/dist/types/modules/excel/chart/stroke-font.d.ts +36 -0
- package/dist/types/modules/excel/chart/topojson.d.ts +98 -0
- package/dist/types/modules/excel/chart/types.d.ts +2559 -0
- package/dist/types/modules/excel/chart-host-registry.d.ts +157 -0
- package/dist/types/modules/excel/chartsheet.d.ts +102 -0
- package/dist/types/modules/excel/defined-names.d.ts +35 -0
- package/dist/types/modules/excel/errors.d.ts +6 -0
- package/dist/types/modules/excel/form-control.d.ts +6 -0
- package/dist/types/modules/excel/pivot-chart.d.ts +7 -0
- package/dist/types/modules/excel/pivot-table.d.ts +55 -0
- package/dist/types/modules/excel/sparkline/index.d.ts +7 -0
- package/dist/types/modules/excel/sparkline/sparkline.d.ts +206 -0
- package/dist/types/modules/excel/types.d.ts +72 -0
- package/dist/types/modules/excel/utils/address.d.ts +18 -0
- package/dist/types/modules/excel/utils/guid.d.ts +15 -0
- package/dist/types/modules/excel/utils/ooxml-paths.d.ts +74 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-chart-sidecar.d.ts +35 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-chart.d.ts +32 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-chartsheet.d.ts +9 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-content-types.d.ts +16 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-drawing.d.ts +34 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-pivot.d.ts +14 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-relationships.d.ts +18 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-structure.d.ts +21 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-styles.d.ts +15 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-table.d.ts +31 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-workbook.d.ts +19 -0
- package/dist/types/modules/excel/utils/ooxml-validator/check-worksheet.d.ts +25 -0
- package/dist/types/modules/excel/utils/ooxml-validator/context.d.ts +85 -0
- package/dist/types/modules/excel/utils/ooxml-validator/index.d.ts +31 -0
- package/dist/types/modules/excel/utils/ooxml-validator/path-utils.d.ts +67 -0
- package/dist/types/modules/excel/utils/ooxml-validator/reporter.d.ts +41 -0
- package/dist/types/modules/excel/utils/ooxml-validator/types.d.ts +109 -0
- package/dist/types/modules/excel/utils/ooxml-validator/xml-utils.d.ts +38 -0
- package/dist/types/modules/excel/workbook.browser.d.ts +248 -30
- package/dist/types/modules/excel/workbook.d.ts +43 -0
- package/dist/types/modules/excel/worksheet.d.ts +157 -3
- package/dist/types/modules/excel/xlsx/rel-type.d.ts +40 -0
- package/dist/types/modules/excel/xlsx/xform/book/defined-name-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/chart/chart-space-xform.d.ts +353 -0
- package/dist/types/modules/excel/xlsx/xform/comment/threaded-comments-xform.d.ts +60 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +30 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/graphic-frame-xform.d.ts +54 -0
- package/dist/types/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +3 -1
- package/dist/types/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +46 -0
- package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +13 -2
- package/dist/types/modules/excel/xlsx/xform/sheet/chartsheet-xform.d.ts +185 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/ext-lst-xform.d.ts +1 -0
- package/dist/types/modules/excel/xlsx/xform/xsd-values.d.ts +63 -0
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +115 -21
- package/dist/types/modules/pdf/builder/document-builder.d.ts +74 -0
- package/dist/types/modules/pdf/excel-bridge.d.ts +69 -0
- package/dist/types/modules/pdf/font/font-manager.d.ts +25 -0
- package/dist/types/modules/pdf/index.d.ts +5 -2
- package/dist/types/modules/pdf/render/chart-surface.d.ts +33 -0
- package/dist/types/modules/pdf/render/layout-engine.d.ts +22 -1
- package/dist/types/modules/pdf/types.d.ts +227 -23
- package/dist/types/modules/pdf/word-bridge.d.ts +47 -0
- package/dist/types/modules/word/constants.d.ts +179 -0
- package/dist/types/modules/word/content-types.d.ts +27 -0
- package/dist/types/modules/word/digital-signatures.d.ts +87 -0
- package/dist/types/modules/word/document.d.ts +728 -0
- package/dist/types/modules/word/docx-packager.d.ts +14 -0
- package/dist/types/modules/word/docx-reader.d.ts +11 -0
- package/dist/types/modules/word/encryption.d.ts +102 -0
- package/dist/types/modules/word/errors.d.ts +49 -0
- package/dist/types/modules/word/font-obfuscation.d.ts +31 -0
- package/dist/types/modules/word/html-renderer.d.ts +38 -0
- package/dist/types/modules/word/index.base.d.ts +19 -0
- package/dist/types/modules/word/index.browser.d.ts +4 -0
- package/dist/types/modules/word/index.d.ts +4 -0
- package/dist/types/modules/word/internal-utils.d.ts +23 -0
- package/dist/types/modules/word/relationships.d.ts +31 -0
- package/dist/types/modules/word/types.d.ts +2325 -0
- package/dist/types/modules/word/units.d.ts +49 -0
- package/dist/types/modules/word/writers/chart-writer.d.ts +10 -0
- package/dist/types/modules/word/writers/checkbox-writer.d.ts +9 -0
- package/dist/types/modules/word/writers/comment-writer.d.ts +15 -0
- package/dist/types/modules/word/writers/document-writer.d.ts +16 -0
- package/dist/types/modules/word/writers/footnote-writer.d.ts +11 -0
- package/dist/types/modules/word/writers/header-footer-writer.d.ts +13 -0
- package/dist/types/modules/word/writers/image-writer.d.ts +10 -0
- package/dist/types/modules/word/writers/math-writer.d.ts +9 -0
- package/dist/types/modules/word/writers/numbering-writer.d.ts +10 -0
- package/dist/types/modules/word/writers/paragraph-writer.d.ts +13 -0
- package/dist/types/modules/word/writers/parts-writer.d.ts +26 -0
- package/dist/types/modules/word/writers/run-writer.d.ts +15 -0
- package/dist/types/modules/word/writers/section-writer.d.ts +10 -0
- package/dist/types/modules/word/writers/styles-writer.d.ts +10 -0
- package/dist/types/modules/word/writers/table-writer.d.ts +10 -0
- package/dist/types/modules/word/writers/textbox-writer.d.ts +9 -0
- package/dist/types/modules/word/writers/toc-writer.d.ts +9 -0
- package/dist/types/modules/xml/encode.d.ts +56 -7
- package/package.json +29 -11
- package/dist/browser/modules/excel/utils/ooxml-validator.d.ts +0 -48
- package/dist/browser/modules/excel/utils/ooxml-validator.js +0 -493
- package/dist/browser/modules/excel/utils/passthrough-manager.d.ts +0 -77
- package/dist/browser/modules/excel/utils/passthrough-manager.js +0 -129
- package/dist/cjs/modules/excel/utils/ooxml-validator.js +0 -499
- package/dist/cjs/modules/excel/utils/passthrough-manager.js +0 -133
- package/dist/esm/modules/excel/utils/ooxml-validator.js +0 -493
- package/dist/esm/modules/excel/utils/passthrough-manager.js +0 -129
- package/dist/types/modules/excel/utils/ooxml-validator.d.ts +0 -48
- package/dist/types/modules/excel/utils/passthrough-manager.d.ts +0 -77
|
@@ -0,0 +1,1171 @@
|
|
|
1
|
+
import { colCache } from "../utils/col-cache.js";
|
|
2
|
+
import { dateToExcel } from "../../../utils/utils.base.js";
|
|
3
|
+
/**
|
|
4
|
+
* Populate all number/string caches in a ChartModel from the given workbook.
|
|
5
|
+
* Mutates the model in place. Safe to call multiple times (idempotent).
|
|
6
|
+
*
|
|
7
|
+
* @param model - The chart model to enrich
|
|
8
|
+
* @param workbook - The workbook used to resolve sheet/cell references
|
|
9
|
+
* @param contextWorksheet - Optional worksheet providing the default scope for
|
|
10
|
+
* defined-name resolution. When a defined name has a sheet-scoped entry
|
|
11
|
+
* matching this worksheet's workbook index (`localSheetId`), that entry
|
|
12
|
+
* wins over the workbook-scoped entry. Supplying this argument is required
|
|
13
|
+
* to correctly resolve sheet-scoped names; omitting it falls back to
|
|
14
|
+
* workbook-scoped names only.
|
|
15
|
+
*/
|
|
16
|
+
export function fillChartCaches(model, workbook, contextWorksheet) {
|
|
17
|
+
const plotArea = model.chart?.plotArea;
|
|
18
|
+
if (!plotArea) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const date1904 = workbook.properties?.date1904;
|
|
22
|
+
const ctx = buildResolverContext(workbook, contextWorksheet);
|
|
23
|
+
// Fill the classic chart title's `<c:strRef>` cache when the title
|
|
24
|
+
// was authored as `{ formula: "..." }`. The writer already emits
|
|
25
|
+
// `<c:strCache>` for any `strRef.cache.points` it finds; without
|
|
26
|
+
// this fill a formula-bound title round-trips as
|
|
27
|
+
// `<c:strRef><c:f>…</c:f></c:strRef>` with no cache, so readers that
|
|
28
|
+
// don't recalculate formulas (preview tooling, headless converters)
|
|
29
|
+
// see a blank title frame. ChartEx has the same machinery in
|
|
30
|
+
// `fillChartExCaches`; keeping them symmetric.
|
|
31
|
+
fillClassicTitleCache(model.chart?.title, ctx);
|
|
32
|
+
// Axis titles follow the same shape — `ChartTitle` is the same type
|
|
33
|
+
// on `axis.title` and carries the same `strRef.cache`. Round-trip
|
|
34
|
+
// parity requires filling them too.
|
|
35
|
+
for (const axis of plotArea.axes ?? []) {
|
|
36
|
+
fillClassicTitleCache(axis.title, ctx);
|
|
37
|
+
}
|
|
38
|
+
for (const group of plotArea.chartTypes) {
|
|
39
|
+
fillGroupCaches(group, ctx, date1904);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Populate a classic `ChartTitle.strRef.cache` from its formula when
|
|
44
|
+
* the cache is empty. Shared between chart title and axis titles.
|
|
45
|
+
* No-ops for titles that were authored as rich text / rawTx / a
|
|
46
|
+
* literal string — only formula-bound titles carry a strRef.
|
|
47
|
+
*/
|
|
48
|
+
function fillClassicTitleCache(title, ctx) {
|
|
49
|
+
const strRef = title?.strRef;
|
|
50
|
+
if (!strRef?.formula) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (strRef.cache?.points && strRef.cache.points.length > 0) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const resolved = resolveReference(strRef.formula, ctx);
|
|
57
|
+
if (!resolved) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const points = [];
|
|
61
|
+
let idx = 0;
|
|
62
|
+
for (const cell of resolved.cells) {
|
|
63
|
+
const s = toString(cell.value);
|
|
64
|
+
if (s !== undefined) {
|
|
65
|
+
points.push({ index: idx, value: s });
|
|
66
|
+
}
|
|
67
|
+
idx += 1;
|
|
68
|
+
}
|
|
69
|
+
// Gate on "any resolved cell", not "any non-empty stringified
|
|
70
|
+
// value". Sibling fillers (`fillNumRefInternal` / `fillStrRefInternal`)
|
|
71
|
+
// emit a sparse cache `{ pointCount: N, points: [] }` when the
|
|
72
|
+
// resolved range had no stringifiable cells — that's the whole
|
|
73
|
+
// reason the fill exists: readers that don't recalculate formulas
|
|
74
|
+
// still need the `pointCount` envelope to size sparse arrays
|
|
75
|
+
// correctly. The title filler was previously inconsistent: it
|
|
76
|
+
// tracked `idx` through empty cells but then dropped the cache
|
|
77
|
+
// entirely unless at least one cell yielded a non-empty string.
|
|
78
|
+
// That meant a formula-bound title whose source cell is currently
|
|
79
|
+
// blank round-tripped as `<c:strRef><c:f>…</c:f></c:strRef>` with
|
|
80
|
+
// no cache — exactly the failure mode the fill was written to
|
|
81
|
+
// prevent.
|
|
82
|
+
if (resolved.cells.length > 0) {
|
|
83
|
+
strRef.cache = { pointCount: idx, points };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function fillChartExCaches(model, workbook, contextWorksheet) {
|
|
87
|
+
// Defensive guard — parseChartEx emits `chartData.data = []` even for
|
|
88
|
+
// malformed documents, but downstream callers (and unit fixtures) can
|
|
89
|
+
// construct partial models. Match the classic `fillChartCaches` which
|
|
90
|
+
// no-ops when `plotArea` is missing.
|
|
91
|
+
const data = model.chartSpace?.chartData?.data;
|
|
92
|
+
const ctx = buildResolverContext(workbook, contextWorksheet);
|
|
93
|
+
// Fill the ChartEx title's `<cx:txData>` cache. The builder accepts a
|
|
94
|
+
// `{ formula: string }` title and parks `strRef: { formula, cache:
|
|
95
|
+
// { points: [] } }` on the model; the writer emits `<cx:v>` from the
|
|
96
|
+
// first cached point. Without this fill, a formula-linked title
|
|
97
|
+
// round-trips as `<cx:txData><cx:f>…</cx:f></cx:txData>` (no cached
|
|
98
|
+
// value), so readers without a formula engine see an empty title
|
|
99
|
+
// until Excel recalculates.
|
|
100
|
+
const title = model.chartSpace?.chart?.title;
|
|
101
|
+
const titleStrRef = title?.strRef;
|
|
102
|
+
if (titleStrRef?.formula && (titleStrRef.cache?.points?.length ?? 0) === 0) {
|
|
103
|
+
const resolved = resolveReference(titleStrRef.formula, ctx);
|
|
104
|
+
if (resolved) {
|
|
105
|
+
const first = resolved.cells.find(cell => toString(cell.value) !== undefined);
|
|
106
|
+
if (first) {
|
|
107
|
+
const value = toString(first.value);
|
|
108
|
+
if (value !== undefined) {
|
|
109
|
+
titleStrRef.cache = { points: [{ index: 0, value }] };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (!data || data.length === 0) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
for (const entry of data) {
|
|
118
|
+
if (entry.strDim?.formula && !hasChartExStringPoints(entry.strDim)) {
|
|
119
|
+
const resolved = resolveReference(entry.strDim.formula, ctx);
|
|
120
|
+
if (resolved && resolved.cells.length > 0) {
|
|
121
|
+
const points = [];
|
|
122
|
+
let idx = 0;
|
|
123
|
+
for (const cell of resolved.cells) {
|
|
124
|
+
const value = toString(cell.value);
|
|
125
|
+
if (value !== undefined && value !== "") {
|
|
126
|
+
points.push({ index: idx, value });
|
|
127
|
+
}
|
|
128
|
+
idx++;
|
|
129
|
+
}
|
|
130
|
+
// Write levels whenever we had resolvable cells: even all-empty
|
|
131
|
+
// resolves should emit `[{ ptCount: N, points: [] }]` so Excel
|
|
132
|
+
// sizes the sparse array correctly. This matches the classic
|
|
133
|
+
// `fillNumRefInternal` / `fillStrRefInternal` behaviour which
|
|
134
|
+
// the null-value-cell test explicitly depends on.
|
|
135
|
+
entry.strDim.levels = [{ ptCount: idx, points }];
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (entry.numDim?.formula && !hasChartExNumberPoints(entry.numDim)) {
|
|
139
|
+
const resolved = resolveReference(entry.numDim.formula, ctx);
|
|
140
|
+
if (resolved && resolved.cells.length > 0) {
|
|
141
|
+
const points = [];
|
|
142
|
+
let idx = 0;
|
|
143
|
+
for (const cell of resolved.cells) {
|
|
144
|
+
const value = toNumber(cell.value, workbook.properties?.date1904);
|
|
145
|
+
if (value !== undefined) {
|
|
146
|
+
points.push({ index: idx, value });
|
|
147
|
+
}
|
|
148
|
+
idx++;
|
|
149
|
+
}
|
|
150
|
+
// Preserve any `formatCode` already attached to the original
|
|
151
|
+
// numeric level so a round-tripped `<cx:lvl formatCode="…">`
|
|
152
|
+
// keeps its numFmt — the old path blindly replaced `levels`
|
|
153
|
+
// with a freshly-built object and silently dropped the
|
|
154
|
+
// attribute on every save.
|
|
155
|
+
const existingLvl = entry.numDim.levels?.[0];
|
|
156
|
+
entry.numDim.levels = [
|
|
157
|
+
{
|
|
158
|
+
ptCount: idx,
|
|
159
|
+
points,
|
|
160
|
+
...(existingLvl?.formatCode ? { formatCode: existingLvl.formatCode } : {})
|
|
161
|
+
}
|
|
162
|
+
];
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function fillGroupCaches(group, ctx, date1904) {
|
|
168
|
+
// Group-level `dataLabels.dataLabelsRange` (Excel 2013+ "Value From
|
|
169
|
+
// Cells" at the chart-type group level). The builder places
|
|
170
|
+
// `dataLabelsRange` on the group when the caller passes `dataLabels:
|
|
171
|
+
// { valueFromCells }` at the group level — we previously only filled
|
|
172
|
+
// the per-series variant, so a group-wide value-from-cells range
|
|
173
|
+
// silently stayed empty until a formula engine recalculated it.
|
|
174
|
+
const groupDataLabels = group
|
|
175
|
+
.dataLabels;
|
|
176
|
+
if (groupDataLabels?.dataLabelsRange?.formula) {
|
|
177
|
+
fillDataLabelsRange(groupDataLabels.dataLabelsRange, ctx);
|
|
178
|
+
}
|
|
179
|
+
const series = group.series;
|
|
180
|
+
if (!series) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
for (const s of series) {
|
|
184
|
+
fillSeriesCaches(s, ctx, date1904);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function hasChartExStringPoints(dim) {
|
|
188
|
+
// Hierarchical charts (treemap / sunburst) point their `<cx:strDim>`
|
|
189
|
+
// at a contiguous multi-column range (`$A$2:$C$N`). A single flat
|
|
190
|
+
// `<cx:lvl>` cache across 3 columns × N rows (3×N points) does not
|
|
191
|
+
// survive Excel's hierarchical-data pivot: the chart draws nothing
|
|
192
|
+
// because the loader cannot re-derive the row × column layout from
|
|
193
|
+
// a flat point list. Excel's own writer omits the cache entirely for
|
|
194
|
+
// treemap + sunburst and re-reads the cells on open. Mirror that:
|
|
195
|
+
// when a strDim is tagged `_skipCache` (set by the builder for
|
|
196
|
+
// hierarchical chartEx series), treat it as "already populated"
|
|
197
|
+
// so `fillChartExCaches` leaves it alone and the renderer emits
|
|
198
|
+
// just the `<cx:f>` reference.
|
|
199
|
+
if (dim._skipCache) {
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return dim.levels?.some(level => level.points.length > 0) ?? false;
|
|
203
|
+
}
|
|
204
|
+
function hasChartExNumberPoints(dim) {
|
|
205
|
+
if (dim._skipCache) {
|
|
206
|
+
return true;
|
|
207
|
+
}
|
|
208
|
+
return dim.levels?.some(level => level.points.length > 0) ?? false;
|
|
209
|
+
}
|
|
210
|
+
function fillSeriesCaches(series, ctx, date1904) {
|
|
211
|
+
// Series name (tx): may be strRef
|
|
212
|
+
const tx = series.tx;
|
|
213
|
+
if (tx?.strRef) {
|
|
214
|
+
fillStrRefInternal(tx.strRef, ctx);
|
|
215
|
+
}
|
|
216
|
+
// Category / X axis data source
|
|
217
|
+
const cat = series.cat;
|
|
218
|
+
if (cat) {
|
|
219
|
+
fillAxisDataSource(cat, ctx, date1904);
|
|
220
|
+
}
|
|
221
|
+
const xVal = series.xVal;
|
|
222
|
+
if (xVal) {
|
|
223
|
+
fillAxisDataSource(xVal, ctx, date1904);
|
|
224
|
+
}
|
|
225
|
+
// Numeric values — val, yVal, bubbleSize
|
|
226
|
+
const val = series.val;
|
|
227
|
+
if (val?.numRef) {
|
|
228
|
+
fillNumRefInternal(val.numRef, ctx, date1904);
|
|
229
|
+
}
|
|
230
|
+
const yVal = series.yVal;
|
|
231
|
+
if (yVal?.numRef) {
|
|
232
|
+
fillNumRefInternal(yVal.numRef, ctx, date1904);
|
|
233
|
+
}
|
|
234
|
+
const bubbleSize = series.bubbleSize;
|
|
235
|
+
if (bubbleSize?.numRef) {
|
|
236
|
+
fillNumRefInternal(bubbleSize.numRef, ctx, date1904);
|
|
237
|
+
}
|
|
238
|
+
// Error bars may have custom plus/minus references
|
|
239
|
+
const errorBars = series.errorBars;
|
|
240
|
+
if (errorBars) {
|
|
241
|
+
const list = Array.isArray(errorBars) ? errorBars : [errorBars];
|
|
242
|
+
for (const eb of list) {
|
|
243
|
+
if (eb.plus?.numRef) {
|
|
244
|
+
fillNumRefInternal(eb.plus.numRef, ctx, date1904);
|
|
245
|
+
}
|
|
246
|
+
if (eb.minus?.numRef) {
|
|
247
|
+
fillNumRefInternal(eb.minus.numRef, ctx, date1904);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
// "Value From Cells" data labels (Excel 2013+) — populate the
|
|
252
|
+
// `c15:datalabelsRange` cache so readers without a formula engine see
|
|
253
|
+
// the right labels and so the writer can emit `<c15:dlblRangeCache>`.
|
|
254
|
+
const dataLabels = series.dataLabels;
|
|
255
|
+
if (dataLabels?.dataLabelsRange?.formula) {
|
|
256
|
+
fillDataLabelsRange(dataLabels.dataLabelsRange, ctx);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
function fillDataLabelsRange(range, ctx) {
|
|
260
|
+
if (range.cache?.points && range.cache.points.length > 0) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const resolved = resolveReference(range.formula, ctx);
|
|
264
|
+
if (!resolved) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
const points = [];
|
|
268
|
+
let idx = 0;
|
|
269
|
+
for (const cell of resolved.cells) {
|
|
270
|
+
const s = toString(cell.value);
|
|
271
|
+
if (s !== undefined && s !== "") {
|
|
272
|
+
points.push({ index: idx, value: s });
|
|
273
|
+
}
|
|
274
|
+
idx++;
|
|
275
|
+
}
|
|
276
|
+
// Match the sibling fillers (`fillNumRefInternal`, `fillStrRefInternal`,
|
|
277
|
+
// `fillChartExCaches`) — gate on "resolved any cells" rather than
|
|
278
|
+
// "collected any non-empty values". An all-blank range still needs a
|
|
279
|
+
// sparse `{ pointCount: N, points: [] }` cache so Excel sizes the
|
|
280
|
+
// label array correctly; dropping the cache entirely under-counted
|
|
281
|
+
// the label index and desynchronised labels from their data points.
|
|
282
|
+
if (idx > 0) {
|
|
283
|
+
range.cache = { pointCount: idx, points };
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function fillAxisDataSource(src, ctx, date1904) {
|
|
287
|
+
if (src.strRef) {
|
|
288
|
+
fillStrRefInternal(src.strRef, ctx);
|
|
289
|
+
}
|
|
290
|
+
if (src.numRef) {
|
|
291
|
+
fillNumRefInternal(src.numRef, ctx, date1904);
|
|
292
|
+
}
|
|
293
|
+
if (src.multiLvlStrRef) {
|
|
294
|
+
fillMultiLvlStrRefInternal(src.multiLvlStrRef, ctx);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Populate a NumberReference cache from the workbook.
|
|
299
|
+
* Only fills if `cache.points` is currently empty.
|
|
300
|
+
*
|
|
301
|
+
* @param contextWorksheet - Optional worksheet whose sheet-scoped defined
|
|
302
|
+
* names take precedence over workbook-scoped ones.
|
|
303
|
+
*/
|
|
304
|
+
export function fillNumRef(ref, workbook, date1904, contextWorksheet) {
|
|
305
|
+
fillNumRefInternal(ref, buildResolverContext(workbook, contextWorksheet), date1904);
|
|
306
|
+
}
|
|
307
|
+
function fillNumRefInternal(ref, ctx, date1904) {
|
|
308
|
+
if (!ref.formula) {
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (ref.cache?.points && ref.cache.points.length > 0) {
|
|
312
|
+
return; // already populated
|
|
313
|
+
}
|
|
314
|
+
const resolved = resolveReference(ref.formula, ctx);
|
|
315
|
+
if (!resolved) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const points = [];
|
|
319
|
+
let idx = 0;
|
|
320
|
+
for (const cell of resolved.cells) {
|
|
321
|
+
const n = toNumber(cell.value, date1904);
|
|
322
|
+
if (n !== undefined) {
|
|
323
|
+
points.push({ index: idx, value: n });
|
|
324
|
+
}
|
|
325
|
+
idx++;
|
|
326
|
+
}
|
|
327
|
+
// `idx === 0` means we resolved no cells at all — treat the same as
|
|
328
|
+
// an un-resolvable reference and keep any pre-existing cache intact.
|
|
329
|
+
// When we did resolve cells but all of them were empty/undefined,
|
|
330
|
+
// still emit the cache with `points: []` and the correct
|
|
331
|
+
// `pointCount`: Excel needs the pointCount to size sparse arrays
|
|
332
|
+
// correctly even when every slot is blank.
|
|
333
|
+
if (idx === 0) {
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (!ref.cache) {
|
|
337
|
+
ref.cache = { points: [] };
|
|
338
|
+
}
|
|
339
|
+
ref.cache.points = points;
|
|
340
|
+
ref.cache.pointCount = idx; // total slots (including empty)
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Populate a StringReference cache from the workbook.
|
|
344
|
+
* Only fills if `cache.points` is currently empty.
|
|
345
|
+
*
|
|
346
|
+
* @param contextWorksheet - Optional worksheet whose sheet-scoped defined
|
|
347
|
+
* names take precedence over workbook-scoped ones.
|
|
348
|
+
*/
|
|
349
|
+
export function fillStrRef(ref, workbook, contextWorksheet) {
|
|
350
|
+
fillStrRefInternal(ref, buildResolverContext(workbook, contextWorksheet));
|
|
351
|
+
}
|
|
352
|
+
function fillStrRefInternal(ref, ctx) {
|
|
353
|
+
if (!ref.formula) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (ref.cache?.points && ref.cache.points.length > 0) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
const resolved = resolveReference(ref.formula, ctx);
|
|
360
|
+
if (!resolved) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const points = [];
|
|
364
|
+
let idx = 0;
|
|
365
|
+
for (const cell of resolved.cells) {
|
|
366
|
+
const s = toString(cell.value);
|
|
367
|
+
if (s !== undefined && s !== "") {
|
|
368
|
+
points.push({ index: idx, value: s });
|
|
369
|
+
}
|
|
370
|
+
idx++;
|
|
371
|
+
}
|
|
372
|
+
// See `fillNumRefInternal`: no cells resolved → preserve any
|
|
373
|
+
// pre-existing cache; otherwise write the computed cache (possibly
|
|
374
|
+
// with `points: []` and `pointCount` reflecting blank slots).
|
|
375
|
+
if (idx === 0) {
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
if (!ref.cache) {
|
|
379
|
+
ref.cache = { points: [] };
|
|
380
|
+
}
|
|
381
|
+
ref.cache.points = points;
|
|
382
|
+
ref.cache.pointCount = idx;
|
|
383
|
+
}
|
|
384
|
+
export function fillMultiLvlStrRef(ref, workbook, contextWorksheet) {
|
|
385
|
+
fillMultiLvlStrRefInternal(ref, buildResolverContext(workbook, contextWorksheet));
|
|
386
|
+
}
|
|
387
|
+
function fillMultiLvlStrRefInternal(ref, ctx) {
|
|
388
|
+
if (!ref.formula) {
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
391
|
+
if (ref.cache?.levels?.some(level => level.points.length > 0)) {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
const resolved = resolveReferenceMatrix(ref.formula, ctx);
|
|
395
|
+
if (!resolved) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const levels = [];
|
|
399
|
+
for (let col = 0; col < resolved.columnCount; col++) {
|
|
400
|
+
const points = [];
|
|
401
|
+
for (let row = 0; row < resolved.rowCount; row++) {
|
|
402
|
+
const value = toString(resolved.values[row]?.[col]);
|
|
403
|
+
if (value !== undefined && value !== "") {
|
|
404
|
+
points.push({ index: row, value });
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
levels.push({ pointCount: resolved.rowCount, points });
|
|
408
|
+
}
|
|
409
|
+
ref.cache = { pointCount: resolved.rowCount, levels };
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Maximum defined-name expansion depth. Picked to match LibreOffice and
|
|
413
|
+
* comfortably exceed anything a legitimate workbook produces (Excel's UI
|
|
414
|
+
* stops the user well before this).
|
|
415
|
+
*/
|
|
416
|
+
const MAX_DEFINED_NAME_DEPTH = 128;
|
|
417
|
+
function buildResolverContext(workbook, contextWorksheet) {
|
|
418
|
+
let localSheetId;
|
|
419
|
+
if (contextWorksheet) {
|
|
420
|
+
// OOXML `definedName/@localSheetId` is a 0-based index into the
|
|
421
|
+
// workbook-level `<sheets>` element, which INTERLEAVES worksheets
|
|
422
|
+
// and chartsheets. Previously this helper used
|
|
423
|
+
// `workbook.worksheets.indexOf(contextWorksheet)` — the compressed
|
|
424
|
+
// worksheets-only position — so an interleaved
|
|
425
|
+
// `[WS1, CS, WS2]` workbook resolved WS2's `localSheetId` to `1`,
|
|
426
|
+
// colliding with the chartsheet's real tab position and making
|
|
427
|
+
// every sheet-scoped defined name on WS2 miss.
|
|
428
|
+
//
|
|
429
|
+
// `worksheet.orderNo` is set at BOTH save time (addWorksheet /
|
|
430
|
+
// addChartsheet use a unified counter) and load time
|
|
431
|
+
// (workbook-xform assigns `sheetPosition` across the mixed
|
|
432
|
+
// `<sheets>` list), so it is the authoritative mixed-tab index.
|
|
433
|
+
// Fall back to the compressed lookup for test worksheets that
|
|
434
|
+
// bypass the allocator and never receive an `orderNo`.
|
|
435
|
+
if (typeof contextWorksheet.orderNo === "number") {
|
|
436
|
+
localSheetId = contextWorksheet.orderNo;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
const idx = workbook.worksheets.indexOf(contextWorksheet);
|
|
440
|
+
if (idx >= 0) {
|
|
441
|
+
localSheetId = idx;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
workbook,
|
|
447
|
+
contextWorksheet,
|
|
448
|
+
localSheetId,
|
|
449
|
+
visitedDefinedNames: new Set(),
|
|
450
|
+
definedNameDepth: 0
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Resolve a chart formula like `Sheet1!$A$1:$A$4` or `'My Sheet'!$B$2:$B$5`
|
|
455
|
+
* into a sequence of cell values in row-major order.
|
|
456
|
+
*
|
|
457
|
+
* Multi-range unions (`Sheet1!A1:A3,Sheet1!A5:A7`) are flattened preserving order.
|
|
458
|
+
* Returns undefined if the reference cannot be resolved.
|
|
459
|
+
*
|
|
460
|
+
* Resolution strategy (first match wins):
|
|
461
|
+
* 1. Structured table reference (`Table1[Column]`)
|
|
462
|
+
* 2. Defined name (workbook- or sheet-scoped), recursively expanded
|
|
463
|
+
* 3. Direct A1 cell/range references (possibly comma-separated union)
|
|
464
|
+
*/
|
|
465
|
+
function resolveReference(formula, ctx) {
|
|
466
|
+
const structured = resolveStructuredReference(formula, ctx.workbook);
|
|
467
|
+
if (structured) {
|
|
468
|
+
return structured;
|
|
469
|
+
}
|
|
470
|
+
const named = resolveDefinedNameReference(formula, ctx);
|
|
471
|
+
if (named) {
|
|
472
|
+
return named;
|
|
473
|
+
}
|
|
474
|
+
// Multi-range support: Excel uses commas or semicolons between sub-refs.
|
|
475
|
+
// Inside quoted sheet names, commas don't count — do a safe split.
|
|
476
|
+
const parts = splitFormulaRanges(formula);
|
|
477
|
+
let worksheet;
|
|
478
|
+
const cells = [];
|
|
479
|
+
for (const part of parts) {
|
|
480
|
+
const trimmed = part.trim();
|
|
481
|
+
if (!trimmed) {
|
|
482
|
+
continue;
|
|
483
|
+
}
|
|
484
|
+
let decoded;
|
|
485
|
+
try {
|
|
486
|
+
decoded = colCache.decodeEx(trimmed);
|
|
487
|
+
}
|
|
488
|
+
catch {
|
|
489
|
+
return undefined;
|
|
490
|
+
}
|
|
491
|
+
// `decodeEx` can also return `{ sheetName, error: "#REF!" }` for
|
|
492
|
+
// malformed references — that shape has neither `row`/`col` nor
|
|
493
|
+
// `top`/`left`, so without an explicit check we would return
|
|
494
|
+
// `{ worksheet, cells: [] }` and silently mask an invalid formula as a
|
|
495
|
+
// successful empty resolution.
|
|
496
|
+
if ("error" in decoded) {
|
|
497
|
+
return undefined;
|
|
498
|
+
}
|
|
499
|
+
const sheetName = decoded.sheetName;
|
|
500
|
+
if (!sheetName) {
|
|
501
|
+
return undefined;
|
|
502
|
+
}
|
|
503
|
+
const ws = ctx.workbook.getWorksheet(sheetName);
|
|
504
|
+
if (!ws) {
|
|
505
|
+
return undefined;
|
|
506
|
+
}
|
|
507
|
+
// Track first resolved worksheet for the return value
|
|
508
|
+
if (!worksheet) {
|
|
509
|
+
worksheet = ws;
|
|
510
|
+
}
|
|
511
|
+
if ("top" in decoded && "left" in decoded) {
|
|
512
|
+
// Range: iterate in row-major order matching Excel's cache layout.
|
|
513
|
+
// For vertical ranges (single column), this is top→bottom.
|
|
514
|
+
// For horizontal ranges (single row), this is left→right.
|
|
515
|
+
// For 2D ranges, row-major (left→right, top→bottom).
|
|
516
|
+
const top = decoded.top;
|
|
517
|
+
const left = decoded.left;
|
|
518
|
+
const bottom = decoded.bottom;
|
|
519
|
+
const right = decoded.right;
|
|
520
|
+
for (let r = top; r <= bottom; r++) {
|
|
521
|
+
for (let c = left; c <= right; c++) {
|
|
522
|
+
cells.push({ value: extractCellValue(ws, r, c) });
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
else if ("row" in decoded && "col" in decoded) {
|
|
527
|
+
const r = decoded.row;
|
|
528
|
+
const c = decoded.col;
|
|
529
|
+
cells.push({ value: extractCellValue(ws, r, c) });
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
if (!worksheet) {
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
return { worksheet, cells };
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Regex matching a bare Excel defined name (no sheet prefix, no `$`, no `:`,
|
|
539
|
+
* no `!`, no `,`). Excel's grammar requires the first character to be a
|
|
540
|
+
* letter, underscore, or backslash, and disallows names that look like cell
|
|
541
|
+
* references; we don't try to validate name legality here — the final
|
|
542
|
+
* authority is whether `workbook.definedNames` has a matching entry.
|
|
543
|
+
*
|
|
544
|
+
* Allowing Unicode letters makes this work for CJK defined names, which are
|
|
545
|
+
* common in Chinese Excel files.
|
|
546
|
+
*/
|
|
547
|
+
const BARE_DEFINED_NAME_RE = /^[A-Za-z_\\\u00A0-\uFFFF][\w.?\\\u00A0-\uFFFF]*$/;
|
|
548
|
+
/**
|
|
549
|
+
* Attempt to resolve {@link formula} as a defined name and expand to the
|
|
550
|
+
* underlying A1 ranges. Supports both bare names (`MyRange`) and qualified
|
|
551
|
+
* names (`Sheet1!MyRange`, `'My Sheet'!MyRange`).
|
|
552
|
+
*
|
|
553
|
+
* Name-scope resolution matches Excel semantics:
|
|
554
|
+
* - Qualified `Sheet!Name` → sheet-scoped entry on `Sheet`, else
|
|
555
|
+
* workbook-scoped
|
|
556
|
+
* - Bare `Name` → sheet-scoped entry on the context worksheet (when
|
|
557
|
+
* provided), else workbook-scoped
|
|
558
|
+
*
|
|
559
|
+
* The result of expanding the name is resolved recursively, so chart
|
|
560
|
+
* formulas that target a named formula (e.g. `OFFSET(...)` stored as a
|
|
561
|
+
* defined name) do not silently fall through — when the name resolves to
|
|
562
|
+
* another reference-like expression, we follow it.
|
|
563
|
+
*/
|
|
564
|
+
function resolveDefinedNameReference(formula, ctx) {
|
|
565
|
+
const resolution = findDefinedName(formula, ctx);
|
|
566
|
+
if (!resolution) {
|
|
567
|
+
return undefined;
|
|
568
|
+
}
|
|
569
|
+
// Cycle guard: A -> B -> A must terminate.
|
|
570
|
+
const visitKey = storageKey(resolution.name, resolution.localSheetId);
|
|
571
|
+
if (ctx.visitedDefinedNames.has(visitKey)) {
|
|
572
|
+
return undefined;
|
|
573
|
+
}
|
|
574
|
+
// Depth guard: terminate pathological non-cyclic chains
|
|
575
|
+
// (A → B → C → D → … with hundreds of links) before the JS call
|
|
576
|
+
// stack blows up.
|
|
577
|
+
if (ctx.definedNameDepth >= MAX_DEFINED_NAME_DEPTH) {
|
|
578
|
+
return undefined;
|
|
579
|
+
}
|
|
580
|
+
ctx.visitedDefinedNames.add(visitKey);
|
|
581
|
+
ctx.definedNameDepth += 1;
|
|
582
|
+
try {
|
|
583
|
+
// A defined name may expand to multiple ranges (comma-separated union).
|
|
584
|
+
// We recursively resolve each part through the full reference pipeline
|
|
585
|
+
// so that nested names, structured refs, and A1 refs all work.
|
|
586
|
+
const aggregated = [];
|
|
587
|
+
let firstWorksheet;
|
|
588
|
+
for (const rangeStr of resolution.ranges) {
|
|
589
|
+
if (!rangeStr) {
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const inner = resolveReference(rangeStr, ctx);
|
|
593
|
+
if (!inner) {
|
|
594
|
+
continue;
|
|
595
|
+
}
|
|
596
|
+
if (!firstWorksheet) {
|
|
597
|
+
firstWorksheet = inner.worksheet;
|
|
598
|
+
}
|
|
599
|
+
for (const cell of inner.cells) {
|
|
600
|
+
aggregated.push(cell);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (!firstWorksheet) {
|
|
604
|
+
return undefined;
|
|
605
|
+
}
|
|
606
|
+
return { worksheet: firstWorksheet, cells: aggregated };
|
|
607
|
+
}
|
|
608
|
+
finally {
|
|
609
|
+
ctx.visitedDefinedNames.delete(visitKey);
|
|
610
|
+
ctx.definedNameDepth -= 1;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Look up a defined name in the workbook, honouring sheet-scoped vs
|
|
615
|
+
* workbook-scoped precedence. Returns `undefined` when the formula does not
|
|
616
|
+
* look like a defined-name reference at all, or when no entry matches.
|
|
617
|
+
*/
|
|
618
|
+
function findDefinedName(formula, ctx) {
|
|
619
|
+
const trimmed = formula.trim();
|
|
620
|
+
if (!trimmed) {
|
|
621
|
+
return undefined;
|
|
622
|
+
}
|
|
623
|
+
// Qualified form: Sheet!Name or 'Sheet Name'!Name
|
|
624
|
+
const qualified = splitQualifiedName(trimmed);
|
|
625
|
+
if (qualified) {
|
|
626
|
+
// Sheet-scoped entry on the qualifying sheet wins; fall back to
|
|
627
|
+
// workbook-scoped if the sheet has no matching entry.
|
|
628
|
+
const qualifyingSheet = ctx.workbook.getWorksheet(qualified.sheetName);
|
|
629
|
+
if (qualifyingSheet) {
|
|
630
|
+
// Match the scoping key used in `buildResolverContext` — always
|
|
631
|
+
// prefer `orderNo` (the mixed-tab workbook position, counting
|
|
632
|
+
// chartsheets) over `worksheets.indexOf` (the worksheets-only
|
|
633
|
+
// position). When these disagree — e.g. in a workbook ordered
|
|
634
|
+
// `[WS1, ChartSheet, WS2]`, `WS2.orderNo === 2` but
|
|
635
|
+
// `worksheets.indexOf(WS2) === 1` — sheet-scoped defined name
|
|
636
|
+
// lookups via bare and qualified paths must agree, otherwise
|
|
637
|
+
// the qualified path silently falls back to the workbook-scoped
|
|
638
|
+
// entry (or misses entirely) while the bare path finds the
|
|
639
|
+
// correct sheet-scoped one.
|
|
640
|
+
const sheetIdx = typeof qualifyingSheet.orderNo === "number"
|
|
641
|
+
? qualifyingSheet.orderNo
|
|
642
|
+
: ctx.workbook.worksheets.indexOf(qualifyingSheet);
|
|
643
|
+
if (sheetIdx >= 0) {
|
|
644
|
+
const scoped = getDefinedNameRanges(ctx.workbook, qualified.name, sheetIdx);
|
|
645
|
+
if (scoped) {
|
|
646
|
+
return { name: qualified.name, localSheetId: sheetIdx, ranges: scoped };
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
const global = getDefinedNameRanges(ctx.workbook, qualified.name, undefined);
|
|
651
|
+
if (global) {
|
|
652
|
+
return { name: qualified.name, ranges: global };
|
|
653
|
+
}
|
|
654
|
+
return undefined;
|
|
655
|
+
}
|
|
656
|
+
// Bare form: must pass the name shape gate to avoid calling into the
|
|
657
|
+
// defined-names API for every failed cell reference.
|
|
658
|
+
if (!BARE_DEFINED_NAME_RE.test(trimmed)) {
|
|
659
|
+
return undefined;
|
|
660
|
+
}
|
|
661
|
+
// Sheet-scoped on the context worksheet wins, then workbook-scoped.
|
|
662
|
+
if (ctx.localSheetId !== undefined) {
|
|
663
|
+
const scoped = getDefinedNameRanges(ctx.workbook, trimmed, ctx.localSheetId);
|
|
664
|
+
if (scoped) {
|
|
665
|
+
return { name: trimmed, localSheetId: ctx.localSheetId, ranges: scoped };
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
const global = getDefinedNameRanges(ctx.workbook, trimmed, undefined);
|
|
669
|
+
if (global) {
|
|
670
|
+
return { name: trimmed, ranges: global };
|
|
671
|
+
}
|
|
672
|
+
return undefined;
|
|
673
|
+
}
|
|
674
|
+
/**
|
|
675
|
+
* Read the ranges (or formula expression) associated with a defined name at
|
|
676
|
+
* a specific scope. Returns `undefined` when no entry exists at that scope.
|
|
677
|
+
*/
|
|
678
|
+
function getDefinedNameRanges(workbook, name, localSheetId) {
|
|
679
|
+
const definedNames = workbook.definedNames;
|
|
680
|
+
if (!definedNames) {
|
|
681
|
+
return undefined;
|
|
682
|
+
}
|
|
683
|
+
const model = definedNames.getRangesScoped(name, localSheetId);
|
|
684
|
+
if (!model.ranges || model.ranges.length === 0) {
|
|
685
|
+
return undefined;
|
|
686
|
+
}
|
|
687
|
+
// Verify the entry actually exists at the requested scope — getRangesScoped
|
|
688
|
+
// falls back to the bare name when the scoped key is missing, and we must
|
|
689
|
+
// not return workbook-scoped results from a sheet-scoped lookup.
|
|
690
|
+
const matrixMap = definedNames.matrixMap;
|
|
691
|
+
const formulaMap = definedNames.formulaMap;
|
|
692
|
+
const sKey = localSheetId !== undefined ? `${name}\0${localSheetId}` : name;
|
|
693
|
+
if (!matrixMap[sKey] && formulaMap[sKey] === undefined) {
|
|
694
|
+
return undefined;
|
|
695
|
+
}
|
|
696
|
+
return model.ranges;
|
|
697
|
+
}
|
|
698
|
+
function storageKey(name, localSheetId) {
|
|
699
|
+
return localSheetId !== undefined ? `${name}\0${localSheetId}` : name;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Split `Sheet!Name` or `'Quoted Sheet'!Name` into its components. Returns
|
|
703
|
+
* `undefined` when the input is not of that shape or the right-hand side
|
|
704
|
+
* contains range punctuation (in which case it is a cell reference, not a
|
|
705
|
+
* defined-name reference).
|
|
706
|
+
*/
|
|
707
|
+
function splitQualifiedName(formula) {
|
|
708
|
+
let i = 0;
|
|
709
|
+
let sheetName = "";
|
|
710
|
+
if (formula[0] === "'") {
|
|
711
|
+
// Walk a quoted sheet name, treating '' as an escaped single quote.
|
|
712
|
+
i = 1;
|
|
713
|
+
while (i < formula.length) {
|
|
714
|
+
if (formula[i] === "'" && formula[i + 1] === "'") {
|
|
715
|
+
sheetName += "'";
|
|
716
|
+
i += 2;
|
|
717
|
+
}
|
|
718
|
+
else if (formula[i] === "'") {
|
|
719
|
+
i++;
|
|
720
|
+
break;
|
|
721
|
+
}
|
|
722
|
+
else {
|
|
723
|
+
sheetName += formula[i];
|
|
724
|
+
i++;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
else {
|
|
729
|
+
// Unquoted sheet name — ends at the first '!'.
|
|
730
|
+
const bang = formula.indexOf("!");
|
|
731
|
+
if (bang <= 0) {
|
|
732
|
+
return undefined;
|
|
733
|
+
}
|
|
734
|
+
sheetName = formula.slice(0, bang);
|
|
735
|
+
i = bang;
|
|
736
|
+
}
|
|
737
|
+
if (formula[i] !== "!") {
|
|
738
|
+
return undefined;
|
|
739
|
+
}
|
|
740
|
+
const name = formula.slice(i + 1);
|
|
741
|
+
if (!BARE_DEFINED_NAME_RE.test(name)) {
|
|
742
|
+
return undefined;
|
|
743
|
+
}
|
|
744
|
+
return { sheetName, name };
|
|
745
|
+
}
|
|
746
|
+
/**
|
|
747
|
+
* Peel off an optional `Sheet1!` or `'My Sheet'!` prefix from a formula
|
|
748
|
+
* without validating the shape of the remainder. Unlike
|
|
749
|
+
* {@link splitQualifiedName} (which additionally checks that the RHS is a
|
|
750
|
+
* bare defined name), this helper is safe to use on structured
|
|
751
|
+
* references (`Table1[Col]`), absolute ranges (`$A$1:$B$2`) and anything
|
|
752
|
+
* else that might follow a sheet prefix.
|
|
753
|
+
*
|
|
754
|
+
* Returns `undefined` when the input has no sheet prefix — callers should
|
|
755
|
+
* treat that as "use the input unchanged".
|
|
756
|
+
*/
|
|
757
|
+
function splitSheetPrefix(formula) {
|
|
758
|
+
let i = 0;
|
|
759
|
+
let sheetName = "";
|
|
760
|
+
if (formula[0] === "'") {
|
|
761
|
+
i = 1;
|
|
762
|
+
while (i < formula.length) {
|
|
763
|
+
if (formula[i] === "'" && formula[i + 1] === "'") {
|
|
764
|
+
sheetName += "'";
|
|
765
|
+
i += 2;
|
|
766
|
+
}
|
|
767
|
+
else if (formula[i] === "'") {
|
|
768
|
+
i++;
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
else {
|
|
772
|
+
sheetName += formula[i];
|
|
773
|
+
i++;
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
if (formula[i] !== "!") {
|
|
777
|
+
return undefined;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
const bang = formula.indexOf("!");
|
|
782
|
+
if (bang <= 0) {
|
|
783
|
+
return undefined;
|
|
784
|
+
}
|
|
785
|
+
sheetName = formula.slice(0, bang);
|
|
786
|
+
i = bang;
|
|
787
|
+
}
|
|
788
|
+
if (formula[i] !== "!") {
|
|
789
|
+
return undefined;
|
|
790
|
+
}
|
|
791
|
+
return { sheetName, remainder: formula.slice(i + 1) };
|
|
792
|
+
}
|
|
793
|
+
function resolveStructuredReference(formula, workbook) {
|
|
794
|
+
// Excel accepts both bare (`Table1[Col]`) and sheet-qualified
|
|
795
|
+
// (`Sheet1!Table1[Col]`) structured references. Strip the optional sheet
|
|
796
|
+
// prefix so table lookup can operate on the bare `Table1[Col]` form; we
|
|
797
|
+
// also use the prefix to bias the worksheet search order so a same-named
|
|
798
|
+
// table on the referenced sheet wins over an unrelated sheet that
|
|
799
|
+
// happens to carry the same name.
|
|
800
|
+
//
|
|
801
|
+
// NOTE: `splitQualifiedName` validates the RHS against
|
|
802
|
+
// `BARE_DEFINED_NAME_RE`, which rejects structured references because
|
|
803
|
+
// they contain `[`. We therefore use a dedicated sheet-prefix splitter
|
|
804
|
+
// that does not gate on name shape — `splitSheetPrefix` only peels off
|
|
805
|
+
// the quoted / unquoted sheet name, leaving the table reference
|
|
806
|
+
// syntactically intact.
|
|
807
|
+
const split = splitSheetPrefix(formula.trim());
|
|
808
|
+
const bareFormula = split ? split.remainder : formula.trim();
|
|
809
|
+
const preferredSheetName = split?.sheetName;
|
|
810
|
+
const parsed = parseStructuredReference(bareFormula);
|
|
811
|
+
if (!parsed) {
|
|
812
|
+
return undefined;
|
|
813
|
+
}
|
|
814
|
+
const worksheets = [...workbook.worksheets];
|
|
815
|
+
if (preferredSheetName) {
|
|
816
|
+
// Move the preferred sheet to the front of the search (case-insensitive).
|
|
817
|
+
const target = preferredSheetName.toLowerCase();
|
|
818
|
+
const idx = worksheets.findIndex(ws => ws.name.toLowerCase() === target);
|
|
819
|
+
if (idx > 0) {
|
|
820
|
+
worksheets.unshift(...worksheets.splice(idx, 1));
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
for (const worksheet of worksheets) {
|
|
824
|
+
const table = worksheet
|
|
825
|
+
.getTables()
|
|
826
|
+
.find(t => t.name === parsed.tableName || t.displayName === parsed.tableName);
|
|
827
|
+
if (!table) {
|
|
828
|
+
continue;
|
|
829
|
+
}
|
|
830
|
+
const model = table.model;
|
|
831
|
+
const columnIndex = model.columns.findIndex(column => column.name === parsed.columnName);
|
|
832
|
+
if (columnIndex < 0) {
|
|
833
|
+
return undefined;
|
|
834
|
+
}
|
|
835
|
+
const tableRef = colCache.decode(model.tableRef ?? model.ref);
|
|
836
|
+
if (!("top" in tableRef)) {
|
|
837
|
+
return undefined;
|
|
838
|
+
}
|
|
839
|
+
const dataStartRow = tableRef.top + (model.headerRow === false ? 0 : 1);
|
|
840
|
+
const dataEndRow = tableRef.bottom - (model.totalsRow ? 1 : 0);
|
|
841
|
+
const col = tableRef.left + columnIndex;
|
|
842
|
+
const cells = [];
|
|
843
|
+
for (let row = dataStartRow; row <= dataEndRow; row++) {
|
|
844
|
+
cells.push({ value: extractCellValue(worksheet, row, col) });
|
|
845
|
+
}
|
|
846
|
+
return { worksheet, cells };
|
|
847
|
+
}
|
|
848
|
+
return undefined;
|
|
849
|
+
}
|
|
850
|
+
function parseStructuredReference(formula) {
|
|
851
|
+
const table = readStructuredTableName(formula);
|
|
852
|
+
if (!table || formula[table.end] !== "[" || !formula.endsWith("]")) {
|
|
853
|
+
return undefined;
|
|
854
|
+
}
|
|
855
|
+
const body = formula.slice(table.end + 1, -1);
|
|
856
|
+
if (body.length === 0) {
|
|
857
|
+
return undefined;
|
|
858
|
+
}
|
|
859
|
+
const columnName = extractStructuredReferenceColumn(body);
|
|
860
|
+
return columnName ? { tableName: table.name, columnName } : undefined;
|
|
861
|
+
}
|
|
862
|
+
function readStructuredTableName(formula) {
|
|
863
|
+
if (formula.startsWith("'")) {
|
|
864
|
+
let name = "";
|
|
865
|
+
for (let i = 1; i < formula.length; i++) {
|
|
866
|
+
if (formula[i] === "'" && formula[i + 1] === "'") {
|
|
867
|
+
name += "'";
|
|
868
|
+
i++;
|
|
869
|
+
}
|
|
870
|
+
else if (formula[i] === "'") {
|
|
871
|
+
return { name, end: i + 1 };
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
name += formula[i];
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return undefined;
|
|
878
|
+
}
|
|
879
|
+
const bracket = formula.indexOf("[");
|
|
880
|
+
if (bracket <= 0) {
|
|
881
|
+
return undefined;
|
|
882
|
+
}
|
|
883
|
+
return { name: formula.slice(0, bracket), end: bracket };
|
|
884
|
+
}
|
|
885
|
+
function extractStructuredReferenceColumn(body) {
|
|
886
|
+
if (body.startsWith("@")) {
|
|
887
|
+
const inner = body.slice(1).replace(/^\[(.*)\]$/, "$1");
|
|
888
|
+
const item = readStructuredReferenceItem(`${inner}]`, 0);
|
|
889
|
+
return item.value;
|
|
890
|
+
}
|
|
891
|
+
if (!body.startsWith("[")) {
|
|
892
|
+
if (body.startsWith("#")) {
|
|
893
|
+
return undefined;
|
|
894
|
+
}
|
|
895
|
+
const item = readStructuredReferenceItem(`${body}]`, 0);
|
|
896
|
+
return item.value;
|
|
897
|
+
}
|
|
898
|
+
const items = [];
|
|
899
|
+
let i = 0;
|
|
900
|
+
while (i < body.length) {
|
|
901
|
+
if (body[i] !== "[") {
|
|
902
|
+
i++;
|
|
903
|
+
continue;
|
|
904
|
+
}
|
|
905
|
+
const item = readStructuredReferenceItem(body, i + 1);
|
|
906
|
+
items.push(item.value);
|
|
907
|
+
i = item.end;
|
|
908
|
+
}
|
|
909
|
+
return items.filter(item => item && !item.startsWith("#")).pop();
|
|
910
|
+
}
|
|
911
|
+
function readStructuredReferenceItem(value, start) {
|
|
912
|
+
let i = start;
|
|
913
|
+
let result = "";
|
|
914
|
+
while (i < value.length) {
|
|
915
|
+
if (value[i] === "'" && i + 1 < value.length) {
|
|
916
|
+
result += value[i + 1];
|
|
917
|
+
i += 2;
|
|
918
|
+
}
|
|
919
|
+
else if (value[i] === "]") {
|
|
920
|
+
i++;
|
|
921
|
+
break;
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
result += value[i];
|
|
925
|
+
i++;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
return { value: result.trim(), end: i };
|
|
929
|
+
}
|
|
930
|
+
function resolveReferenceMatrix(formula, ctx) {
|
|
931
|
+
// Expand defined-name references up front so a named multi-area range can
|
|
932
|
+
// still drive a multi-level string cache.
|
|
933
|
+
const named = findDefinedName(formula, ctx);
|
|
934
|
+
if (named) {
|
|
935
|
+
const visitKey = storageKey(named.name, named.localSheetId);
|
|
936
|
+
if (ctx.visitedDefinedNames.has(visitKey)) {
|
|
937
|
+
return undefined;
|
|
938
|
+
}
|
|
939
|
+
// Same depth guard as `resolveDefinedNameReference`; matrices route
|
|
940
|
+
// through a separate code path so they need their own bail-out.
|
|
941
|
+
if (ctx.definedNameDepth >= MAX_DEFINED_NAME_DEPTH) {
|
|
942
|
+
return undefined;
|
|
943
|
+
}
|
|
944
|
+
ctx.visitedDefinedNames.add(visitKey);
|
|
945
|
+
ctx.definedNameDepth += 1;
|
|
946
|
+
try {
|
|
947
|
+
let firstWorksheet;
|
|
948
|
+
const mergedValues = [];
|
|
949
|
+
let mergedColumnCount = 0;
|
|
950
|
+
for (const rangeStr of named.ranges) {
|
|
951
|
+
const inner = resolveReferenceMatrix(rangeStr, ctx);
|
|
952
|
+
if (!inner) {
|
|
953
|
+
continue;
|
|
954
|
+
}
|
|
955
|
+
if (!firstWorksheet) {
|
|
956
|
+
firstWorksheet = inner.worksheet;
|
|
957
|
+
}
|
|
958
|
+
mergedValues.push(...inner.values);
|
|
959
|
+
mergedColumnCount = Math.max(mergedColumnCount, inner.columnCount);
|
|
960
|
+
}
|
|
961
|
+
if (!firstWorksheet) {
|
|
962
|
+
return undefined;
|
|
963
|
+
}
|
|
964
|
+
return {
|
|
965
|
+
worksheet: firstWorksheet,
|
|
966
|
+
values: mergedValues,
|
|
967
|
+
rowCount: mergedValues.length,
|
|
968
|
+
columnCount: mergedColumnCount
|
|
969
|
+
};
|
|
970
|
+
}
|
|
971
|
+
finally {
|
|
972
|
+
ctx.visitedDefinedNames.delete(visitKey);
|
|
973
|
+
ctx.definedNameDepth -= 1;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
const parts = splitFormulaRanges(formula);
|
|
977
|
+
let worksheet;
|
|
978
|
+
const rows = [];
|
|
979
|
+
let columnCount = 0;
|
|
980
|
+
for (const part of parts) {
|
|
981
|
+
const trimmed = part.trim();
|
|
982
|
+
if (!trimmed) {
|
|
983
|
+
continue;
|
|
984
|
+
}
|
|
985
|
+
let decoded;
|
|
986
|
+
try {
|
|
987
|
+
decoded = colCache.decodeEx(trimmed);
|
|
988
|
+
}
|
|
989
|
+
catch {
|
|
990
|
+
return undefined;
|
|
991
|
+
}
|
|
992
|
+
// See `resolveReference`: treat `{ error: ... }` results from
|
|
993
|
+
// `decodeEx` as unresolved rather than as empty cell sets.
|
|
994
|
+
if ("error" in decoded) {
|
|
995
|
+
return undefined;
|
|
996
|
+
}
|
|
997
|
+
const sheetName = decoded.sheetName;
|
|
998
|
+
if (!sheetName) {
|
|
999
|
+
return undefined;
|
|
1000
|
+
}
|
|
1001
|
+
const ws = ctx.workbook.getWorksheet(sheetName);
|
|
1002
|
+
if (!ws) {
|
|
1003
|
+
return undefined;
|
|
1004
|
+
}
|
|
1005
|
+
if (!worksheet) {
|
|
1006
|
+
worksheet = ws;
|
|
1007
|
+
}
|
|
1008
|
+
if ("top" in decoded && "left" in decoded) {
|
|
1009
|
+
const top = decoded.top;
|
|
1010
|
+
const left = decoded.left;
|
|
1011
|
+
const bottom = decoded.bottom;
|
|
1012
|
+
const right = decoded.right;
|
|
1013
|
+
columnCount = Math.max(columnCount, right - left + 1);
|
|
1014
|
+
for (let r = top; r <= bottom; r++) {
|
|
1015
|
+
const row = [];
|
|
1016
|
+
for (let c = left; c <= right; c++) {
|
|
1017
|
+
row.push(extractCellValue(ws, r, c));
|
|
1018
|
+
}
|
|
1019
|
+
rows.push(row);
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
else if ("row" in decoded && "col" in decoded) {
|
|
1023
|
+
columnCount = Math.max(columnCount, 1);
|
|
1024
|
+
rows.push([extractCellValue(ws, decoded.row, decoded.col)]);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
if (!worksheet) {
|
|
1028
|
+
return undefined;
|
|
1029
|
+
}
|
|
1030
|
+
return { worksheet, values: rows, rowCount: rows.length, columnCount };
|
|
1031
|
+
}
|
|
1032
|
+
/**
|
|
1033
|
+
* Split a chart formula that may contain multiple ranges (union) separated
|
|
1034
|
+
* by commas or semicolons, respecting quoted sheet names.
|
|
1035
|
+
*/
|
|
1036
|
+
function splitFormulaRanges(formula) {
|
|
1037
|
+
const parts = [];
|
|
1038
|
+
let current = "";
|
|
1039
|
+
let inQuote = false;
|
|
1040
|
+
for (let i = 0; i < formula.length; i++) {
|
|
1041
|
+
const ch = formula[i];
|
|
1042
|
+
if (ch === "'") {
|
|
1043
|
+
// Excel escapes a single quote inside a sheet name as ''
|
|
1044
|
+
if (inQuote && formula[i + 1] === "'") {
|
|
1045
|
+
current += "''";
|
|
1046
|
+
i++;
|
|
1047
|
+
continue;
|
|
1048
|
+
}
|
|
1049
|
+
inQuote = !inQuote;
|
|
1050
|
+
current += ch;
|
|
1051
|
+
}
|
|
1052
|
+
else if (!inQuote && (ch === "," || ch === ";")) {
|
|
1053
|
+
parts.push(current);
|
|
1054
|
+
current = "";
|
|
1055
|
+
}
|
|
1056
|
+
else {
|
|
1057
|
+
current += ch;
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
if (current) {
|
|
1061
|
+
parts.push(current);
|
|
1062
|
+
}
|
|
1063
|
+
return parts;
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Extract a raw value from a worksheet cell.
|
|
1067
|
+
* Avoids forcing creation of empty cells by using the row-level accessor.
|
|
1068
|
+
*/
|
|
1069
|
+
function extractCellValue(ws, row, col) {
|
|
1070
|
+
// Worksheet.getCell creates sparse cell slots but does not mutate existing
|
|
1071
|
+
// values — safe to call.
|
|
1072
|
+
const cell = ws.getCell(row, col);
|
|
1073
|
+
const v = cell.value;
|
|
1074
|
+
if (v === null || v === undefined) {
|
|
1075
|
+
return undefined;
|
|
1076
|
+
}
|
|
1077
|
+
// Formula values are wrapped: { formula, result }
|
|
1078
|
+
if (typeof v === "object" && "result" in v) {
|
|
1079
|
+
const result = v.result;
|
|
1080
|
+
return result;
|
|
1081
|
+
}
|
|
1082
|
+
// Rich text
|
|
1083
|
+
if (typeof v === "object" && "richText" in v) {
|
|
1084
|
+
const rt = v.richText;
|
|
1085
|
+
if (rt) {
|
|
1086
|
+
return rt.map(r => r.text ?? "").join("");
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
// Hyperlink / error
|
|
1090
|
+
if (typeof v === "object") {
|
|
1091
|
+
if ("error" in v) {
|
|
1092
|
+
return undefined;
|
|
1093
|
+
}
|
|
1094
|
+
if ("text" in v && "hyperlink" in v) {
|
|
1095
|
+
return v.text;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return v;
|
|
1099
|
+
}
|
|
1100
|
+
function toNumber(v, date1904) {
|
|
1101
|
+
if (v === null || v === undefined) {
|
|
1102
|
+
return undefined;
|
|
1103
|
+
}
|
|
1104
|
+
if (typeof v === "number") {
|
|
1105
|
+
return Number.isFinite(v) ? v : undefined;
|
|
1106
|
+
}
|
|
1107
|
+
if (typeof v === "boolean") {
|
|
1108
|
+
return v ? 1 : 0;
|
|
1109
|
+
}
|
|
1110
|
+
if (v instanceof Date) {
|
|
1111
|
+
// Delegate to the canonical converter in `@utils/utils.base` so the
|
|
1112
|
+
// epoch / date1904 offset stays consistent with the rest of the
|
|
1113
|
+
// codebase (`cell-format`, formula engine, XML writer). A previous
|
|
1114
|
+
// local implementation used a `Date.UTC(1899, 11, 30)` epoch with
|
|
1115
|
+
// its own `serial >= 60 → +1` hack that was both off-by-one
|
|
1116
|
+
// (canonical epoch is Dec 31 1899) AND timezone-dependent (since
|
|
1117
|
+
// callers may pass local-time `Date`s whose UTC projection differs).
|
|
1118
|
+
return dateToExcel(v, date1904);
|
|
1119
|
+
}
|
|
1120
|
+
if (typeof v === "string") {
|
|
1121
|
+
// Try to coerce numeric string
|
|
1122
|
+
const n = Number(v);
|
|
1123
|
+
if (Number.isFinite(n) && v.trim() !== "") {
|
|
1124
|
+
return n;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return undefined;
|
|
1128
|
+
}
|
|
1129
|
+
function toString(v) {
|
|
1130
|
+
if (v === null || v === undefined) {
|
|
1131
|
+
return undefined;
|
|
1132
|
+
}
|
|
1133
|
+
if (typeof v === "string") {
|
|
1134
|
+
return v;
|
|
1135
|
+
}
|
|
1136
|
+
if (typeof v === "number" || typeof v === "boolean") {
|
|
1137
|
+
return String(v);
|
|
1138
|
+
}
|
|
1139
|
+
if (v instanceof Date) {
|
|
1140
|
+
// Date-cells feeding a chart's category axis (via a `strRef` — e.g.
|
|
1141
|
+
// `=Sheet1!$A$1:$A$10` where A1:A10 are dates) should surface as
|
|
1142
|
+
// human-readable labels, not ISO 8601 timestamps. `toISOString()`
|
|
1143
|
+
// produced output like `"2023-01-15T00:00:00.000Z"` which rendered
|
|
1144
|
+
// verbatim on axis labels and diverged from Excel's cache (Excel
|
|
1145
|
+
// stores the formatted display text per the referenced cell's
|
|
1146
|
+
// numFmt).
|
|
1147
|
+
//
|
|
1148
|
+
// We don't have access to the source cell's numFmt from this
|
|
1149
|
+
// fallback path, but a locale-neutral `YYYY-MM-DD` (or
|
|
1150
|
+
// `YYYY-MM-DD HH:mm:ss` when the time portion is non-zero) is a
|
|
1151
|
+
// reasonable approximation that renders well in every preview and
|
|
1152
|
+
// matches Excel's default date format more closely than ISO.
|
|
1153
|
+
if (Number.isNaN(v.getTime())) {
|
|
1154
|
+
return undefined;
|
|
1155
|
+
}
|
|
1156
|
+
const year = v.getUTCFullYear().toString().padStart(4, "0");
|
|
1157
|
+
const month = (v.getUTCMonth() + 1).toString().padStart(2, "0");
|
|
1158
|
+
const day = v.getUTCDate().toString().padStart(2, "0");
|
|
1159
|
+
const hour = v.getUTCHours();
|
|
1160
|
+
const min = v.getUTCMinutes();
|
|
1161
|
+
const sec = v.getUTCSeconds();
|
|
1162
|
+
if (hour === 0 && min === 0 && sec === 0) {
|
|
1163
|
+
return `${year}-${month}-${day}`;
|
|
1164
|
+
}
|
|
1165
|
+
const hh = hour.toString().padStart(2, "0");
|
|
1166
|
+
const mm = min.toString().padStart(2, "0");
|
|
1167
|
+
const ss = sec.toString().padStart(2, "0");
|
|
1168
|
+
return `${year}-${month}-${day} ${hh}:${mm}:${ss}`;
|
|
1169
|
+
}
|
|
1170
|
+
return undefined;
|
|
1171
|
+
}
|