@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,1324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Chart - High-level chart object for worksheet embedding.
|
|
4
|
+
*
|
|
5
|
+
* Similar to Image, a Chart belongs to a Worksheet and carries the
|
|
6
|
+
* structural data needed for both the DrawingML anchor and the
|
|
7
|
+
* standalone chart XML part.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.buildChartModel = exports.Chart = void 0;
|
|
11
|
+
const anchor_1 = require("../anchor.js");
|
|
12
|
+
const errors_1 = require("../errors.js");
|
|
13
|
+
const col_cache_1 = require("../utils/col-cache.js");
|
|
14
|
+
const rel_type_1 = require("../xlsx/rel-type.js");
|
|
15
|
+
const cache_populator_1 = require("./cache-populator");
|
|
16
|
+
const chart_builder_1 = require("./chart-builder");
|
|
17
|
+
Object.defineProperty(exports, "buildChartModel", { enumerable: true, get: function () { return chart_builder_1.buildChartModel; } });
|
|
18
|
+
const chart_ex_renderer_1 = require("./chart-ex-renderer");
|
|
19
|
+
const chart_images_1 = require("./chart-images");
|
|
20
|
+
const chart_renderer_1 = require("./chart-renderer");
|
|
21
|
+
const shape_properties_1 = require("./shape-properties");
|
|
22
|
+
/**
|
|
23
|
+
* Default chart extent when a caller passes a single-cell address. Matches
|
|
24
|
+
* Excel's behaviour on a fresh chart insertion (roughly 10 columns × 15
|
|
25
|
+
* rows). Shared between the initial anchor resolution and {@link Chart._cloneRange}
|
|
26
|
+
* so the two paths cannot drift.
|
|
27
|
+
*/
|
|
28
|
+
const DEFAULT_CHART_WIDTH_COLS = 10;
|
|
29
|
+
const DEFAULT_CHART_HEIGHT_ROWS = 15;
|
|
30
|
+
// Pre-compiled regexes for _extractTextFromRawTx.
|
|
31
|
+
// NOTE: These patterns are consumed via `String.prototype.matchAll`, which
|
|
32
|
+
// returns a fresh iterator per call. They are intentionally NOT used with
|
|
33
|
+
// `RegExp.prototype.exec` + shared `lastIndex`, which would interleave state
|
|
34
|
+
// across concurrent callers (multiple titles extracted on the same chart in
|
|
35
|
+
// parallel promise chains).
|
|
36
|
+
//
|
|
37
|
+
// The `<a:t>` open tag may carry attributes — notably `xml:space="preserve"`
|
|
38
|
+
// when the run contains leading / trailing or internal whitespace. The
|
|
39
|
+
// original pattern (`<a:t>…`) missed those, causing the text extractor
|
|
40
|
+
// to skip every preserved-whitespace run. Allow a `>` or any attribute
|
|
41
|
+
// list (`[^>]*>`) to close the open tag.
|
|
42
|
+
const RAW_TX_AT_RE = /<a:t(?:\s[^>]*)?>([\s\S]*?)<\/a:t>/g;
|
|
43
|
+
const RAW_TX_CV_RE = /<c:v(?:\s[^>]*)?>([\s\S]*?)<\/c:v>/g;
|
|
44
|
+
/**
|
|
45
|
+
* A chart embedded in a worksheet.
|
|
46
|
+
*
|
|
47
|
+
* Charts come in two flavours:
|
|
48
|
+
*
|
|
49
|
+
* - **Classic** (`chartNumber` set): a fully-parsed `c:chart` with a
|
|
50
|
+
* {@link ChartModel}. All public accessors (`chartModel`,
|
|
51
|
+
* `chartTypes`, `axes`, series mutators, `style`, `mutate`, …) are
|
|
52
|
+
* backed by the structured model.
|
|
53
|
+
*
|
|
54
|
+
* - **ChartEx** (`chartExNumber` set): Office 2016+ `cx:chart`. The
|
|
55
|
+
* structured model (`chartExModel`) is populated; a parallel
|
|
56
|
+
* `rawXml` buffer is kept so byte-for-byte round-trip is the default
|
|
57
|
+
* when no mutation happens. The high-level accessors that make
|
|
58
|
+
* sense on both flavours (`title`, `legend`, `spPr`, `toSVG`,
|
|
59
|
+
* `toPNG`, `unknownElements`) work uniformly. ChartTypeGroup-level
|
|
60
|
+
* APIs (`chartTypes`, `axes`, `plotArea`, `getAxis`, `categoryAxis`,
|
|
61
|
+
* `valueAxis`, `addSeries`, `removeSeries`, `getSeries`,
|
|
62
|
+
* `updateSeries`, `addSeriesFromOptions`, `seriesCount`, `mutate`,
|
|
63
|
+
* `setStyle`) are classic-only — ChartEx has its own topology that
|
|
64
|
+
* doesn't map cleanly onto the classic group/series abstraction;
|
|
65
|
+
* use {@link Chart.mutateChartEx} for ChartEx mutations.
|
|
66
|
+
*/
|
|
67
|
+
class Chart {
|
|
68
|
+
constructor(worksheet, ids, range) {
|
|
69
|
+
this.worksheet = worksheet;
|
|
70
|
+
this.chartNumber = ids.chartNumber ?? 0;
|
|
71
|
+
this.chartExNumber = ids.chartExNumber ?? 0;
|
|
72
|
+
this.range = Chart.parseRange(worksheet, range);
|
|
73
|
+
}
|
|
74
|
+
/** Whether this is an Office 2016+ extended chart (cx:chart) */
|
|
75
|
+
get isChartEx() {
|
|
76
|
+
return this.chartExNumber > 0;
|
|
77
|
+
}
|
|
78
|
+
static parseRange(worksheet, range) {
|
|
79
|
+
if (typeof range === "string") {
|
|
80
|
+
const decoded = col_cache_1.colCache.decode(range);
|
|
81
|
+
if ("top" in decoded) {
|
|
82
|
+
return {
|
|
83
|
+
tl: new anchor_1.Anchor(worksheet, { col: decoded.left, row: decoded.top }, -1),
|
|
84
|
+
br: new anchor_1.Anchor(worksheet, { col: decoded.right, row: decoded.bottom }, 0),
|
|
85
|
+
editAs: "twoCell"
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// Single cell — default to DEFAULT_CHART_WIDTH_COLS x DEFAULT_CHART_HEIGHT_ROWS.
|
|
89
|
+
const addr = col_cache_1.colCache.decodeAddress(range);
|
|
90
|
+
return {
|
|
91
|
+
tl: new anchor_1.Anchor(worksheet, { col: addr.col, row: addr.row }, -1),
|
|
92
|
+
br: new anchor_1.Anchor(worksheet, {
|
|
93
|
+
col: addr.col + DEFAULT_CHART_WIDTH_COLS,
|
|
94
|
+
row: addr.row + DEFAULT_CHART_HEIGHT_ROWS
|
|
95
|
+
}, 0),
|
|
96
|
+
editAs: "twoCell"
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const parseAnchor = (v) => {
|
|
100
|
+
if (typeof v === "string") {
|
|
101
|
+
return new anchor_1.Anchor(worksheet, v, -1);
|
|
102
|
+
}
|
|
103
|
+
return new anchor_1.Anchor(worksheet, v, 0);
|
|
104
|
+
};
|
|
105
|
+
// Absolute anchor: { pos, ext }. `ext` is mandatory — without it
|
|
106
|
+
// the drawing layer has no extent to emit and the writer would
|
|
107
|
+
// produce `<xdr:ext cx="undefined" cy="undefined"/>`. Reject
|
|
108
|
+
// early so callers see a clear error at the assignment site
|
|
109
|
+
// rather than an opaque serialization failure.
|
|
110
|
+
if ("pos" in range && range.pos !== undefined) {
|
|
111
|
+
if (!range.ext) {
|
|
112
|
+
throw new errors_1.ChartOptionsError("Chart range with `pos` requires `ext` (absolute anchor needs an explicit EMU extent).");
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
// Absolute anchors have no meaningful "tl" cell, but the drawing layer
|
|
116
|
+
// still requires one — default to (0, 0) with the provided offsets.
|
|
117
|
+
tl: new anchor_1.Anchor(worksheet, { col: 0, row: 0 }, 0),
|
|
118
|
+
pos: range.pos,
|
|
119
|
+
ext: range.ext,
|
|
120
|
+
editAs: range.editAs ?? "absolute"
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// One-cell anchor: { tl, ext } with no bottom-right. We key on
|
|
124
|
+
// `range.br === undefined` (not `"br" in range`) so a caller that
|
|
125
|
+
// passes `{ tl, ext, br: undefined }` still lands here instead of
|
|
126
|
+
// falling through to the two-cell branch, which would then call
|
|
127
|
+
// `parseAnchor(undefined)` and throw from inside the Anchor
|
|
128
|
+
// constructor.
|
|
129
|
+
if ("tl" in range &&
|
|
130
|
+
"ext" in range &&
|
|
131
|
+
range.ext !== undefined &&
|
|
132
|
+
(!("br" in range) || range.br === undefined)) {
|
|
133
|
+
return {
|
|
134
|
+
tl: parseAnchor(range.tl),
|
|
135
|
+
ext: range.ext,
|
|
136
|
+
editAs: range.editAs ?? "oneCell"
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// Two-cell anchor: { tl, br }
|
|
140
|
+
const twoCell = range;
|
|
141
|
+
return {
|
|
142
|
+
tl: parseAnchor(twoCell.tl),
|
|
143
|
+
br: parseAnchor(twoCell.br),
|
|
144
|
+
editAs: twoCell.editAs ?? "twoCell"
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
get model() {
|
|
148
|
+
const base = {
|
|
149
|
+
chartNumber: this.chartNumber,
|
|
150
|
+
chartExNumber: this.chartExNumber,
|
|
151
|
+
range: {
|
|
152
|
+
tl: this.range.tl.model,
|
|
153
|
+
br: this.range.br ? this.range.br.model : undefined,
|
|
154
|
+
editAs: this.range.editAs,
|
|
155
|
+
pos: this.range.pos,
|
|
156
|
+
ext: this.range.ext
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
return base;
|
|
160
|
+
}
|
|
161
|
+
// ===========================================================================
|
|
162
|
+
// Chart data access
|
|
163
|
+
// ===========================================================================
|
|
164
|
+
/** Get the full ChartModel from the workbook's chart entries (classic charts only) */
|
|
165
|
+
get chartModel() {
|
|
166
|
+
if (this.chartNumber <= 0) {
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
return this.worksheet.workbook.getChartEntry(this.chartNumber)?.model;
|
|
170
|
+
}
|
|
171
|
+
/** Get the structured ChartEx model, when this chart is an Office 2016+ chartEx. */
|
|
172
|
+
get chartExModel() {
|
|
173
|
+
if (this.chartExNumber <= 0) {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
return this.worksheet.workbook.getChartExStructuredEntry(this.chartExNumber)?.model;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Vendor-extension elements the parser observed but could not map to a
|
|
180
|
+
* structured field. Populated when the chart was loaded from an existing
|
|
181
|
+
* `.xlsx` whose author emitted `c15:`/`cx14:` style extension tags (often
|
|
182
|
+
* MSO-internal; the OOXML spec treats them as implementation-specific).
|
|
183
|
+
*
|
|
184
|
+
* The array is **purely informational** in the default `preserve` writer
|
|
185
|
+
* mode — structural rebuilds keep the raw XML pass-through that contains
|
|
186
|
+
* those tags. In **`strictTemplateMode`** the writer surfaces this list
|
|
187
|
+
* in its failure message when a mutation cannot be expressed as a raw
|
|
188
|
+
* patch, so authors can decide between:
|
|
189
|
+
*
|
|
190
|
+
* 1. Relaxing `strictTemplateMode` and accepting that a rebuild will
|
|
191
|
+
* drop these vendor tags, or
|
|
192
|
+
* 2. Reshaping the mutation to land on a patch-friendly path (for
|
|
193
|
+
* example editing `title` text rather than replacing the whole
|
|
194
|
+
* `c:chart` subtree).
|
|
195
|
+
*
|
|
196
|
+
* Returns `undefined` if the chart was freshly created (no raw XML was
|
|
197
|
+
* ever parsed) or if every child was recognised. See
|
|
198
|
+
* {@link XlsxWriteOptions.strictTemplateMode} for the writer surface.
|
|
199
|
+
*/
|
|
200
|
+
get unknownElements() {
|
|
201
|
+
const classic = this.chartModel?.unknownElements;
|
|
202
|
+
if (classic && classic.length > 0) {
|
|
203
|
+
return classic.slice();
|
|
204
|
+
}
|
|
205
|
+
const chartEx = this.chartExModel?.unknownElements;
|
|
206
|
+
if (chartEx && chartEx.length > 0) {
|
|
207
|
+
return chartEx.slice();
|
|
208
|
+
}
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
// ===========================================================================
|
|
212
|
+
// User-shape drawing part (c:userShapes)
|
|
213
|
+
// ===========================================================================
|
|
214
|
+
/**
|
|
215
|
+
* Raw XML bytes of the `c:userShapes` drawing part attached to this
|
|
216
|
+
* chart, or `undefined` when the chart has no user shapes. User
|
|
217
|
+
* shapes are annotation overlays (callouts, arrows, free text) that
|
|
218
|
+
* Excel stores in a separate `xl/drawings/drawingN.xml` part using
|
|
219
|
+
* relative anchors — the OOXML spec keeps their DrawingML schema
|
|
220
|
+
* distinct from worksheet drawings, so the library treats the part
|
|
221
|
+
* as opaque bytes for round-trip and programmatic replacement
|
|
222
|
+
* instead of exposing a full structural API.
|
|
223
|
+
*
|
|
224
|
+
* Classic charts only. Returns `undefined` on chartEx charts (they
|
|
225
|
+
* have their own extension mechanism and do not use `c:userShapes`).
|
|
226
|
+
*/
|
|
227
|
+
get userShapesXml() {
|
|
228
|
+
if (this.chartNumber <= 0) {
|
|
229
|
+
return undefined;
|
|
230
|
+
}
|
|
231
|
+
return this.worksheet.workbook.getChartEntry(this.chartNumber)?.userShapesXml;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Replace the `c:userShapes` drawing part for this chart with the
|
|
235
|
+
* supplied raw XML bytes. Passing `undefined` or an empty byte
|
|
236
|
+
* array removes the user-shapes reference entirely (equivalent to
|
|
237
|
+
* {@link removeUserShapes}).
|
|
238
|
+
*
|
|
239
|
+
* The XML must be a complete DrawingML document whose root is a
|
|
240
|
+
* `c:userShapes` element containing `c:relSizeAnchor` /
|
|
241
|
+
* `c:absSizeAnchor` children. The library performs a shallow sanity
|
|
242
|
+
* check only — no schema validation.
|
|
243
|
+
*
|
|
244
|
+
* When a chart did not previously have user shapes, this allocates
|
|
245
|
+
* a new `r:id` and adds the drawing-part rel so the reference is
|
|
246
|
+
* discoverable in `chartN.xml.rels`. When a chart already had user
|
|
247
|
+
* shapes, the existing `r:id` is kept and only the bytes are
|
|
248
|
+
* updated.
|
|
249
|
+
*
|
|
250
|
+
* Classic charts only. Throws on chartEx charts.
|
|
251
|
+
*/
|
|
252
|
+
setUserShapesXml(xml) {
|
|
253
|
+
if (this.chartNumber <= 0) {
|
|
254
|
+
throw new errors_1.ChartOptionsError("Chart.setUserShapesXml is only supported on classic charts.");
|
|
255
|
+
}
|
|
256
|
+
const entry = this.worksheet.workbook.getChartEntry(this.chartNumber);
|
|
257
|
+
if (!entry) {
|
|
258
|
+
throw new errors_1.ChartOptionsError(`Chart ${this.chartNumber} has no registered chart entry.`);
|
|
259
|
+
}
|
|
260
|
+
if (xml === undefined) {
|
|
261
|
+
this.removeUserShapes();
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const bytes = typeof xml === "string" ? new TextEncoder().encode(xml) : xml;
|
|
265
|
+
// Empty strings / empty byte arrays are treated the same as `undefined`
|
|
266
|
+
// — they remove the user-shapes reference entirely.
|
|
267
|
+
if (bytes.length === 0) {
|
|
268
|
+
this.removeUserShapes();
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
// Minimal sanity check — full validation is left to downstream consumers.
|
|
272
|
+
const peek = new TextDecoder().decode(bytes.slice(0, 512));
|
|
273
|
+
if (!peek.includes("userShapes")) {
|
|
274
|
+
throw new errors_1.ChartOptionsError("Chart.setUserShapesXml expects a DrawingML document whose root is c:userShapes.");
|
|
275
|
+
}
|
|
276
|
+
entry.userShapesXml = bytes;
|
|
277
|
+
entry.dirty = true;
|
|
278
|
+
// Reserve an r:id if we didn't have one, and pre-record a matching
|
|
279
|
+
// rel entry so that other allocators on this chart part
|
|
280
|
+
// (e.g. `chart-images.resolvePendingChartImages`) see the id as
|
|
281
|
+
// already taken and don't reuse it. The writer rewrites the
|
|
282
|
+
// `Target` to the final `chartUserShape{N}.xml` path at emission
|
|
283
|
+
// time (xlsx writer, `_writeChart`), so the placeholder Target here
|
|
284
|
+
// is advisory only.
|
|
285
|
+
//
|
|
286
|
+
// We seed the counter from `max(existing numeric suffix) + 1`
|
|
287
|
+
// instead of `rels.length + 1`, because rels can be sparse
|
|
288
|
+
// (e.g. rId1 / rId5 with rId2-4 removed) and `length + 1` would
|
|
289
|
+
// collide with live identifiers in that case.
|
|
290
|
+
if (!entry.model.userShapesRelId) {
|
|
291
|
+
const rels = (entry.rels ?? (entry.rels = []));
|
|
292
|
+
const existing = new Set(rels.map(r => r?.Id).filter((id) => Boolean(id)));
|
|
293
|
+
let maxSeen = 0;
|
|
294
|
+
for (const id of existing) {
|
|
295
|
+
const match = /^rId(\d+)$/.exec(id);
|
|
296
|
+
if (match) {
|
|
297
|
+
const n = parseInt(match[1], 10);
|
|
298
|
+
if (Number.isFinite(n) && n > maxSeen) {
|
|
299
|
+
maxSeen = n;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
let counter = maxSeen + 1;
|
|
304
|
+
let rid = `rId${counter}`;
|
|
305
|
+
while (existing.has(rid)) {
|
|
306
|
+
counter += 1;
|
|
307
|
+
rid = `rId${counter}`;
|
|
308
|
+
}
|
|
309
|
+
entry.model.userShapesRelId = rid;
|
|
310
|
+
// Push a placeholder rel so downstream allocators see the id as
|
|
311
|
+
// taken. The xlsx writer resolves the Target to the actual
|
|
312
|
+
// drawing part path at emission time.
|
|
313
|
+
//
|
|
314
|
+
// CRITICAL: use `RelType.ChartUserShapes` (the canonical
|
|
315
|
+
// `chartUserShapes`, plural, ECMA-376 / Open XML SDK URI). An
|
|
316
|
+
// earlier version hardcoded the singular `chartUserShape` here,
|
|
317
|
+
// which drifted from `RelType.ChartUserShapes` used by the xlsx
|
|
318
|
+
// writer (see `xlsx.browser.ts`). The writer couldn't recognise
|
|
319
|
+
// this placeholder as the existing userShapes rel and would push
|
|
320
|
+
// a second rel on every write, producing a duplicate rel entry
|
|
321
|
+
// in the chart rels file.
|
|
322
|
+
const hasUserShapesRel = rels.some(r => r?.Type === rel_type_1.RelType.ChartUserShapes);
|
|
323
|
+
if (!hasUserShapesRel) {
|
|
324
|
+
rels.push({
|
|
325
|
+
Id: rid,
|
|
326
|
+
Type: rel_type_1.RelType.ChartUserShapes,
|
|
327
|
+
Target: ""
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Drop the `c:userShapes` reference and its backing drawing part.
|
|
334
|
+
* Classic charts only. No-op when the chart has no user shapes.
|
|
335
|
+
*/
|
|
336
|
+
removeUserShapes() {
|
|
337
|
+
if (this.chartNumber <= 0) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
const entry = this.worksheet.workbook.getChartEntry(this.chartNumber);
|
|
341
|
+
if (!entry) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (!entry.userShapesXml && !entry.model.userShapesRelId) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
entry.userShapesXml = undefined;
|
|
348
|
+
entry.dirty = true;
|
|
349
|
+
const relId = entry.model.userShapesRelId;
|
|
350
|
+
entry.model.userShapesRelId = undefined;
|
|
351
|
+
if (relId && Array.isArray(entry.rels)) {
|
|
352
|
+
entry.rels = entry.rels.filter(r => r?.Id !== relId);
|
|
353
|
+
}
|
|
354
|
+
// Also purge the matching rel from the workbook-level `_chartRels`
|
|
355
|
+
// bag. The writer merges `model.chartRels[n]` (which is
|
|
356
|
+
// `_chartRels`) into the emitted .rels file BEFORE folding in
|
|
357
|
+
// `entry.rels`, so cleaning only `entry.rels` leaves the original
|
|
358
|
+
// userShapes rel in place — producing a chart whose XML has no
|
|
359
|
+
// `<c:userShapes>` reference but whose .rels still points at a
|
|
360
|
+
// drawing part that is never emitted.
|
|
361
|
+
const workbook = this.worksheet.workbook;
|
|
362
|
+
const workbookChartRels = workbook._chartRels;
|
|
363
|
+
if (workbookChartRels && Array.isArray(workbookChartRels[this.chartNumber])) {
|
|
364
|
+
workbookChartRels[this.chartNumber] = workbookChartRels[this.chartNumber].filter(r => {
|
|
365
|
+
// Match on the specific `Id` we just cleared — but also defensively
|
|
366
|
+
// drop any entry whose `Type` points at a userShapes drawing
|
|
367
|
+
// rel, covering the edge case where the model lost track of its
|
|
368
|
+
// authored `userShapesRelId` but the rel is still present.
|
|
369
|
+
if (relId && r?.Id === relId) {
|
|
370
|
+
return false;
|
|
371
|
+
}
|
|
372
|
+
if (r?.Type === rel_type_1.RelType.ChartUserShapes) {
|
|
373
|
+
return false;
|
|
374
|
+
}
|
|
375
|
+
return true;
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Render this chart as a **zero-dependency deterministic preview** SVG.
|
|
381
|
+
*
|
|
382
|
+
* The output is suitable for thumbnails, email attachments,
|
|
383
|
+
* server-side report generation, CI smoke tests, and README images.
|
|
384
|
+
* It is **not** an Excel-pixel-perfect compositor — text layout,
|
|
385
|
+
* font metrics, and 3D projection are approximated for a stable
|
|
386
|
+
* preview rather than reproduced from Excel's internal renderer.
|
|
387
|
+
*
|
|
388
|
+
* For production-grade rendering (Excel-identical layout, real 3D
|
|
389
|
+
* for non-bar types, exact font hinting), round-trip the `.xlsx`
|
|
390
|
+
* through headless LibreOffice (`soffice --convert-to pdf`) — the
|
|
391
|
+
* byte-preserving round-trip + `templateMode: "strict"` guarantees
|
|
392
|
+
* in this library make that a safe handoff.
|
|
393
|
+
*
|
|
394
|
+
* See `src/modules/excel/README.md` → "Rendering scope" for the
|
|
395
|
+
* complete boundary list.
|
|
396
|
+
*/
|
|
397
|
+
toSVG(options = {}) {
|
|
398
|
+
const model = this.chartModel;
|
|
399
|
+
if (model) {
|
|
400
|
+
return (0, chart_renderer_1.renderChartSvg)(model, options);
|
|
401
|
+
}
|
|
402
|
+
const chartEx = this.chartExModel;
|
|
403
|
+
if (chartEx) {
|
|
404
|
+
this._refreshChartExCaches();
|
|
405
|
+
return (0, chart_ex_renderer_1.renderChartExSvg)(chartEx, options);
|
|
406
|
+
}
|
|
407
|
+
throw new errors_1.ChartOptionsError("Cannot render chart because no chart model is available.");
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Render this chart as a **zero-dependency deterministic preview** PNG.
|
|
411
|
+
*
|
|
412
|
+
* Browsers use a `<canvas>` pipeline; Node.js uses the built-in
|
|
413
|
+
* `BasicRasterCanvas` rasteriser (a pure-JS SVG-subset rasteriser —
|
|
414
|
+
* no native canvas dependency). DrawingML effect filters
|
|
415
|
+
* (shadow/glow/soft-edge/blur/reflection) round-trip through XML and
|
|
416
|
+
* emit as SVG `<filter>`, but the Node PNG rasteriser silently drops
|
|
417
|
+
* them; the browser canvas path renders them natively.
|
|
418
|
+
*
|
|
419
|
+
* See {@link toSVG} for the full scope-boundary note. For pixel-perfect
|
|
420
|
+
* output, convert through LibreOffice.
|
|
421
|
+
*/
|
|
422
|
+
async toPNG(options = {}) {
|
|
423
|
+
// `async` makes the "no model" branch reject the returned promise
|
|
424
|
+
// instead of throwing synchronously. The previous non-async form
|
|
425
|
+
// violated its `Promise<Uint8Array>` contract by throwing on the
|
|
426
|
+
// hot path — a caller using `.then().catch()` (e.g. a background
|
|
427
|
+
// job runner) would see an uncaught synchronous exception rather
|
|
428
|
+
// than a rejected promise.
|
|
429
|
+
const model = this.chartModel;
|
|
430
|
+
if (model) {
|
|
431
|
+
return (0, chart_renderer_1.renderChartPng)(model, options);
|
|
432
|
+
}
|
|
433
|
+
const chartEx = this.chartExModel;
|
|
434
|
+
if (chartEx) {
|
|
435
|
+
this._refreshChartExCaches();
|
|
436
|
+
return (0, chart_ex_renderer_1.renderChartExPng)(chartEx, options);
|
|
437
|
+
}
|
|
438
|
+
throw new errors_1.ChartOptionsError("Cannot render chart because no chart model is available.");
|
|
439
|
+
}
|
|
440
|
+
/** Get the chart title text. Returns undefined if no title. */
|
|
441
|
+
get title() {
|
|
442
|
+
const titleObj = this.chartModel?.chart?.title ?? this.chartExModel?.chartSpace?.chart?.title;
|
|
443
|
+
if (!titleObj) {
|
|
444
|
+
return undefined;
|
|
445
|
+
}
|
|
446
|
+
if (titleObj.text) {
|
|
447
|
+
return this._extractTextFromRichText(titleObj.text);
|
|
448
|
+
}
|
|
449
|
+
// Only consider the strRef cache resolved when it actually contains
|
|
450
|
+
// at least one point. Formula-bound titles are authored with
|
|
451
|
+
// `strRef: { formula, cache: { points: [] } }` (see
|
|
452
|
+
// `chart-builder.ts:makeTitle`), and without the explicit length
|
|
453
|
+
// check this getter returned `""` for every such title that hadn't
|
|
454
|
+
// yet gone through `fillChartCaches` — callers couldn't
|
|
455
|
+
// distinguish "title exists, not yet resolved" from an
|
|
456
|
+
// intentionally-empty title.
|
|
457
|
+
if (titleObj.strRef?.cache?.points && titleObj.strRef.cache.points.length > 0) {
|
|
458
|
+
return titleObj.strRef.cache.points.map(p => p.value).join("");
|
|
459
|
+
}
|
|
460
|
+
// Fall back to rawTx — extract text from <a:t> elements
|
|
461
|
+
if (titleObj.rawTx) {
|
|
462
|
+
return this._extractTextFromRawTx(titleObj.rawTx);
|
|
463
|
+
}
|
|
464
|
+
return undefined;
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Set the chart title.
|
|
468
|
+
*
|
|
469
|
+
* Accepts:
|
|
470
|
+
* - `undefined` → removes title (sets autoTitleDeleted).
|
|
471
|
+
* - `string` → sets title text. If the existing title had rich-text formatting,
|
|
472
|
+
* the formatting of the first run is preserved and only the text is replaced.
|
|
473
|
+
* - `ChartRichText` → replaces the title with fully-structured rich text.
|
|
474
|
+
* - `{ formula: string }` → sets the title to a worksheet formula reference.
|
|
475
|
+
*/
|
|
476
|
+
set title(value) {
|
|
477
|
+
const chart = this.chartModel?.chart ?? this.chartExModel?.chartSpace?.chart;
|
|
478
|
+
if (!chart) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
if (value === undefined) {
|
|
482
|
+
this._markDirty(true);
|
|
483
|
+
chart.title = undefined;
|
|
484
|
+
chart.autoTitleDeleted = true;
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
if (typeof value === "object" && "formula" in value && typeof value.formula === "string") {
|
|
488
|
+
this._markDirty();
|
|
489
|
+
chart.title = {
|
|
490
|
+
strRef: { formula: value.formula, cache: { points: [] } },
|
|
491
|
+
overlay: chart.title?.overlay ?? false
|
|
492
|
+
};
|
|
493
|
+
chart.autoTitleDeleted = false;
|
|
494
|
+
// Repopulate the title cache from the referenced cell(s) so
|
|
495
|
+
// preview callers (toSVG / toPNG) and headless converters can
|
|
496
|
+
// resolve the title text without waiting for a worksheet-side
|
|
497
|
+
// recalc. `fillChartCaches` no-ops for non-formula titles and
|
|
498
|
+
// already-populated caches, so calling it here is safe.
|
|
499
|
+
if (this.isChartEx) {
|
|
500
|
+
this._refreshChartExCaches();
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
this._refreshCaches();
|
|
504
|
+
}
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (typeof value === "object" && "paragraphs" in value) {
|
|
508
|
+
this._markDirty();
|
|
509
|
+
// Rich text — shallow-clone the paragraphs array so callers who
|
|
510
|
+
// reuse the same `ChartRichText` object across charts don't
|
|
511
|
+
// accidentally alias mutations. Runs remain shared by reference
|
|
512
|
+
// inside each paragraph — consumers generally treat them as
|
|
513
|
+
// immutable, and a deep clone here is cheap but hides the
|
|
514
|
+
// aliasing concern rather than documents it. Users who mutate
|
|
515
|
+
// a run after assignment should clone the object themselves.
|
|
516
|
+
chart.title = {
|
|
517
|
+
...(chart.title ?? {}),
|
|
518
|
+
strRef: undefined,
|
|
519
|
+
rawTx: undefined,
|
|
520
|
+
text: { ...value, paragraphs: [...value.paragraphs] },
|
|
521
|
+
overlay: chart.title?.overlay ?? false
|
|
522
|
+
};
|
|
523
|
+
chart.autoTitleDeleted = false;
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
// Plain string — try to preserve first-run formatting of existing title.
|
|
527
|
+
if (typeof value !== "string") {
|
|
528
|
+
// Reach here only when `value` is an object whose shape matches none of
|
|
529
|
+
// the branches above (e.g. `{ formula: 123 }`, `{ foo: 1 }`). Previously
|
|
530
|
+
// we silently returned, which quietly swallowed malformed input; throw
|
|
531
|
+
// instead so callers see the bug at the assignment site.
|
|
532
|
+
throw new errors_1.ChartOptionsError("Chart.title accepts string | ChartRichText | { formula: string } | undefined. " +
|
|
533
|
+
`Got: ${JSON.stringify(value)}`);
|
|
534
|
+
}
|
|
535
|
+
this._markDirty(true);
|
|
536
|
+
const existing = chart.title;
|
|
537
|
+
const preservedProps = this._extractFirstRunProperties(existing);
|
|
538
|
+
chart.title = {
|
|
539
|
+
...(existing ?? {}),
|
|
540
|
+
strRef: undefined,
|
|
541
|
+
rawTx: undefined,
|
|
542
|
+
text: {
|
|
543
|
+
paragraphs: [
|
|
544
|
+
{
|
|
545
|
+
runs: [{ text: value, properties: preservedProps }]
|
|
546
|
+
}
|
|
547
|
+
]
|
|
548
|
+
},
|
|
549
|
+
overlay: existing?.overlay ?? false
|
|
550
|
+
};
|
|
551
|
+
chart.autoTitleDeleted = false;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Set the chart title using structured rich text.
|
|
555
|
+
* Convenience method equivalent to `chart.title = richText`.
|
|
556
|
+
*/
|
|
557
|
+
setTitleRichText(richText) {
|
|
558
|
+
this.title = richText;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Get the structured rich text of the chart title.
|
|
562
|
+
* Returns undefined if the title is unset, formula-only, or captured as rawTx.
|
|
563
|
+
*/
|
|
564
|
+
get titleRichText() {
|
|
565
|
+
return this.chartModel?.chart?.title?.text ?? this.chartExModel?.chartSpace?.chart?.title?.text;
|
|
566
|
+
}
|
|
567
|
+
/** Get the chart type groups in the plot area */
|
|
568
|
+
get chartTypes() {
|
|
569
|
+
return this.chartModel?.chart?.plotArea?.chartTypes ?? [];
|
|
570
|
+
}
|
|
571
|
+
/** Get the chart axes */
|
|
572
|
+
get axes() {
|
|
573
|
+
return this.chartModel?.chart?.plotArea?.axes ?? [];
|
|
574
|
+
}
|
|
575
|
+
/** Get the chart legend */
|
|
576
|
+
get legend() {
|
|
577
|
+
return this.chartModel?.chart?.legend ?? this.chartExModel?.chartSpace?.chart?.legend;
|
|
578
|
+
}
|
|
579
|
+
/** Set the chart legend */
|
|
580
|
+
set legend(value) {
|
|
581
|
+
const chart = this.chartModel?.chart ?? this.chartExModel?.chartSpace?.chart;
|
|
582
|
+
if (chart) {
|
|
583
|
+
this._markDirty(true);
|
|
584
|
+
chart.legend = value;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Get the chart-level shape properties. Works for both classic charts
|
|
589
|
+
* (`c:chartSpace/c:spPr`) and ChartEx (`cx:chartSpace/cx:spPr` — the
|
|
590
|
+
* Chart2014 schema puts `spPr` on `chartSpace`, not on `chart`).
|
|
591
|
+
*/
|
|
592
|
+
get spPr() {
|
|
593
|
+
if (this.chartModel) {
|
|
594
|
+
return this.chartModel.spPr;
|
|
595
|
+
}
|
|
596
|
+
// ChartEx stores chart-frame shape properties on `CT_ChartSpace/spPr`.
|
|
597
|
+
// Legacy files that (incorrectly) placed `spPr` on `<cx:chart>`
|
|
598
|
+
// are migrated by the parser into `chartSpace.spPr` at load
|
|
599
|
+
// time — so this getter no longer needs a fallback path.
|
|
600
|
+
return this.chartExModel?.chartSpace?.spPr;
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Set the chart-level shape properties. Routes to either
|
|
604
|
+
* `ChartModel.spPr` (classic) or `ChartExModel.chartSpace.spPr`
|
|
605
|
+
* (ChartEx); previously the ChartEx branch was a silent no-op, and
|
|
606
|
+
* the fix before that mis-targeted `chart.spPr` — which is not a
|
|
607
|
+
* valid child of `CT_Chart` in the Chart2014 schema (chart-frame
|
|
608
|
+
* styling belongs to `CT_ChartSpace/spPr`).
|
|
609
|
+
*/
|
|
610
|
+
set spPr(value) {
|
|
611
|
+
const cm = this.chartModel;
|
|
612
|
+
if (cm) {
|
|
613
|
+
this._markDirty();
|
|
614
|
+
cm.spPr = value;
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
const chartSpace = this.chartExModel?.chartSpace;
|
|
618
|
+
if (chartSpace) {
|
|
619
|
+
this._markDirty();
|
|
620
|
+
chartSpace.spPr = value;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Get an axis by its ID.
|
|
625
|
+
*/
|
|
626
|
+
getAxis(axId) {
|
|
627
|
+
return this.axes.find(ax => ax.axId === axId);
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Get the category (X) axis, if any.
|
|
631
|
+
*/
|
|
632
|
+
get categoryAxis() {
|
|
633
|
+
return this.axes.find(ax => ax.axisType === "cat" || ax.axisType === "date");
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Get the value (Y) axis, if any.
|
|
637
|
+
*/
|
|
638
|
+
get valueAxis() {
|
|
639
|
+
return this.axes.find(ax => ax.axisType === "val");
|
|
640
|
+
}
|
|
641
|
+
/** Get the plot area for direct manipulation */
|
|
642
|
+
get plotArea() {
|
|
643
|
+
return this.chartModel?.chart?.plotArea;
|
|
644
|
+
}
|
|
645
|
+
mutate(mutator, options = {}) {
|
|
646
|
+
const model = this.chartModel;
|
|
647
|
+
if (!model) {
|
|
648
|
+
throw new errors_1.ChartOptionsError("Cannot mutate a classic chart model because this chart is ChartEx or missing.");
|
|
649
|
+
}
|
|
650
|
+
mutator(model);
|
|
651
|
+
this._markDirty(options.preferRawPatch ?? false, options.requireRawPatch ?? false);
|
|
652
|
+
return this;
|
|
653
|
+
}
|
|
654
|
+
mutateChartEx(mutator, options = {}) {
|
|
655
|
+
const model = this.chartExModel;
|
|
656
|
+
if (!model) {
|
|
657
|
+
throw new errors_1.ChartOptionsError("Cannot mutate a ChartEx model because this chart is classic or missing.");
|
|
658
|
+
}
|
|
659
|
+
mutator(model);
|
|
660
|
+
// Invalidate the model-level rawXml cache so subsequent calls to
|
|
661
|
+
// `renderChartEx(model)` (e.g. standalone preview, tests) honour the
|
|
662
|
+
// mutation instead of short-circuiting to the bytes captured at parse
|
|
663
|
+
// time. The xlsx writer path has its own change-detection (see
|
|
664
|
+
// `hasChartExEntryChanged` in xlsx.browser.ts) and does not depend on
|
|
665
|
+
// this flag, but direct consumers of `renderChartEx` do.
|
|
666
|
+
//
|
|
667
|
+
// `preferRawPatch` consumers explicitly opt in to surgical byte
|
|
668
|
+
// patching — they keep the rawXml so the patcher in xlsx.browser.ts
|
|
669
|
+
// can reuse it.
|
|
670
|
+
if (!options.preferRawPatch && !options.requireRawPatch) {
|
|
671
|
+
model.rawXml = undefined;
|
|
672
|
+
// Also clear title-level rawTx when the structured `text` was
|
|
673
|
+
// updated. Otherwise the writer's "structured path wins over
|
|
674
|
+
// raw" rule correctly routes the new text, but downstream
|
|
675
|
+
// snapshotters (change-detection / test helpers) still see the
|
|
676
|
+
// stale rawTx bytes and conclude the model hasn't been mutated.
|
|
677
|
+
// Clearing here unifies the invalidation model.
|
|
678
|
+
const title = model.chartSpace.chart.title;
|
|
679
|
+
if (title?.text && title.rawTx !== undefined) {
|
|
680
|
+
title.rawTx = undefined;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
this._markDirty(options.preferRawPatch ?? false, options.requireRawPatch ?? false);
|
|
684
|
+
return this;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Set the built-in chart style by index.
|
|
688
|
+
*
|
|
689
|
+
* Writes `<c:style val="N"/>` on the classic chart (`chartN.xml`).
|
|
690
|
+
* Valid values are 1–48, matching the legacy Excel 2007/2010 style
|
|
691
|
+
* catalogue and `xlsxwriter`'s `set_style(N)`. This is the lightweight
|
|
692
|
+
* option — it does **not** emit a `styleN.xml` / `colorsN.xml` sidecar;
|
|
693
|
+
* for modern Office-2013-era styling use {@link setChartStyle} instead.
|
|
694
|
+
*
|
|
695
|
+
* ChartEx charts do not honour this field; calling `setStyle` on one
|
|
696
|
+
* throws, which matches OOXML: `c:style` only exists in the classic
|
|
697
|
+
* `c:` namespace.
|
|
698
|
+
*
|
|
699
|
+
* @param style - Integer in the range 1–48.
|
|
700
|
+
* @throws {ChartOptionsError} when `style` is outside 1–48 or the
|
|
701
|
+
* chart is a ChartEx.
|
|
702
|
+
*/
|
|
703
|
+
setStyle(style) {
|
|
704
|
+
if (!Number.isInteger(style) || style < 1 || style > 48) {
|
|
705
|
+
throw new errors_1.ChartOptionsError(`Chart.setStyle: built-in style must be an integer in 1..48, received ${style}`);
|
|
706
|
+
}
|
|
707
|
+
const model = this.chartModel;
|
|
708
|
+
if (!model) {
|
|
709
|
+
throw new errors_1.ChartOptionsError("Chart.setStyle is only valid on classic charts; ChartEx does not honour `c:style`");
|
|
710
|
+
}
|
|
711
|
+
model.style = style;
|
|
712
|
+
this._markDirty();
|
|
713
|
+
return this;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* Alias for {@link setStyle} that matches the `xlsxwriter` terminology
|
|
717
|
+
* used by Python/Rust users migrating their chart code. Equivalent in
|
|
718
|
+
* every way — both write the same `<c:style val>` attribute.
|
|
719
|
+
*/
|
|
720
|
+
setBuiltInStyle(style) {
|
|
721
|
+
return this.setStyle(style);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Add a series to a chart type group.
|
|
725
|
+
*
|
|
726
|
+
* The series' `index` and `order` fields are rewritten to the next
|
|
727
|
+
* available slot in the target group so callers can safely push
|
|
728
|
+
* series that were built with a placeholder index (e.g. a reused
|
|
729
|
+
* result of `buildChartSeriesForType(..., 0)`). OOXML requires
|
|
730
|
+
* `c:ser/@idx` to be unique within the chart; leaving caller-provided
|
|
731
|
+
* values alone silently produces a chart with duplicate `<c:idx>`
|
|
732
|
+
* entries that Excel either rejects or collapses to a single series.
|
|
733
|
+
*
|
|
734
|
+
* @param series - The series object matching the expected series type for the chart.
|
|
735
|
+
* @param groupIndex - 0-based index of the chart type group (for combo charts). Defaults to 0.
|
|
736
|
+
*/
|
|
737
|
+
addSeries(series, groupIndex = 0) {
|
|
738
|
+
const ctg = this.chartTypes[groupIndex];
|
|
739
|
+
if (ctg) {
|
|
740
|
+
this._markDirty();
|
|
741
|
+
const nextIdx = this._nextSeriesIndex();
|
|
742
|
+
series.index = nextIdx;
|
|
743
|
+
series.order = nextIdx;
|
|
744
|
+
// `ctg.series` is a discriminated union keyed on `ctg.type` — TS can't
|
|
745
|
+
// verify that `series` matches the expected variant from a generic
|
|
746
|
+
// `SeriesBase`. Callers are documented as responsible for passing a
|
|
747
|
+
// matching shape; we widen through `unknown` to avoid `as any` while
|
|
748
|
+
// keeping a single signature. Runtime validation lives in
|
|
749
|
+
// `buildChartModel`, which is invoked when the chart is serialised.
|
|
750
|
+
ctg.series.push(series);
|
|
751
|
+
// Refresh caches so the first preview render (and any
|
|
752
|
+
// change-detection snapshot taken before the next save cycle)
|
|
753
|
+
// sees the actual data rather than the blank shell the caller
|
|
754
|
+
// probably built via `buildChartSeriesForType`. `updateSeries`
|
|
755
|
+
// and `addSeriesFromOptions` already do this; the lower-level
|
|
756
|
+
// `addSeries` path previously skipped the refresh, so a chart
|
|
757
|
+
// authored via direct `ctg.series.push`-style flows displayed
|
|
758
|
+
// empty until the next save / reload cycle.
|
|
759
|
+
this._refreshCaches();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Remove a series from a chart type group by index.
|
|
764
|
+
*
|
|
765
|
+
* @param index - 0-based index of the series within the group.
|
|
766
|
+
* @param groupIndex - 0-based index of the chart type group (for combo charts). Defaults to 0.
|
|
767
|
+
* @returns The removed series, or undefined if out of range.
|
|
768
|
+
*/
|
|
769
|
+
removeSeries(index, groupIndex = 0) {
|
|
770
|
+
const ctg = this.chartTypes[groupIndex];
|
|
771
|
+
if (!ctg || index < 0 || index >= ctg.series.length) {
|
|
772
|
+
return undefined;
|
|
773
|
+
}
|
|
774
|
+
this._markDirty();
|
|
775
|
+
return ctg.series.splice(index, 1)[0];
|
|
776
|
+
}
|
|
777
|
+
/**
|
|
778
|
+
* Get a series from a chart type group.
|
|
779
|
+
*
|
|
780
|
+
* @param index - 0-based index of the series within the group.
|
|
781
|
+
* @param groupIndex - 0-based index of the chart type group (for combo charts). Defaults to 0.
|
|
782
|
+
*/
|
|
783
|
+
getSeries(index, groupIndex = 0) {
|
|
784
|
+
const ctg = this.chartTypes[groupIndex];
|
|
785
|
+
if (!ctg) {
|
|
786
|
+
return undefined;
|
|
787
|
+
}
|
|
788
|
+
return ctg.series[index];
|
|
789
|
+
}
|
|
790
|
+
/** Update common fields on an existing classic chart series. */
|
|
791
|
+
updateSeries(index, options, groupIndex = 0) {
|
|
792
|
+
const series = this.getSeries(index, groupIndex);
|
|
793
|
+
if (!series) {
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
796
|
+
// Apply the patch first so a malformed option (e.g. an unknown
|
|
797
|
+
// enum on `lineDash`) throws *before* we flip the dirty flag. The
|
|
798
|
+
// previous ordering left the chart entry marked dirty on failure,
|
|
799
|
+
// which then forced a full rebuild on the next write even though
|
|
800
|
+
// no mutation had actually landed on the model.
|
|
801
|
+
(0, chart_builder_1.applyChartSeriesOptionsPatch)(series, options, this.chartTypes[groupIndex]?.type);
|
|
802
|
+
// Resolve any staged `series.spPr.fill.blip._pendingImage` that the
|
|
803
|
+
// patch placed on the series. The initial `addChart` path does
|
|
804
|
+
// this in the worksheet's `addChart` hook (same for `addChartsheet`
|
|
805
|
+
// / `replaceChartsheetChart`), but post-registration mutations via
|
|
806
|
+
// `updateSeries` had no equivalent pass — the `_pendingImage`
|
|
807
|
+
// payload sat on the model and the xlsx writer emitted
|
|
808
|
+
// `<a:blipFill>` without a matching rel, leaving Excel with a
|
|
809
|
+
// broken picture reference. Match the registration paths so
|
|
810
|
+
// pictureFill works uniformly for create and update.
|
|
811
|
+
if (options.pictureFill?.image !== undefined) {
|
|
812
|
+
this._resolveSeriesPictureFills();
|
|
813
|
+
}
|
|
814
|
+
// Refresh numeric / string caches when the patch introduced a new
|
|
815
|
+
// formula reference. `applyChartSeriesOptionsPatch` always replaces
|
|
816
|
+
// `target.val` / `target.cat` / `target.xVal` / `target.bubbleSize`
|
|
817
|
+
// with a fresh `makeNumRef` / `makeStrRef` whose `cache.points` is
|
|
818
|
+
// empty, so preview readers and headless converters see blank
|
|
819
|
+
// values until the next `fillChartCaches` pass. Calling it here
|
|
820
|
+
// keeps parity with the worksheet's initial `addChart` step.
|
|
821
|
+
if (options.values !== undefined ||
|
|
822
|
+
options.categories !== undefined ||
|
|
823
|
+
options.xValues !== undefined ||
|
|
824
|
+
options.bubbleSize !== undefined) {
|
|
825
|
+
this._refreshCaches();
|
|
826
|
+
}
|
|
827
|
+
this._markDirty(true);
|
|
828
|
+
return true;
|
|
829
|
+
}
|
|
830
|
+
/** Add a series from high-level options, matching the target chart type group. */
|
|
831
|
+
addSeriesFromOptions(options, groupIndex = 0) {
|
|
832
|
+
const ctg = this.chartTypes[groupIndex];
|
|
833
|
+
if (!ctg) {
|
|
834
|
+
return false;
|
|
835
|
+
}
|
|
836
|
+
const index = this._nextSeriesIndex();
|
|
837
|
+
// `buildChartSeriesForType` can throw for invalid options (e.g. a
|
|
838
|
+
// `pie` chart given `scatter`-only fields). Build first, mark
|
|
839
|
+
// dirty only after the push lands — otherwise a failing build
|
|
840
|
+
// leaves the entry marked dirty without any change to serialise.
|
|
841
|
+
//
|
|
842
|
+
// `buildChartSeriesForType` returns the exact variant matching `ctg.type`,
|
|
843
|
+
// but TS sees `SeriesBase`. Widen via `unknown` (instead of `as any`) so
|
|
844
|
+
// the tighter typing of the union is preserved at the push site.
|
|
845
|
+
const built = (0, chart_builder_1.buildChartSeriesForType)(ctg.type, options, index);
|
|
846
|
+
ctg.series.push(built);
|
|
847
|
+
// Same rationale as `updateSeries`: if the new series carries a
|
|
848
|
+
// pictureFill image, resolve the pending payload into an actual
|
|
849
|
+
// media entry + chart rel so the writer emits valid XML.
|
|
850
|
+
if (options.pictureFill?.image !== undefined) {
|
|
851
|
+
this._resolveSeriesPictureFills();
|
|
852
|
+
}
|
|
853
|
+
// Newly added series always carry empty caches on their val /
|
|
854
|
+
// cat / xVal references — refresh so the first preview render
|
|
855
|
+
// sees the actual data rather than a blank shell.
|
|
856
|
+
this._refreshCaches();
|
|
857
|
+
this._markDirty();
|
|
858
|
+
return true;
|
|
859
|
+
}
|
|
860
|
+
/** Update the value range for a series. */
|
|
861
|
+
setSeriesValues(index, values, groupIndex = 0) {
|
|
862
|
+
return this.updateSeries(index, { values }, groupIndex);
|
|
863
|
+
}
|
|
864
|
+
/** Update the category range for a series. */
|
|
865
|
+
setSeriesCategories(index, categories, groupIndex = 0) {
|
|
866
|
+
return this.updateSeries(index, { categories }, groupIndex);
|
|
867
|
+
}
|
|
868
|
+
/** Update the series display name or formula reference. */
|
|
869
|
+
setSeriesName(index, name, groupIndex = 0) {
|
|
870
|
+
return this.updateSeries(index, { name }, groupIndex);
|
|
871
|
+
}
|
|
872
|
+
/** Get the total number of series across all chart type groups. */
|
|
873
|
+
get totalSeriesCount() {
|
|
874
|
+
return this.chartTypes.reduce((sum, ctg) => sum + (ctg.series?.length ?? 0), 0);
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* Get the number of series in a specific chart type group.
|
|
878
|
+
*
|
|
879
|
+
* @param groupIndex - 0-based index of the chart type group (defaults to 0).
|
|
880
|
+
*/
|
|
881
|
+
getSeriesCount(groupIndex = 0) {
|
|
882
|
+
const ctg = this.chartTypes[groupIndex];
|
|
883
|
+
return ctg?.series?.length ?? 0;
|
|
884
|
+
}
|
|
885
|
+
/**
|
|
886
|
+
* @deprecated Use `getSeriesCount()` instead. Returns the count of series in the first chart type group.
|
|
887
|
+
*/
|
|
888
|
+
get seriesCount() {
|
|
889
|
+
return this.getSeriesCount(0);
|
|
890
|
+
}
|
|
891
|
+
// ===========================================================================
|
|
892
|
+
// Chart cloning and duplication
|
|
893
|
+
// ===========================================================================
|
|
894
|
+
/**
|
|
895
|
+
* Create a deep copy of this chart and add it to a target worksheet.
|
|
896
|
+
* The new chart receives a fresh chartNumber; the original is untouched.
|
|
897
|
+
*
|
|
898
|
+
* @param targetWs - Worksheet to receive the clone. Defaults to this chart's worksheet.
|
|
899
|
+
* @param range - Anchor range for the clone. Defaults to the original range.
|
|
900
|
+
* @returns The new chartNumber in the target workbook.
|
|
901
|
+
*/
|
|
902
|
+
copyTo(targetWs, range) {
|
|
903
|
+
const sourceModel = this.chartModel;
|
|
904
|
+
const sourceChartExModel = this.chartExModel;
|
|
905
|
+
if (!sourceModel && !sourceChartExModel) {
|
|
906
|
+
throw new errors_1.ChartOptionsError("Cannot copy chart because no chart model is available.");
|
|
907
|
+
}
|
|
908
|
+
const targetRange = range ?? this._cloneRange();
|
|
909
|
+
// `Worksheet` declares `_registerChart` / `_registerChartEx` as
|
|
910
|
+
// `@internal private`, which TypeScript hides from external callers.
|
|
911
|
+
// Chart lives in the same compilation unit as Worksheet but the class
|
|
912
|
+
// boundary still enforces `private`, so we access the hooks through a
|
|
913
|
+
// narrowly-typed structural interface. Keep this cast co-located with
|
|
914
|
+
// the call sites so any rename of the Worksheet internals surfaces here.
|
|
915
|
+
const registrar = targetWs;
|
|
916
|
+
if (sourceChartExModel) {
|
|
917
|
+
const newChartExNumber = registrar._registerChartEx(deepClone(sourceChartExModel), targetRange);
|
|
918
|
+
// Copy chartEx-specific sidecars (the `_chartExRels` bag of
|
|
919
|
+
// authored relationship entries). Previously the copy dropped
|
|
920
|
+
// every rel, so a chartEx with `cx14:` extension references or
|
|
921
|
+
// embedded media ended up pointing at undefined rel ids on the
|
|
922
|
+
// clone.
|
|
923
|
+
this.worksheet.workbook.copyChartExSidecars?.(this.chartExNumber, newChartExNumber, targetWs.workbook);
|
|
924
|
+
return newChartExNumber;
|
|
925
|
+
}
|
|
926
|
+
const clonedModel = deepClone(sourceModel);
|
|
927
|
+
const chartNumber = registrar._registerChart(clonedModel, targetRange);
|
|
928
|
+
this.worksheet.workbook.copyChartSidecars?.(this.chartNumber, chartNumber, targetWs.workbook);
|
|
929
|
+
// `_registerChart` creates a minimal entry (model only). Carry
|
|
930
|
+
// the per-entry `userShapesXml` bytes across so annotation
|
|
931
|
+
// overlays (callouts, arrows, text boxes the user drew on top of
|
|
932
|
+
// the chart) survive the clone. Without this the duplicate loses
|
|
933
|
+
// every overlay — the drawing part is referenced via a per-entry
|
|
934
|
+
// rel that `copyChartSidecars` already copied, but the backing
|
|
935
|
+
// bytes live on the entry itself and were being dropped.
|
|
936
|
+
//
|
|
937
|
+
// Also carry over `entry.rels`. The workbook-level
|
|
938
|
+
// `copyChartSidecars` hook copies `_chartRels[n]` (style / colors /
|
|
939
|
+
// on-disk image rels), but rels generated programmatically by
|
|
940
|
+
// `resolvePendingChartImages` (for a `series.spPr.fill.blip`
|
|
941
|
+
// picture fill) and the user-shapes placeholder rel pushed by
|
|
942
|
+
// `setUserShapesXml` live on `entry.rels`. Without this copy,
|
|
943
|
+
// the clone's `spPr.fill.blip.relationshipId` / `model.userShapesRelId`
|
|
944
|
+
// referenced in the deep-cloned model point at rel IDs that
|
|
945
|
+
// only exist on the SOURCE entry — the target writes out a
|
|
946
|
+
// chart whose XML uses `r:embed="rId{N}"` but whose .rels has
|
|
947
|
+
// no matching entry, so Excel renders the picture-fill series
|
|
948
|
+
// as a broken / blank fill.
|
|
949
|
+
const srcEntry = this.worksheet.workbook.getChartEntry(this.chartNumber);
|
|
950
|
+
const dstEntry = targetWs.workbook.getChartEntry(chartNumber);
|
|
951
|
+
if (srcEntry && dstEntry) {
|
|
952
|
+
if (srcEntry.userShapesXml) {
|
|
953
|
+
dstEntry.userShapesXml = srcEntry.userShapesXml.slice();
|
|
954
|
+
}
|
|
955
|
+
if (Array.isArray(srcEntry.rels) && srcEntry.rels.length > 0) {
|
|
956
|
+
// Shallow-clone each rel so later mutations on the source
|
|
957
|
+
// don't leak into the clone. The writer only reads `Id`,
|
|
958
|
+
// `Type`, `Target`, and `TargetMode` off these entries, so
|
|
959
|
+
// a spread is sufficient.
|
|
960
|
+
dstEntry.rels = srcEntry.rels.map(rel => ({ ...rel }));
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
return chartNumber;
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Create a deep copy of this chart in the same worksheet.
|
|
967
|
+
* @param range - Anchor for the clone (defaults to shifting right of original).
|
|
968
|
+
*/
|
|
969
|
+
clone(range) {
|
|
970
|
+
return this.copyTo(this.worksheet, range ?? this._cloneRange());
|
|
971
|
+
}
|
|
972
|
+
_cloneRange() {
|
|
973
|
+
// Two-cell anchor: shift the clone right by the original's width.
|
|
974
|
+
if (this.range.br) {
|
|
975
|
+
const tl = this.range.tl.model;
|
|
976
|
+
const br = this.range.br.model;
|
|
977
|
+
const width = br.nativeCol - tl.nativeCol;
|
|
978
|
+
return {
|
|
979
|
+
tl: { col: br.nativeCol + 1, row: tl.nativeRow },
|
|
980
|
+
br: { col: br.nativeCol + 1 + width, row: br.nativeRow }
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
// Absolute anchor: shift horizontally by the extent so the clone
|
|
984
|
+
// sits alongside the original. Preserve `editAs: "absolute"` so
|
|
985
|
+
// the writer emits `<xdr:absoluteAnchor>` — the previous fallback
|
|
986
|
+
// degraded every non-two-cell anchor into a twoCell placed
|
|
987
|
+
// on top of the original, both changing the anchor kind and
|
|
988
|
+
// overlapping the source chart 100%.
|
|
989
|
+
if (this.range.pos && this.range.ext) {
|
|
990
|
+
return {
|
|
991
|
+
pos: {
|
|
992
|
+
x: this.range.pos.x + this.range.ext.cx,
|
|
993
|
+
y: this.range.pos.y
|
|
994
|
+
},
|
|
995
|
+
ext: { cx: this.range.ext.cx, cy: this.range.ext.cy },
|
|
996
|
+
editAs: "absolute"
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
// One-cell anchor: shift the `tl` column right by enough columns
|
|
1000
|
+
// to clear the original's extent. Converting the EMU width back
|
|
1001
|
+
// to a column count is approximate (Excel column widths vary per
|
|
1002
|
+
// sheet), so estimate at `DEFAULT_CHART_WIDTH_COLS` for
|
|
1003
|
+
// consistency with the two-cell fallback and keep `editAs:
|
|
1004
|
+
// "oneCell"` so the writer emits `<xdr:oneCellAnchor>`.
|
|
1005
|
+
if (this.range.ext) {
|
|
1006
|
+
return {
|
|
1007
|
+
tl: {
|
|
1008
|
+
col: this.range.tl.nativeCol + DEFAULT_CHART_WIDTH_COLS,
|
|
1009
|
+
row: this.range.tl.nativeRow
|
|
1010
|
+
},
|
|
1011
|
+
ext: { cx: this.range.ext.cx, cy: this.range.ext.cy },
|
|
1012
|
+
editAs: "oneCell"
|
|
1013
|
+
};
|
|
1014
|
+
}
|
|
1015
|
+
// No extent at all (should not happen in practice — `parseRange`
|
|
1016
|
+
// always populates at least `ext` for oneCell/absolute and `br` for
|
|
1017
|
+
// twoCell). Fall back to a two-cell shifted right by the default
|
|
1018
|
+
// chart extent.
|
|
1019
|
+
return {
|
|
1020
|
+
tl: {
|
|
1021
|
+
col: this.range.tl.nativeCol + DEFAULT_CHART_WIDTH_COLS,
|
|
1022
|
+
row: this.range.tl.nativeRow
|
|
1023
|
+
},
|
|
1024
|
+
br: {
|
|
1025
|
+
col: this.range.tl.nativeCol + 2 * DEFAULT_CHART_WIDTH_COLS,
|
|
1026
|
+
row: this.range.tl.nativeRow + DEFAULT_CHART_HEIGHT_ROWS
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
// ===========================================================================
|
|
1031
|
+
// Private helpers
|
|
1032
|
+
// ===========================================================================
|
|
1033
|
+
/**
|
|
1034
|
+
* Compute the next available series index across all chart type groups.
|
|
1035
|
+
* OOXML `c:ser/@idx` must be unique within the entire chart. Scans for
|
|
1036
|
+
* the maximum authored index (not the series count) so post-removeSeries
|
|
1037
|
+
* state and non-contiguous authored indices still produce a unique slot.
|
|
1038
|
+
*/
|
|
1039
|
+
_nextSeriesIndex() {
|
|
1040
|
+
let maxIdx = -1;
|
|
1041
|
+
for (const g of this.chartTypes) {
|
|
1042
|
+
for (const s of g.series) {
|
|
1043
|
+
const idx = typeof s.index === "number" ? s.index : -1;
|
|
1044
|
+
if (Number.isFinite(idx) && idx > maxIdx) {
|
|
1045
|
+
maxIdx = idx;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
return maxIdx + 1;
|
|
1050
|
+
}
|
|
1051
|
+
_markDirty(preferRawPatch = false, requireRawPatch = false) {
|
|
1052
|
+
if (this.chartNumber > 0) {
|
|
1053
|
+
const entry = this.worksheet.workbook.getChartEntry(this.chartNumber);
|
|
1054
|
+
if (entry) {
|
|
1055
|
+
entry.dirty = true;
|
|
1056
|
+
// Once any mutation drops `preferRawPatch`, a full rebuild is
|
|
1057
|
+
// required — a subsequent minor mutation must not re-enable
|
|
1058
|
+
// patching. Conversely, if the entry was already marked for
|
|
1059
|
+
// full rebuild, a minor mutation should not downgrade it back
|
|
1060
|
+
// to patch mode.
|
|
1061
|
+
if (!preferRawPatch) {
|
|
1062
|
+
entry.preferRawPatch = false;
|
|
1063
|
+
}
|
|
1064
|
+
else if (entry.preferRawPatch === undefined) {
|
|
1065
|
+
entry.preferRawPatch = true;
|
|
1066
|
+
}
|
|
1067
|
+
if (requireRawPatch) {
|
|
1068
|
+
entry.requireRawPatch = true;
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
if (this.chartExNumber > 0) {
|
|
1073
|
+
const entry = this.worksheet.workbook.getChartExStructuredEntry(this.chartExNumber);
|
|
1074
|
+
if (entry) {
|
|
1075
|
+
entry.dirty = true;
|
|
1076
|
+
if (!preferRawPatch) {
|
|
1077
|
+
entry.preferRawPatch = false;
|
|
1078
|
+
}
|
|
1079
|
+
else if (entry.preferRawPatch === undefined) {
|
|
1080
|
+
entry.preferRawPatch = true;
|
|
1081
|
+
}
|
|
1082
|
+
if (requireRawPatch) {
|
|
1083
|
+
entry.requireRawPatch = true;
|
|
1084
|
+
}
|
|
1085
|
+
// Invalidate the ChartExModel.rawXml cache on every structural
|
|
1086
|
+
// mutation (title / legend / spPr setters, addSeries etc.) —
|
|
1087
|
+
// direct consumers of `renderChartEx(model)` (standalone
|
|
1088
|
+
// preview, tests) short-circuit to `model.rawXml` when present
|
|
1089
|
+
// and would otherwise silently drop the mutation. The
|
|
1090
|
+
// `preferRawPatch` opt-in keeps the bytes so the xlsx writer
|
|
1091
|
+
// can still do surgical byte patching on them.
|
|
1092
|
+
if (!preferRawPatch && !requireRawPatch && entry.model) {
|
|
1093
|
+
entry.model.rawXml = undefined;
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
/**
|
|
1099
|
+
* Resolve any `_pendingImage` payloads this chart's series carry into
|
|
1100
|
+
* workbook media entries + chart relationships. Used by
|
|
1101
|
+
* `updateSeries` / `addSeriesFromOptions` when a caller adds a
|
|
1102
|
+
* picture fill *after* registration — the initial `addChart` /
|
|
1103
|
+
* `addChartsheet` path already calls `resolvePendingChartImages`,
|
|
1104
|
+
* but post-registration mutations previously left `_pendingImage`
|
|
1105
|
+
* un-registered and the writer emitted `<a:blipFill>` pointing at a
|
|
1106
|
+
* missing rel.
|
|
1107
|
+
*
|
|
1108
|
+
* Uses the same resolver helper as the initial path, so rel id
|
|
1109
|
+
* allocation, collision checks against `_chartRels`, and media
|
|
1110
|
+
* naming stay centralised.
|
|
1111
|
+
*/
|
|
1112
|
+
_resolveSeriesPictureFills() {
|
|
1113
|
+
if (this.chartNumber <= 0) {
|
|
1114
|
+
return;
|
|
1115
|
+
}
|
|
1116
|
+
const entry = this.worksheet.workbook.getChartEntry(this.chartNumber);
|
|
1117
|
+
if (!entry) {
|
|
1118
|
+
return;
|
|
1119
|
+
}
|
|
1120
|
+
try {
|
|
1121
|
+
(0, chart_images_1.resolvePendingChartImages)(entry, this.worksheet.workbook, this.chartNumber);
|
|
1122
|
+
}
|
|
1123
|
+
catch {
|
|
1124
|
+
// Best-effort: a malformed image payload should not take down
|
|
1125
|
+
// the surrounding `updateSeries` / `addSeriesFromOptions` call.
|
|
1126
|
+
// The series keeps its `pictureOptions`; only the blip-fill
|
|
1127
|
+
// registration is skipped.
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
/**
|
|
1131
|
+
* Rebuild numeric / string caches on this chart's model from the
|
|
1132
|
+
* current worksheet data. Callers mutating formula references after
|
|
1133
|
+
* registration (`updateSeries`, `addSeriesFromOptions`, title setter
|
|
1134
|
+
* with `{ formula }`) invoke this so preview renders and the
|
|
1135
|
+
* snapshot-based change detector see populated points instead of
|
|
1136
|
+
* the empty `{ points: [] }` shell the builders install.
|
|
1137
|
+
*
|
|
1138
|
+
* `fillChartCaches` short-circuits on already-populated caches, so
|
|
1139
|
+
* repeated calls across a burst of mutations are effectively O(N)
|
|
1140
|
+
* in the number of *new* references.
|
|
1141
|
+
*/
|
|
1142
|
+
_refreshCaches() {
|
|
1143
|
+
const model = this.chartModel;
|
|
1144
|
+
if (!model) {
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1147
|
+
try {
|
|
1148
|
+
// Pass `this.worksheet` as the resolver context so sheet-scoped
|
|
1149
|
+
// defined names on this chart's owning sheet outrank workbook-
|
|
1150
|
+
// scoped names of the same bare name (matches Excel resolution
|
|
1151
|
+
// order and the `addChart` path in `Worksheet`).
|
|
1152
|
+
(0, cache_populator_1.fillChartCaches)(model, this.worksheet.workbook, this.worksheet);
|
|
1153
|
+
}
|
|
1154
|
+
catch {
|
|
1155
|
+
// Cache population is best-effort; a bad reference in one
|
|
1156
|
+
// series should not prevent the mutation from landing. The
|
|
1157
|
+
// writer still emits the new formula, and a later workbook-
|
|
1158
|
+
// wide pass can populate the cache when called explicitly.
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Populate ChartEx data caches (`strDim.levels` / `numDim.levels`) from
|
|
1163
|
+
* the workbook's worksheet data so that preview renders see actual
|
|
1164
|
+
* values instead of empty arrays.
|
|
1165
|
+
*
|
|
1166
|
+
* The builder marks hierarchical dimensions with `_skipCache` to
|
|
1167
|
+
* prevent the XML writer from emitting flat cache levels (which
|
|
1168
|
+
* confuses Excel's hierarchy renderer). However, the in-memory
|
|
1169
|
+
* renderer still needs the data. We temporarily clear the flag,
|
|
1170
|
+
* fill, then restore it so the writer behaviour is unaffected.
|
|
1171
|
+
*/
|
|
1172
|
+
_refreshChartExCaches() {
|
|
1173
|
+
const model = this.chartExModel;
|
|
1174
|
+
if (!model) {
|
|
1175
|
+
return;
|
|
1176
|
+
}
|
|
1177
|
+
// Temporarily lift _skipCache so fillChartExCaches actually populates
|
|
1178
|
+
const skipped = [];
|
|
1179
|
+
for (const entry of model.chartSpace.chartData.data) {
|
|
1180
|
+
const str = entry.strDim;
|
|
1181
|
+
if (str?.["_skipCache"]) {
|
|
1182
|
+
skipped.push({ dim: str, field: "_skipCache" });
|
|
1183
|
+
delete str["_skipCache"];
|
|
1184
|
+
}
|
|
1185
|
+
const num = entry.numDim;
|
|
1186
|
+
if (num?.["_skipCache"]) {
|
|
1187
|
+
skipped.push({ dim: num, field: "_skipCache" });
|
|
1188
|
+
delete num["_skipCache"];
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
try {
|
|
1192
|
+
(0, cache_populator_1.fillChartExCaches)(model, this.worksheet.workbook, this.worksheet);
|
|
1193
|
+
}
|
|
1194
|
+
catch {
|
|
1195
|
+
// Best-effort — same rationale as _refreshCaches.
|
|
1196
|
+
}
|
|
1197
|
+
finally {
|
|
1198
|
+
// Restore _skipCache so the writer still suppresses cache output,
|
|
1199
|
+
// even if fillChartExCaches threw an error.
|
|
1200
|
+
for (const { dim } of skipped) {
|
|
1201
|
+
dim["_skipCache"] = true;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
_extractTextFromRichText(rt) {
|
|
1206
|
+
return rt.paragraphs.map(p => (p.runs ?? []).map(r => r.text).join("")).join("\n");
|
|
1207
|
+
}
|
|
1208
|
+
_extractTextFromRawTx(rawTx) {
|
|
1209
|
+
// Extract all <a:t>…</a:t> text content from raw c:tx XML.
|
|
1210
|
+
// Also check <c:v>…</c:v> for strRef-based titles.
|
|
1211
|
+
//
|
|
1212
|
+
// Uses `matchAll` rather than `RegExp.exec` + shared `lastIndex` so
|
|
1213
|
+
// concurrent calls (extracting multiple titles in parallel promise
|
|
1214
|
+
// chains) cannot interleave each other's iterator state.
|
|
1215
|
+
const parts = [];
|
|
1216
|
+
for (const match of rawTx.matchAll(RAW_TX_AT_RE)) {
|
|
1217
|
+
parts.push(this._decodeXmlEntities(match[1]));
|
|
1218
|
+
}
|
|
1219
|
+
if (parts.length > 0) {
|
|
1220
|
+
return parts.join("");
|
|
1221
|
+
}
|
|
1222
|
+
for (const match of rawTx.matchAll(RAW_TX_CV_RE)) {
|
|
1223
|
+
parts.push(this._decodeXmlEntities(match[1]));
|
|
1224
|
+
}
|
|
1225
|
+
return parts.length > 0 ? parts.join("") : undefined;
|
|
1226
|
+
}
|
|
1227
|
+
_decodeXmlEntities(text) {
|
|
1228
|
+
// Single-pass decoder so sequences like `&lt;` (the XML-encoded
|
|
1229
|
+
// form of a literal `<`) decode to `<` — NOT to `<`. Chaining
|
|
1230
|
+
// `.replace(/&/g,"&").replace(/</g,"<")` produced the double-
|
|
1231
|
+
// decode by accident: the first replace turned `&lt;` into
|
|
1232
|
+
// `<`, which the second step then decoded as `<`. A title
|
|
1233
|
+
// authored as literal `<tag>` would round-trip as `<tag>`,
|
|
1234
|
+
// silently corrupting the user's text.
|
|
1235
|
+
return text.replace(/&(?:([A-Za-z]+)|#x([0-9A-Fa-f]+)|#(\d+));/g, (match, name, hex, dec) => {
|
|
1236
|
+
if (name !== undefined) {
|
|
1237
|
+
switch (name) {
|
|
1238
|
+
case "amp":
|
|
1239
|
+
return "&";
|
|
1240
|
+
case "lt":
|
|
1241
|
+
return "<";
|
|
1242
|
+
case "gt":
|
|
1243
|
+
return ">";
|
|
1244
|
+
case "quot":
|
|
1245
|
+
return '"';
|
|
1246
|
+
case "apos":
|
|
1247
|
+
return "'";
|
|
1248
|
+
default:
|
|
1249
|
+
return match;
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
if (hex !== undefined) {
|
|
1253
|
+
const code = parseInt(hex, 16);
|
|
1254
|
+
return Number.isFinite(code) ? String.fromCodePoint(code) : match;
|
|
1255
|
+
}
|
|
1256
|
+
if (dec !== undefined) {
|
|
1257
|
+
const code = parseInt(dec, 10);
|
|
1258
|
+
return Number.isFinite(code) ? String.fromCodePoint(code) : match;
|
|
1259
|
+
}
|
|
1260
|
+
return match;
|
|
1261
|
+
});
|
|
1262
|
+
}
|
|
1263
|
+
/**
|
|
1264
|
+
* Extract the run properties of the first text run in an existing title,
|
|
1265
|
+
* if any. Used to preserve formatting when replacing plain-string title
|
|
1266
|
+
* text.
|
|
1267
|
+
*
|
|
1268
|
+
* We prefer the structured path (`title.text.paragraphs[0].runs[0]`) and
|
|
1269
|
+
* fall back to parsing the first `<a:rPr>...</a:rPr>` block out of
|
|
1270
|
+
* `rawTx`. The fallback used to only read *attributes* off the opening
|
|
1271
|
+
* tag (size / bold / italic / underline / strike / lang), which meant
|
|
1272
|
+
* the `<a:solidFill>` colour child and `<a:latin>` / `<a:cs>` typefaces
|
|
1273
|
+
* were silently stripped when a plain-string title replaced a
|
|
1274
|
+
* rich-text title. Now we delegate to `parseTxPr` (the same helper the
|
|
1275
|
+
* chart-space xform uses for the full txPr tree) so every supported
|
|
1276
|
+
* rPr field round-trips faithfully.
|
|
1277
|
+
*/
|
|
1278
|
+
_extractFirstRunProperties(title) {
|
|
1279
|
+
if (!title) {
|
|
1280
|
+
return undefined;
|
|
1281
|
+
}
|
|
1282
|
+
// Structured path — cheapest and most complete.
|
|
1283
|
+
const firstRun = title.text?.paragraphs?.[0]?.runs?.[0];
|
|
1284
|
+
if (firstRun?.properties) {
|
|
1285
|
+
return { ...firstRun.properties };
|
|
1286
|
+
}
|
|
1287
|
+
// rawTx path — isolate the first `<a:rPr>…</a:rPr>` fragment (including
|
|
1288
|
+
// the self-closing variant) and delegate parsing to `parseTxPr`, which
|
|
1289
|
+
// understands colour, font family, east-asian / complex-script
|
|
1290
|
+
// typefaces and the run-level number format.
|
|
1291
|
+
if (title.rawTx) {
|
|
1292
|
+
const selfClosing = /<a:rPr\b[^>]*\/>/.exec(title.rawTx);
|
|
1293
|
+
const openClose = /<a:rPr\b[^>]*>[\s\S]*?<\/a:rPr>/.exec(title.rawTx);
|
|
1294
|
+
const rPrFragment = openClose && (!selfClosing || openClose.index <= selfClosing.index)
|
|
1295
|
+
? openClose[0]
|
|
1296
|
+
: selfClosing?.[0];
|
|
1297
|
+
if (rPrFragment) {
|
|
1298
|
+
// `parseTxPr` looks for `<a:defRPr>` and `<a:rPr>` fragments inside
|
|
1299
|
+
// the passed-in raw XML; wrapping in a minimal `<c:txPr>` so it
|
|
1300
|
+
// finds exactly our fragment.
|
|
1301
|
+
const synthetic = `<c:txPr>${rPrFragment}</c:txPr>`;
|
|
1302
|
+
const parsed = (0, shape_properties_1.parseTxPr)({ _rawXml: synthetic });
|
|
1303
|
+
// `parsed` still contains `_rawXml`; strip it so the run properties
|
|
1304
|
+
// don't drag along a synthetic wrapper. Callers (setter for
|
|
1305
|
+
// `title`) only use the structured fields.
|
|
1306
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1307
|
+
const { _rawXml, ...structured } = parsed;
|
|
1308
|
+
return structured;
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
return undefined;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
exports.Chart = Chart;
|
|
1315
|
+
/**
|
|
1316
|
+
* Deep-clone a chart model. Uses `structuredClone` which is always available
|
|
1317
|
+
* in our supported environments (Node 22+, all modern browsers) and handles
|
|
1318
|
+
* the `Uint8Array` captured on {@link ChartExModel.rawXml} correctly — the
|
|
1319
|
+
* older `JSON.parse(JSON.stringify(...))` fallback stripped the typed-array
|
|
1320
|
+
* prototype and corrupted round-trip data.
|
|
1321
|
+
*/
|
|
1322
|
+
function deepClone(obj) {
|
|
1323
|
+
return structuredClone(obj);
|
|
1324
|
+
}
|