@cj-tech-master/excelts 5.0.6 → 5.1.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 +1 -1
- package/dist/browser/index.d.ts +1 -1
- package/dist/browser/modules/archive/unzip/stream.base.js +19 -19
- package/dist/browser/modules/archive/unzip/stream.browser.js +3 -3
- package/dist/browser/modules/csv/csv-core.js +6 -3
- package/dist/browser/modules/csv/csv.browser.js +2 -2
- package/dist/browser/modules/csv/csv.js +1 -1
- package/dist/browser/modules/excel/anchor.js +4 -4
- package/dist/browser/modules/excel/cell.js +5 -5
- package/dist/browser/modules/excel/column.js +4 -4
- package/dist/browser/modules/excel/defined-names.js +1 -1
- package/dist/browser/modules/excel/form-control.js +1 -1
- package/dist/browser/modules/excel/pivot-table.d.ts +168 -17
- package/dist/browser/modules/excel/pivot-table.js +278 -70
- package/dist/browser/modules/excel/row.js +4 -4
- package/dist/browser/modules/excel/stream/workbook-reader.browser.js +4 -4
- package/dist/browser/modules/excel/stream/workbook-writer.browser.js +4 -4
- package/dist/browser/modules/excel/stream/worksheet-reader.js +1 -1
- package/dist/browser/modules/excel/stream/worksheet-writer.js +4 -4
- package/dist/browser/modules/excel/table.js +2 -2
- package/dist/browser/modules/excel/types.d.ts +0 -4
- package/dist/browser/modules/excel/utils/cell-format.js +3 -3
- package/dist/browser/modules/excel/utils/shared-formula.js +1 -1
- package/dist/browser/modules/excel/utils/stream-buf.js +2 -2
- package/dist/browser/modules/excel/utils/string-buf.js +1 -1
- package/dist/browser/modules/excel/workbook.d.ts +0 -2
- package/dist/browser/modules/excel/workbook.js +4 -5
- package/dist/browser/modules/excel/worksheet.js +9 -9
- package/dist/browser/modules/excel/xlsx/xform/base-xform.d.ts +5 -5
- package/dist/browser/modules/excel/xlsx/xform/base-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
- package/dist/browser/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
- package/dist/browser/modules/excel/xlsx/xform/comment/comment-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/comment/comments-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-position-xform.d.ts +3 -4
- package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-notes-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/composite-xform.d.ts +1 -1
- package/dist/browser/modules/excel/xlsx/xform/core/app-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
- package/dist/browser/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/cell-position-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/ext-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
- package/dist/browser/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/list-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/list-xform.js +3 -3
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field-xform.d.ts +5 -15
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +134 -52
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.d.ts +14 -15
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/cache-field.js +244 -70
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +13 -29
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +213 -37
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +7 -34
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +143 -41
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +101 -27
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.d.ts +78 -0
- package/dist/browser/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +149 -0
- package/dist/browser/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
- package/dist/browser/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
- package/dist/browser/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
- package/dist/browser/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
- package/dist/browser/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
- package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
- package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
- package/dist/browser/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
- package/dist/browser/modules/excel/xlsx/xform/style/color-xform.js +1 -1
- package/dist/browser/modules/excel/xlsx/xform/style/style-xform.js +5 -5
- package/dist/browser/modules/excel/xlsx/xform/table/auto-filter-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/table/custom-filter-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/table/filter-column-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/table/filter-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/table/table-column-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/table/table-style-info-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xform/table/table-xform.d.ts +1 -2
- package/dist/browser/modules/excel/xlsx/xlsx.browser.d.ts +5 -2
- package/dist/browser/modules/excel/xlsx/xlsx.browser.js +88 -54
- package/dist/browser/utils/env.d.ts +0 -5
- package/dist/browser/utils/env.js +0 -7
- package/dist/browser/utils/utils.base.d.ts +8 -13
- package/dist/browser/utils/utils.base.js +40 -47
- package/dist/browser/utils/utils.browser.d.ts +1 -1
- package/dist/browser/utils/utils.browser.js +1 -1
- package/dist/browser/utils/utils.d.ts +1 -1
- package/dist/browser/utils/utils.js +1 -1
- package/dist/cjs/modules/archive/unzip/stream.base.js +19 -19
- package/dist/cjs/modules/archive/unzip/stream.browser.js +3 -3
- package/dist/cjs/modules/csv/csv-core.js +6 -3
- package/dist/cjs/modules/csv/csv.browser.js +2 -2
- package/dist/cjs/modules/csv/csv.js +1 -1
- package/dist/cjs/modules/excel/anchor.js +4 -4
- package/dist/cjs/modules/excel/cell.js +5 -5
- package/dist/cjs/modules/excel/column.js +4 -4
- package/dist/cjs/modules/excel/defined-names.js +1 -1
- package/dist/cjs/modules/excel/form-control.js +1 -1
- package/dist/cjs/modules/excel/pivot-table.js +280 -70
- package/dist/cjs/modules/excel/row.js +4 -4
- package/dist/cjs/modules/excel/stream/workbook-reader.browser.js +4 -4
- package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +4 -4
- package/dist/cjs/modules/excel/stream/worksheet-reader.js +1 -1
- package/dist/cjs/modules/excel/stream/worksheet-writer.js +4 -4
- package/dist/cjs/modules/excel/table.js +2 -2
- package/dist/cjs/modules/excel/utils/cell-format.js +3 -3
- package/dist/cjs/modules/excel/utils/shared-formula.js +1 -1
- package/dist/cjs/modules/excel/utils/stream-buf.js +2 -2
- package/dist/cjs/modules/excel/utils/string-buf.js +1 -1
- package/dist/cjs/modules/excel/workbook.js +4 -5
- package/dist/cjs/modules/excel/worksheet.js +9 -9
- package/dist/cjs/modules/excel/xlsx/xform/base-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
- package/dist/cjs/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
- package/dist/cjs/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/core/app-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
- package/dist/cjs/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
- package/dist/cjs/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/list-xform.js +3 -3
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +133 -51
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/cache-field.js +245 -71
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +212 -36
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +142 -40
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
- package/dist/cjs/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +153 -0
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
- package/dist/cjs/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
- package/dist/cjs/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
- package/dist/cjs/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
- package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
- package/dist/cjs/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
- package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
- package/dist/cjs/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
- package/dist/cjs/modules/excel/xlsx/xform/style/color-xform.js +1 -1
- package/dist/cjs/modules/excel/xlsx/xform/style/style-xform.js +5 -5
- package/dist/cjs/modules/excel/xlsx/xlsx.browser.js +88 -54
- package/dist/cjs/utils/env.js +0 -8
- package/dist/cjs/utils/utils.base.js +41 -54
- package/dist/cjs/utils/utils.browser.js +2 -7
- package/dist/cjs/utils/utils.js +2 -7
- package/dist/esm/modules/archive/unzip/stream.base.js +19 -19
- package/dist/esm/modules/archive/unzip/stream.browser.js +3 -3
- package/dist/esm/modules/csv/csv-core.js +6 -3
- package/dist/esm/modules/csv/csv.browser.js +2 -2
- package/dist/esm/modules/csv/csv.js +1 -1
- package/dist/esm/modules/excel/anchor.js +4 -4
- package/dist/esm/modules/excel/cell.js +5 -5
- package/dist/esm/modules/excel/column.js +4 -4
- package/dist/esm/modules/excel/defined-names.js +1 -1
- package/dist/esm/modules/excel/form-control.js +1 -1
- package/dist/esm/modules/excel/pivot-table.js +278 -70
- package/dist/esm/modules/excel/row.js +4 -4
- package/dist/esm/modules/excel/stream/workbook-reader.browser.js +4 -4
- package/dist/esm/modules/excel/stream/workbook-writer.browser.js +4 -4
- package/dist/esm/modules/excel/stream/worksheet-reader.js +1 -1
- package/dist/esm/modules/excel/stream/worksheet-writer.js +4 -4
- package/dist/esm/modules/excel/table.js +2 -2
- package/dist/esm/modules/excel/utils/cell-format.js +3 -3
- package/dist/esm/modules/excel/utils/shared-formula.js +1 -1
- package/dist/esm/modules/excel/utils/stream-buf.js +2 -2
- package/dist/esm/modules/excel/utils/string-buf.js +1 -1
- package/dist/esm/modules/excel/workbook.js +4 -5
- package/dist/esm/modules/excel/worksheet.js +9 -9
- package/dist/esm/modules/excel/xlsx/xform/base-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/book/defined-name-xform.js +2 -2
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-view-xform.js +4 -4
- package/dist/esm/modules/excel/xlsx/xform/book/workbook-xform.js +16 -4
- package/dist/esm/modules/excel/xlsx/xform/comment/style/vml-position-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/comment/style/vml-protection-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/comment/vml-shape-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/comment/vml-textbox-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/core/app-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/core/content-types-xform.js +24 -11
- package/dist/esm/modules/excel/xlsx/xform/drawing/base-cell-anchor-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/ext-xform.js +2 -2
- package/dist/esm/modules/excel/xlsx/xform/drawing/one-cell-anchor-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/drawing/two-cell-anchor-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/list-xform.js +3 -3
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field-xform.js +134 -52
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/cache-field.js +244 -70
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +213 -37
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.js +143 -41
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.js +793 -408
- package/dist/esm/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.js +149 -0
- package/dist/esm/modules/excel/xlsx/xform/sheet/cell-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/cf/cf-rule-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/cf/conditional-formattings-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/sheet/col-xform.js +3 -3
- package/dist/esm/modules/excel/xlsx/xform/sheet/data-validations-xform.js +3 -3
- package/dist/esm/modules/excel/xlsx/xform/sheet/header-footer-xform.js +6 -6
- package/dist/esm/modules/excel/xlsx/xform/sheet/page-setup-xform.js +11 -11
- package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-format-properties-xform.js +3 -3
- package/dist/esm/modules/excel/xlsx/xform/sheet/sheet-view-xform.js +10 -10
- package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +12 -12
- package/dist/esm/modules/excel/xlsx/xform/strings/phonetic-text-xform.js +2 -2
- package/dist/esm/modules/excel/xlsx/xform/style/color-xform.js +1 -1
- package/dist/esm/modules/excel/xlsx/xform/style/style-xform.js +5 -5
- package/dist/esm/modules/excel/xlsx/xlsx.browser.js +88 -54
- package/dist/esm/utils/env.js +0 -7
- package/dist/esm/utils/utils.base.js +40 -47
- package/dist/esm/utils/utils.browser.js +1 -1
- package/dist/esm/utils/utils.js +1 -1
- package/dist/iife/excelts.iife.js +1553 -718
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +36 -105
- package/dist/types/index.browser.d.ts +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/modules/excel/pivot-table.d.ts +168 -17
- package/dist/types/modules/excel/types.d.ts +0 -4
- package/dist/types/modules/excel/workbook.d.ts +0 -2
- package/dist/types/modules/excel/xlsx/xform/base-xform.d.ts +5 -5
- package/dist/types/modules/excel/xlsx/xform/comment/comment-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/comment/comments-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/comment/style/vml-position-xform.d.ts +3 -4
- package/dist/types/modules/excel/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/comment/vml-notes-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/composite-xform.d.ts +1 -1
- package/dist/types/modules/excel/xlsx/xform/drawing/blip-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/drawing/cell-position-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/drawing/ctrl-prop-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/drawing/drawing-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/drawing/ext-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/drawing/vml-drawing-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/list-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/pivot-table/cache-field-xform.d.ts +5 -15
- package/dist/types/modules/excel/xlsx/xform/pivot-table/cache-field.d.ts +14 -15
- package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +13 -29
- package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +7 -34
- package/dist/types/modules/excel/xlsx/xform/pivot-table/pivot-table-xform.d.ts +101 -27
- package/dist/types/modules/excel/xlsx/xform/pivot-table/raw-xml-collector.d.ts +78 -0
- package/dist/types/modules/excel/xlsx/xform/sheet/row-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/auto-filter-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/custom-filter-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/filter-column-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/filter-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/table-column-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/table-style-info-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xform/table/table-xform.d.ts +1 -2
- package/dist/types/modules/excel/xlsx/xlsx.browser.d.ts +5 -2
- package/dist/types/utils/env.d.ts +0 -5
- package/dist/types/utils/utils.base.d.ts +8 -13
- package/dist/types/utils/utils.browser.d.ts +1 -1
- package/dist/types/utils/utils.d.ts +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,39 @@
|
|
|
1
1
|
import { range, toSortedArray } from "../../utils/utils.browser.js";
|
|
2
2
|
import { colCache } from "./utils/col-cache.js";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Wrapper for OOXML error values in sharedItems (e.g. `<e v="REF!"/>`).
|
|
5
|
+
* Distinguishes error strings from regular strings so they roundtrip as `<e>` not `<s>`.
|
|
6
|
+
*/
|
|
7
|
+
export class PivotErrorValue {
|
|
8
|
+
constructor(code) {
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
/** Returns the display form with '#' prefix, e.g. "#REF!" */
|
|
12
|
+
toString() {
|
|
13
|
+
return `#${this.code}`;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Map from PivotTableSubtotal to its Excel display name prefix */
|
|
17
|
+
export const METRIC_DISPLAY_NAMES = {
|
|
18
|
+
sum: "Sum",
|
|
19
|
+
count: "Count",
|
|
20
|
+
average: "Average",
|
|
21
|
+
max: "Max",
|
|
22
|
+
min: "Min",
|
|
23
|
+
product: "Product",
|
|
24
|
+
countNums: "Count Numbers",
|
|
25
|
+
stdDev: "StdDev",
|
|
26
|
+
stdDevP: "StdDevP",
|
|
27
|
+
var: "Var",
|
|
28
|
+
varP: "VarP"
|
|
29
|
+
};
|
|
30
|
+
/** Set of all valid PivotTableSubtotal values (for runtime validation) */
|
|
31
|
+
export const VALID_SUBTOTALS = new Set(Object.keys(METRIC_DISPLAY_NAMES));
|
|
32
|
+
/**
|
|
33
|
+
* Data rows start at index 2 in ExcelJS sparse arrays:
|
|
34
|
+
* index 0 = empty (ExcelJS convention), index 1 = header row.
|
|
35
|
+
*/
|
|
36
|
+
const DATA_START_INDEX = 2;
|
|
4
37
|
/**
|
|
5
38
|
* Creates a PivotTableSource adapter from a Table object.
|
|
6
39
|
* This allows Tables to be used as pivot table data sources with the same interface as Worksheets.
|
|
@@ -29,6 +62,9 @@ function createTableSourceAdapter(table) {
|
|
|
29
62
|
const dataRows = tableModel.rows.map(row => [undefined, ...row]); // sparse array starting at index 1
|
|
30
63
|
// Calculate the range reference for the table
|
|
31
64
|
const tl = tableModel.tl;
|
|
65
|
+
if (!tl) {
|
|
66
|
+
throw new Error(`Table "${tableModel.name}" is missing top-left cell address (tl)`);
|
|
67
|
+
}
|
|
32
68
|
const startRow = tl.row;
|
|
33
69
|
const startCol = tl.col;
|
|
34
70
|
const endRow = startRow + tableModel.rows.length; // header row + data rows
|
|
@@ -37,13 +73,15 @@ function createTableSourceAdapter(table) {
|
|
|
37
73
|
// Use the worksheet name (not table name) for pivotCacheDefinition's worksheetSource
|
|
38
74
|
// The sheet attribute in worksheetSource must reference the actual worksheet name
|
|
39
75
|
const worksheetName = table.worksheet.name;
|
|
76
|
+
const tableName = tableModel.name;
|
|
40
77
|
return {
|
|
41
78
|
name: worksheetName,
|
|
79
|
+
tableName,
|
|
42
80
|
getRow(rowNumber) {
|
|
43
81
|
if (rowNumber === 1) {
|
|
44
82
|
return { values: headerRow };
|
|
45
83
|
}
|
|
46
|
-
const dataIndex = rowNumber -
|
|
84
|
+
const dataIndex = rowNumber - DATA_START_INDEX; // rowNumber 2 maps to index 0
|
|
47
85
|
if (dataIndex >= 0 && dataIndex < dataRows.length) {
|
|
48
86
|
return { values: dataRows[dataIndex] };
|
|
49
87
|
}
|
|
@@ -74,66 +112,87 @@ function createTableSourceAdapter(table) {
|
|
|
74
112
|
dimensions: { shortRange }
|
|
75
113
|
};
|
|
76
114
|
}
|
|
115
|
+
/** Base cache ID starts at 10 (Excel convention), each subsequent table increments */
|
|
116
|
+
const BASE_CACHE_ID = 10;
|
|
77
117
|
/**
|
|
78
118
|
* Resolves the data source from the model, supporting both sourceSheet and sourceTable.
|
|
119
|
+
* Validates that exactly one source is provided.
|
|
79
120
|
*/
|
|
80
121
|
function resolveSource(model) {
|
|
122
|
+
if (model.sourceSheet && model.sourceTable) {
|
|
123
|
+
throw new Error("Cannot specify both sourceSheet and sourceTable. Choose one.");
|
|
124
|
+
}
|
|
81
125
|
if (model.sourceTable) {
|
|
82
126
|
return createTableSourceAdapter(model.sourceTable);
|
|
83
127
|
}
|
|
84
|
-
|
|
128
|
+
if (!model.sourceSheet) {
|
|
129
|
+
throw new Error("Either sourceSheet or sourceTable must be provided.");
|
|
130
|
+
}
|
|
85
131
|
return model.sourceSheet;
|
|
86
132
|
}
|
|
133
|
+
/** Resolve a value entry to its column name string */
|
|
134
|
+
function resolveValueName(v) {
|
|
135
|
+
return typeof v === "string" ? v : v.name;
|
|
136
|
+
}
|
|
137
|
+
/** Resolve a value entry's metric (or undefined if inheriting table-wide default) */
|
|
138
|
+
function resolveValueMetric(v) {
|
|
139
|
+
return typeof v === "string" ? undefined : v.metric;
|
|
140
|
+
}
|
|
87
141
|
function makePivotTable(worksheet, model) {
|
|
88
|
-
//
|
|
89
|
-
// {
|
|
90
|
-
// // Source of data (either sourceSheet OR sourceTable):
|
|
91
|
-
// sourceSheet: worksheet1, // Use entire sheet range
|
|
92
|
-
// // OR
|
|
93
|
-
// sourceTable: table, // Use table data
|
|
94
|
-
//
|
|
95
|
-
// // Pivot table fields: values indicate field names;
|
|
96
|
-
// // they come from the first row in `worksheet1` or table column names.
|
|
97
|
-
// rows: ['A', 'B'],
|
|
98
|
-
// columns: ['C'],
|
|
99
|
-
// values: ['E'], // only 1 item possible for now
|
|
100
|
-
// metric: 'sum', // only 'sum' possible for now
|
|
101
|
-
// }
|
|
102
|
-
// Validate source exists before trying to resolve it
|
|
103
|
-
if (!model.sourceSheet && !model.sourceTable) {
|
|
104
|
-
throw new Error("Either sourceSheet or sourceTable must be provided.");
|
|
105
|
-
}
|
|
106
|
-
if (model.sourceSheet && model.sourceTable) {
|
|
107
|
-
throw new Error("Cannot specify both sourceSheet and sourceTable. Choose one.");
|
|
108
|
-
}
|
|
109
|
-
// Resolve source first to avoid creating adapter multiple times
|
|
142
|
+
// Resolve source (validates exactly one source is provided)
|
|
110
143
|
const source = resolveSource(model);
|
|
111
|
-
validate(
|
|
112
|
-
const { rows
|
|
144
|
+
validate(model, source);
|
|
145
|
+
const { rows } = model;
|
|
113
146
|
const columns = model.columns ?? [];
|
|
114
|
-
const
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
147
|
+
const pages = model.pages ?? [];
|
|
148
|
+
const valueNames = model.values.map(resolveValueName);
|
|
149
|
+
const defaultMetric = model.metric ?? "sum";
|
|
150
|
+
const valueMetrics = model.values.map(v => resolveValueMetric(v) ?? defaultMetric);
|
|
151
|
+
const cacheFields = makeCacheFields(source, [...rows, ...columns, ...pages], valueNames);
|
|
152
|
+
const nameToIndex = {};
|
|
153
|
+
for (let i = 0; i < cacheFields.length; i++) {
|
|
154
|
+
nameToIndex[cacheFields[i].name] = i;
|
|
155
|
+
}
|
|
156
|
+
const resolveIndex = (fieldName, role) => {
|
|
157
|
+
const idx = nameToIndex[fieldName];
|
|
158
|
+
if (idx === undefined) {
|
|
159
|
+
throw new Error(`${role} field "${fieldName}" not found in cache fields`);
|
|
160
|
+
}
|
|
161
|
+
return idx;
|
|
162
|
+
};
|
|
163
|
+
const rowIndices = rows.map(row => resolveIndex(row, "Row"));
|
|
164
|
+
const columnIndices = columns.map(column => resolveIndex(column, "Column"));
|
|
165
|
+
const valueIndices = valueNames.map(value => resolveIndex(value, "Value"));
|
|
166
|
+
const pageIndices = pages.map(page => resolveIndex(page, "Page"));
|
|
167
|
+
// R9-B1: Calculate tableNumber as max(existing)+1 to avoid collision with loaded
|
|
168
|
+
// pivot tables that may have non-contiguous numbering (e.g. [1, 2, 5]).
|
|
169
|
+
// Using length+1 would collide when adding multiple new tables.
|
|
170
|
+
const existingTableNumbers = worksheet.workbook.pivotTables
|
|
171
|
+
.map(pt => pt.tableNumber)
|
|
172
|
+
.filter(n => Number.isFinite(n));
|
|
173
|
+
const tableNumber = existingTableNumbers.length > 0
|
|
174
|
+
? existingTableNumbers.reduce((a, b) => (a > b ? a : b), -Infinity) + 1
|
|
175
|
+
: 1;
|
|
176
|
+
// Dynamic cacheId: avoid collision with existing (loaded) pivot tables.
|
|
177
|
+
// Find the max cacheId already in use and start from max+1.
|
|
178
|
+
const existingCacheIds = worksheet.workbook.pivotTables
|
|
179
|
+
.map(pt => parseInt(pt.cacheId, 10))
|
|
180
|
+
.filter(id => Number.isFinite(id));
|
|
181
|
+
// R8-O3: Use reduce instead of Math.max(...spread) to avoid stack overflow with many pivot tables
|
|
182
|
+
const nextCacheId = existingCacheIds.length > 0
|
|
183
|
+
? existingCacheIds.reduce((a, b) => (a > b ? a : b), -Infinity) + 1
|
|
184
|
+
: BASE_CACHE_ID + tableNumber - 1;
|
|
126
185
|
// form pivot table object
|
|
127
186
|
return {
|
|
128
187
|
source,
|
|
129
188
|
rows: rowIndices,
|
|
130
189
|
columns: columnIndices,
|
|
131
190
|
values: valueIndices,
|
|
132
|
-
|
|
191
|
+
pages: pageIndices,
|
|
192
|
+
metric: defaultMetric,
|
|
193
|
+
valueMetrics,
|
|
133
194
|
cacheFields,
|
|
134
|
-
|
|
135
|
-
// Used in <pivotTableDefinition> and xl/workbook.xml
|
|
136
|
-
cacheId: String(BASE_CACHE_ID + tableNumber - 1),
|
|
195
|
+
cacheId: String(nextCacheId),
|
|
137
196
|
// Control whether pivot table style overrides worksheet column widths
|
|
138
197
|
// '0' = preserve worksheet column widths (useful for custom sizing)
|
|
139
198
|
// '1' = apply pivot table style width/height (default Excel behavior)
|
|
@@ -142,77 +201,224 @@ function makePivotTable(worksheet, model) {
|
|
|
142
201
|
tableNumber
|
|
143
202
|
};
|
|
144
203
|
}
|
|
145
|
-
function validate(
|
|
146
|
-
if (model.metric && model.metric !== "sum" && model.metric !== "count") {
|
|
147
|
-
throw new Error('Only the "sum" and "count" metrics are supported at this time.');
|
|
148
|
-
}
|
|
204
|
+
function validate(model, source) {
|
|
149
205
|
const columns = model.columns ?? [];
|
|
206
|
+
const pages = model.pages ?? [];
|
|
207
|
+
const valueNames = model.values.map(resolveValueName);
|
|
150
208
|
// Get header names from source (already resolved)
|
|
151
209
|
const headerNames = source.getRow(1).values.slice(1);
|
|
152
|
-
//
|
|
153
|
-
|
|
154
|
-
for (
|
|
210
|
+
// Validate no empty header names (null, undefined, empty-string, or whitespace-only).
|
|
211
|
+
// Note: numeric 0 and boolean false are valid headers (they coerce to "0"/"false").
|
|
212
|
+
for (let i = 0; i < headerNames.length; i++) {
|
|
213
|
+
const h = headerNames[i];
|
|
214
|
+
if (h === null || h === undefined || h === "" || (typeof h === "string" && h.trim() === "")) {
|
|
215
|
+
throw new Error(`Empty or missing header name at column ${i + 1} in ${source.name}. Pivot tables require all columns to have non-empty headers.`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// Validate no duplicate header names
|
|
219
|
+
const headerDupCheck = new Set();
|
|
220
|
+
for (const h of headerNames) {
|
|
221
|
+
const name = String(h);
|
|
222
|
+
if (headerDupCheck.has(name)) {
|
|
223
|
+
throw new Error(`Duplicate header name "${name}" found in ${source.name}. Pivot tables require unique column names.`);
|
|
224
|
+
}
|
|
225
|
+
headerDupCheck.add(name);
|
|
226
|
+
}
|
|
227
|
+
// Use Set for O(1) lookup — coerce to String for consistent comparison with user-supplied names
|
|
228
|
+
const headerNameSet = new Set(headerNames.map(String));
|
|
229
|
+
const validateFieldExists = (name) => {
|
|
155
230
|
if (!headerNameSet.has(name)) {
|
|
156
231
|
throw new Error(`The header name "${name}" was not found in ${source.name}.`);
|
|
157
232
|
}
|
|
233
|
+
};
|
|
234
|
+
for (const name of model.rows) {
|
|
235
|
+
validateFieldExists(name);
|
|
236
|
+
}
|
|
237
|
+
for (const name of columns) {
|
|
238
|
+
validateFieldExists(name);
|
|
239
|
+
}
|
|
240
|
+
for (const name of valueNames) {
|
|
241
|
+
validateFieldExists(name);
|
|
242
|
+
}
|
|
243
|
+
for (const name of pages) {
|
|
244
|
+
validateFieldExists(name);
|
|
245
|
+
}
|
|
246
|
+
// Validate no duplicate field names across axis areas (rows, columns, pages).
|
|
247
|
+
// A field can only belong to one axis area. Values can overlap with axis areas (dataField="1").
|
|
248
|
+
const fieldToAxis = new Map();
|
|
249
|
+
const axisAreas = [
|
|
250
|
+
{ name: "rows", fields: model.rows },
|
|
251
|
+
{ name: "columns", fields: columns },
|
|
252
|
+
{ name: "pages", fields: pages }
|
|
253
|
+
];
|
|
254
|
+
for (const area of axisAreas) {
|
|
255
|
+
for (const field of area.fields) {
|
|
256
|
+
const existing = fieldToAxis.get(field);
|
|
257
|
+
if (existing === area.name) {
|
|
258
|
+
throw new Error(`Duplicate field "${field}" in ${area.name}. Each field can only appear once per axis area.`);
|
|
259
|
+
}
|
|
260
|
+
else if (existing) {
|
|
261
|
+
throw new Error(`Field "${field}" cannot appear in both ${existing} and ${area.name}. Each field can only be assigned to one axis area.`);
|
|
262
|
+
}
|
|
263
|
+
fieldToAxis.set(field, area.name);
|
|
264
|
+
}
|
|
158
265
|
}
|
|
159
266
|
if (!model.rows.length) {
|
|
160
267
|
throw new Error("No pivot table rows specified.");
|
|
161
268
|
}
|
|
162
269
|
// Allow empty columns - Excel will use "Values" as column field
|
|
163
|
-
// But can't have multiple values with columns specified
|
|
164
270
|
if (model.values.length < 1) {
|
|
165
271
|
throw new Error("Must have at least one value.");
|
|
166
272
|
}
|
|
167
|
-
|
|
168
|
-
|
|
273
|
+
// Validate metric values at runtime (guards against `as any` bypasses)
|
|
274
|
+
if (model.metric !== undefined && !VALID_SUBTOTALS.has(model.metric)) {
|
|
275
|
+
throw new Error(`Invalid metric "${model.metric}". Must be one of: ${[...VALID_SUBTOTALS].join(", ")}.`);
|
|
169
276
|
}
|
|
277
|
+
for (const v of model.values) {
|
|
278
|
+
const perMetric = resolveValueMetric(v);
|
|
279
|
+
if (perMetric !== undefined && !VALID_SUBTOTALS.has(perMetric)) {
|
|
280
|
+
throw new Error(`Invalid metric "${perMetric}" on value field "${resolveValueName(v)}". Must be one of: ${[...VALID_SUBTOTALS].join(", ")}.`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
// Validate no duplicate value field names
|
|
284
|
+
const valueDupCheck = new Set();
|
|
285
|
+
for (const name of valueNames) {
|
|
286
|
+
if (valueDupCheck.has(name)) {
|
|
287
|
+
throw new Error(`Duplicate value field "${name}". Each value field name must be unique.`);
|
|
288
|
+
}
|
|
289
|
+
valueDupCheck.add(name);
|
|
290
|
+
}
|
|
291
|
+
// Multiple values with columns is supported — the synthetic "Values" pseudo-field
|
|
292
|
+
// (field x="-2") is appended to colFields so Excel positions the data field labels
|
|
293
|
+
// correctly on the column axis.
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* R8-B2: Unwrap complex cell value types to a primitive suitable for pivot table shared items.
|
|
297
|
+
* - CellErrorValue ({error:"#REF!"}) → PivotErrorValue
|
|
298
|
+
* - CellRichTextValue ({richText:[...]}) → concatenated plain text
|
|
299
|
+
* - CellFormulaValue / CellArrayFormulaValue / CellSharedFormulaValue → result value (recursive)
|
|
300
|
+
* - CellHyperlinkValue ({text,hyperlink}) → text string
|
|
301
|
+
* - CellCheckboxValue ({checkbox:bool}) → boolean
|
|
302
|
+
* - Other objects → String(v)
|
|
303
|
+
*/
|
|
304
|
+
function unwrapCellValue(v) {
|
|
305
|
+
if (v === null || v === undefined) {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
if (typeof v !== "object") {
|
|
309
|
+
// Already a primitive (string, number, boolean)
|
|
310
|
+
return v;
|
|
311
|
+
}
|
|
312
|
+
if (v instanceof Date) {
|
|
313
|
+
return v;
|
|
314
|
+
}
|
|
315
|
+
if (v instanceof PivotErrorValue) {
|
|
316
|
+
return v;
|
|
317
|
+
}
|
|
318
|
+
const obj = v;
|
|
319
|
+
// CellErrorValue: { error: "#REF!" } → PivotErrorValue with code "REF!" (strip leading #)
|
|
320
|
+
if (typeof obj.error === "string") {
|
|
321
|
+
const errorStr = obj.error;
|
|
322
|
+
return new PivotErrorValue(errorStr.startsWith("#") ? errorStr.slice(1) : errorStr);
|
|
323
|
+
}
|
|
324
|
+
// CellFormulaValue / CellArrayFormulaValue / CellSharedFormulaValue: { formula/sharedFormula, result }
|
|
325
|
+
if ("formula" in obj || "sharedFormula" in obj) {
|
|
326
|
+
const result = obj.result;
|
|
327
|
+
if (result === undefined || result === null) {
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
// result can be number | string | boolean | Date | CellErrorValue — recurse
|
|
331
|
+
return unwrapCellValue(result);
|
|
332
|
+
}
|
|
333
|
+
// CellRichTextValue: { richText: [{text:"..."}, ...] }
|
|
334
|
+
if (Array.isArray(obj.richText)) {
|
|
335
|
+
return obj.richText.map(rt => rt.text ?? "").join("");
|
|
336
|
+
}
|
|
337
|
+
// CellHyperlinkValue: { text, hyperlink }
|
|
338
|
+
if (typeof obj.text === "string" && typeof obj.hyperlink === "string") {
|
|
339
|
+
return obj.text;
|
|
340
|
+
}
|
|
341
|
+
// CellCheckboxValue: { checkbox: boolean }
|
|
342
|
+
if (typeof obj.checkbox === "boolean") {
|
|
343
|
+
return obj.checkbox;
|
|
344
|
+
}
|
|
345
|
+
// Unknown object — fallback to string
|
|
346
|
+
return String(v);
|
|
170
347
|
}
|
|
171
348
|
function makeCacheFields(source, fieldNamesWithSharedItems, valueFieldNames) {
|
|
172
349
|
// Cache fields are used in pivot tables to reference source data.
|
|
173
350
|
// Fields in fieldNamesWithSharedItems get their unique values extracted as sharedItems.
|
|
174
351
|
// Fields in valueFieldNames (but not in fieldNamesWithSharedItems) get min/max calculated.
|
|
175
|
-
// Other fields are unused and get
|
|
352
|
+
// Other fields are unused and get null sharedItems.
|
|
176
353
|
const names = source.getRow(1).values;
|
|
177
354
|
// Use Set for O(1) lookup instead of object
|
|
178
355
|
const sharedItemsFields = new Set(fieldNamesWithSharedItems);
|
|
179
356
|
const valueFields = new Set(valueFieldNames);
|
|
180
357
|
const aggregate = (columnIndex) => {
|
|
181
358
|
const columnValues = source.getColumn(columnIndex).values;
|
|
182
|
-
// Build unique values set directly, skipping header (index 0,1)
|
|
359
|
+
// Build unique values set directly, skipping header (index 0,1).
|
|
360
|
+
// null/undefined are tracked separately (collapsed to a single null sentinel)
|
|
361
|
+
// because Set treats each null as the same key but undefined as a separate key,
|
|
362
|
+
// and we need null in sharedItems so renderCellNew can find it via indexOf.
|
|
183
363
|
const uniqueValues = new Set();
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
364
|
+
// R8-B12: PivotErrorValue uses reference equality in Set, so track error strings
|
|
365
|
+
// separately to avoid duplicates (e.g., two PivotErrorValue("#REF!") instances).
|
|
366
|
+
const seenErrors = new Map();
|
|
367
|
+
let hasNull = false;
|
|
368
|
+
for (let i = DATA_START_INDEX; i < columnValues.length; i++) {
|
|
369
|
+
// R8-B2: Unwrap complex cell values (formula results, rich text, errors, etc.)
|
|
370
|
+
const v = unwrapCellValue(columnValues[i]);
|
|
371
|
+
if (v === null || (typeof v === "number" && isNaN(v))) {
|
|
372
|
+
hasNull = true;
|
|
373
|
+
}
|
|
374
|
+
else if (v instanceof PivotErrorValue) {
|
|
375
|
+
// R8-B12: Deduplicate PivotErrorValue by error string
|
|
376
|
+
if (!seenErrors.has(v.code)) {
|
|
377
|
+
seenErrors.set(v.code, v);
|
|
378
|
+
uniqueValues.add(v);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
187
382
|
uniqueValues.add(v);
|
|
188
383
|
}
|
|
189
384
|
}
|
|
190
|
-
|
|
385
|
+
const sorted = toSortedArray(uniqueValues);
|
|
386
|
+
// Append null at the end (OOXML convention: <m/> items go last in sharedItems)
|
|
387
|
+
if (hasNull) {
|
|
388
|
+
sorted.push(null);
|
|
389
|
+
}
|
|
390
|
+
return sorted;
|
|
191
391
|
};
|
|
192
|
-
// Calculate min/max for numeric fields
|
|
392
|
+
// Calculate min/max and integer status for numeric fields
|
|
193
393
|
const getMinMax = (columnIndex) => {
|
|
194
394
|
const columnValues = source.getColumn(columnIndex).values;
|
|
195
395
|
let min = Infinity;
|
|
196
396
|
let max = -Infinity;
|
|
197
397
|
let hasNumeric = false;
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
398
|
+
let allInteger = true;
|
|
399
|
+
for (let i = DATA_START_INDEX; i < columnValues.length; i++) {
|
|
400
|
+
// R8-B10: Unwrap formula/complex cell values to extract numeric results
|
|
401
|
+
const unwrapped = unwrapCellValue(columnValues[i]);
|
|
402
|
+
if (typeof unwrapped === "number" && !isNaN(unwrapped)) {
|
|
201
403
|
hasNumeric = true;
|
|
202
|
-
if (
|
|
203
|
-
min =
|
|
404
|
+
if (unwrapped < min) {
|
|
405
|
+
min = unwrapped;
|
|
406
|
+
}
|
|
407
|
+
if (unwrapped > max) {
|
|
408
|
+
max = unwrapped;
|
|
204
409
|
}
|
|
205
|
-
if (
|
|
206
|
-
|
|
410
|
+
if (!Number.isInteger(unwrapped)) {
|
|
411
|
+
allInteger = false;
|
|
207
412
|
}
|
|
208
413
|
}
|
|
209
414
|
}
|
|
210
|
-
return hasNumeric ? { minValue: min, maxValue: max } : null;
|
|
415
|
+
return hasNumeric ? { minValue: min, maxValue: max, allInteger } : null;
|
|
211
416
|
};
|
|
212
417
|
// Build result array
|
|
213
418
|
const result = [];
|
|
214
419
|
for (const columnIndex of range(1, names.length)) {
|
|
215
|
-
const
|
|
420
|
+
const rawName = names[columnIndex];
|
|
421
|
+
const name = String(rawName);
|
|
216
422
|
if (sharedItemsFields.has(name)) {
|
|
217
423
|
// Field used for rows/columns - extract unique values as sharedItems
|
|
218
424
|
result.push({ name, sharedItems: aggregate(columnIndex) });
|
|
@@ -223,8 +429,10 @@ function makeCacheFields(source, fieldNamesWithSharedItems, valueFieldNames) {
|
|
|
223
429
|
result.push({
|
|
224
430
|
name,
|
|
225
431
|
sharedItems: null,
|
|
432
|
+
containsNumber: minMax ? "1" : undefined,
|
|
226
433
|
minValue: minMax?.minValue,
|
|
227
|
-
maxValue: minMax?.maxValue
|
|
434
|
+
maxValue: minMax?.maxValue,
|
|
435
|
+
containsInteger: minMax?.allInteger ? "1" : undefined
|
|
228
436
|
});
|
|
229
437
|
}
|
|
230
438
|
else {
|
|
@@ -156,8 +156,8 @@ class Row {
|
|
|
156
156
|
// Page Breaks
|
|
157
157
|
addPageBreak(lft, rght) {
|
|
158
158
|
const ws = this._worksheet;
|
|
159
|
-
const left = Math.max(0, (lft
|
|
160
|
-
const right = Math.max(0, (rght
|
|
159
|
+
const left = Math.max(0, (lft ?? 0) - 1) || 0;
|
|
160
|
+
const right = Math.max(0, (rght ?? 0) - 1) || 16838;
|
|
161
161
|
const pb = {
|
|
162
162
|
id: this._number,
|
|
163
163
|
max: right,
|
|
@@ -351,7 +351,7 @@ class Row {
|
|
|
351
351
|
this._hidden = value;
|
|
352
352
|
}
|
|
353
353
|
get outlineLevel() {
|
|
354
|
-
return this._outlineLevel
|
|
354
|
+
return this._outlineLevel ?? 0;
|
|
355
355
|
}
|
|
356
356
|
set outlineLevel(value) {
|
|
357
357
|
this._outlineLevel = value;
|
|
@@ -435,7 +435,7 @@ class Row {
|
|
|
435
435
|
delete this.height;
|
|
436
436
|
}
|
|
437
437
|
this.hidden = value.hidden;
|
|
438
|
-
this.outlineLevel = value.outlineLevel
|
|
438
|
+
this.outlineLevel = value.outlineLevel ?? 0;
|
|
439
439
|
this.dyDescent = value.dyDescent;
|
|
440
440
|
this.style = (value.style && JSON.parse(JSON.stringify(value.style))) || {};
|
|
441
441
|
}
|
|
@@ -169,7 +169,7 @@ export class WorkbookReaderBase extends EventEmitter {
|
|
|
169
169
|
this.workbookRels = await xform.parseStream(iterateStream(entry));
|
|
170
170
|
// Build fast lookup for worksheet relationship ids.
|
|
171
171
|
this._workbookRelIdByTarget = Object.create(null);
|
|
172
|
-
for (const rel of this.workbookRels
|
|
172
|
+
for (const rel of this.workbookRels ?? []) {
|
|
173
173
|
if (rel?.Target && rel?.Id) {
|
|
174
174
|
this._workbookRelIdByTarget[rel.Target] = rel.Id;
|
|
175
175
|
}
|
|
@@ -182,7 +182,7 @@ export class WorkbookReaderBase extends EventEmitter {
|
|
|
182
182
|
this.properties = workbook.map?.workbookPr;
|
|
183
183
|
// Build fast lookup for sheet metadata by relationship id.
|
|
184
184
|
this._sheetByRelId = Object.create(null);
|
|
185
|
-
for (const sheet of this.model?.sheets
|
|
185
|
+
for (const sheet of this.model?.sheets ?? []) {
|
|
186
186
|
this._sheetByRelId[sheet.rId] = sheet;
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -289,10 +289,10 @@ export class WorkbookReaderBase extends EventEmitter {
|
|
|
289
289
|
break;
|
|
290
290
|
case "si":
|
|
291
291
|
if (this.options.sharedStrings === "cache") {
|
|
292
|
-
this.sharedStrings.push(richText.length ? { richText } : text
|
|
292
|
+
this.sharedStrings.push(richText.length ? { richText } : (text ?? ""));
|
|
293
293
|
}
|
|
294
294
|
else if (this.options.sharedStrings === "emit") {
|
|
295
|
-
yield { index: index++, text: richText.length ? { richText } : text
|
|
295
|
+
yield { index: index++, text: richText.length ? { richText } : (text ?? "") };
|
|
296
296
|
}
|
|
297
297
|
richText = [];
|
|
298
298
|
font = null;
|
|
@@ -35,10 +35,10 @@ export class WorkbookWriterBase {
|
|
|
35
35
|
this.WorksheetWriterClass = WorksheetWriterClass;
|
|
36
36
|
this.created = options.created || new Date();
|
|
37
37
|
this.modified = options.modified || this.created;
|
|
38
|
-
this.creator = options.creator
|
|
39
|
-
this.lastModifiedBy = options.lastModifiedBy
|
|
38
|
+
this.creator = options.creator ?? "ExcelTS";
|
|
39
|
+
this.lastModifiedBy = options.lastModifiedBy ?? "ExcelTS";
|
|
40
40
|
this.lastPrinted = options.lastPrinted;
|
|
41
|
-
this.useSharedStrings = options.useSharedStrings
|
|
41
|
+
this.useSharedStrings = options.useSharedStrings ?? false;
|
|
42
42
|
this.sharedStrings = new SharedStrings();
|
|
43
43
|
this.styles = options.useStyles ? new StylesXform(true) : new StylesXform.Mock(true);
|
|
44
44
|
this._definedNames = new DefinedNames();
|
|
@@ -170,7 +170,7 @@ export class WorkbookWriterBase {
|
|
|
170
170
|
opts.properties = { tabColor: opts.tabColor, ...opts.properties };
|
|
171
171
|
}
|
|
172
172
|
const id = this.nextId;
|
|
173
|
-
name = name
|
|
173
|
+
name = name ?? `sheet${id}`;
|
|
174
174
|
const worksheet = new this.WorksheetWriterClass({
|
|
175
175
|
id,
|
|
176
176
|
name,
|
|
@@ -165,7 +165,7 @@ class WorksheetReader extends EventEmitter {
|
|
|
165
165
|
min: parseInt(node.attributes.min, 10),
|
|
166
166
|
max: parseInt(node.attributes.max, 10),
|
|
167
167
|
width: parseFloat(node.attributes.width),
|
|
168
|
-
styleId: parseInt(node.attributes.style
|
|
168
|
+
styleId: parseInt(node.attributes.style ?? "0", 10)
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
171
|
break;
|
|
@@ -64,7 +64,7 @@ class WorksheetWriter {
|
|
|
64
64
|
// and a name
|
|
65
65
|
this.name = options.name || `Sheet${this.id}`;
|
|
66
66
|
// add a state
|
|
67
|
-
this.state = options.state
|
|
67
|
+
this.state = options.state ?? "visible";
|
|
68
68
|
// rows are stored here while they need to be worked on.
|
|
69
69
|
// when they are committed, they will be deleted.
|
|
70
70
|
this._rows = [];
|
|
@@ -138,13 +138,13 @@ class WorksheetWriter {
|
|
|
138
138
|
colBreaks: null
|
|
139
139
|
}, options.pageSetup);
|
|
140
140
|
// using shared strings creates a smaller xlsx file but may use more memory
|
|
141
|
-
this.useSharedStrings = options.useSharedStrings
|
|
141
|
+
this.useSharedStrings = options.useSharedStrings ?? false;
|
|
142
142
|
this._workbook = options.workbook;
|
|
143
143
|
this.hasComments = false;
|
|
144
144
|
// views
|
|
145
|
-
this._views = options.views
|
|
145
|
+
this._views = options.views ?? [];
|
|
146
146
|
// auto filter
|
|
147
|
-
this.autoFilter = options.autoFilter
|
|
147
|
+
this.autoFilter = options.autoFilter ?? null;
|
|
148
148
|
this._media = [];
|
|
149
149
|
// worksheet protection
|
|
150
150
|
this.sheetProtection = null;
|
|
@@ -104,7 +104,7 @@ class Table {
|
|
|
104
104
|
case "sum":
|
|
105
105
|
return `SUBTOTAL(109,${this.table.name}[${column.name}])`;
|
|
106
106
|
case "custom":
|
|
107
|
-
return column.totalsRowFormula
|
|
107
|
+
return column.totalsRowFormula ?? null;
|
|
108
108
|
default:
|
|
109
109
|
throw new Error(`Invalid Totals Row Function: ${column.totalsRowFunction}`);
|
|
110
110
|
}
|
|
@@ -166,7 +166,7 @@ class Table {
|
|
|
166
166
|
}
|
|
167
167
|
else {
|
|
168
168
|
assign(column, "totalsRowFunction", "none");
|
|
169
|
-
column.totalsRowFormula = this.getFormula(column)
|
|
169
|
+
column.totalsRowFormula = this.getFormula(column) ?? undefined;
|
|
170
170
|
}
|
|
171
171
|
});
|
|
172
172
|
}
|
|
@@ -454,10 +454,6 @@ export interface ConditionalFormattingOptions {
|
|
|
454
454
|
ref: string;
|
|
455
455
|
rules: ConditionalFormattingRule[];
|
|
456
456
|
}
|
|
457
|
-
export interface ConditionalFormattingOptions {
|
|
458
|
-
ref: string;
|
|
459
|
-
rules: ConditionalFormattingRule[];
|
|
460
|
-
}
|
|
461
457
|
export interface TableStyleProperties {
|
|
462
458
|
theme?: string;
|
|
463
459
|
showFirstColumn?: boolean;
|
|
@@ -107,7 +107,7 @@ export function getFormat(numFmtId) {
|
|
|
107
107
|
}
|
|
108
108
|
// Check default map
|
|
109
109
|
if (DEFAULT_MAP[numFmtId] !== undefined) {
|
|
110
|
-
return TABLE_FMT[DEFAULT_MAP[numFmtId]]
|
|
110
|
+
return TABLE_FMT[DEFAULT_MAP[numFmtId]] ?? "General";
|
|
111
111
|
}
|
|
112
112
|
return "General";
|
|
113
113
|
}
|
|
@@ -339,7 +339,7 @@ function formatGeneral(val) {
|
|
|
339
339
|
*/
|
|
340
340
|
function formatPercentage(val, fmt) {
|
|
341
341
|
// Count % signs
|
|
342
|
-
const percentCount = (fmt.match(/%/g)
|
|
342
|
+
const percentCount = (fmt.match(/%/g) ?? []).length;
|
|
343
343
|
// Multiply value by 100 for each %
|
|
344
344
|
const scaledVal = val * Math.pow(100, percentCount);
|
|
345
345
|
// Remove % from format to process the number part
|
|
@@ -553,7 +553,7 @@ function formatNumberPattern(val, fmt) {
|
|
|
553
553
|
formattedInt = commaify(intPart);
|
|
554
554
|
}
|
|
555
555
|
// Pad integer with leading zeros if needed
|
|
556
|
-
const minIntDigits = (intFmt.match(/0/g)
|
|
556
|
+
const minIntDigits = (intFmt.match(/0/g) ?? []).length;
|
|
557
557
|
if (formattedInt.length < minIntDigits) {
|
|
558
558
|
formattedInt = "0".repeat(minIntDigits - formattedInt.length) + formattedInt;
|
|
559
559
|
}
|
|
@@ -27,7 +27,7 @@ function slideFormula(formula, fromCell, toCell) {
|
|
|
27
27
|
if (!rowDollar) {
|
|
28
28
|
row += to.row - offset.row;
|
|
29
29
|
}
|
|
30
|
-
const res = (sheet
|
|
30
|
+
const res = (sheet ?? "") + (colDollar ?? "") + colCache.n2l(col) + (rowDollar ?? "") + row;
|
|
31
31
|
return res;
|
|
32
32
|
}
|
|
33
33
|
return refMatch;
|