@cj-tech-master/excelts 1.6.2 → 1.6.3-canary.20251224125850.7da664f
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -8
- package/README_zh.md +142 -10
- package/dist/browser/excelts.esm.js +19115 -0
- package/dist/browser/excelts.esm.js.map +1 -0
- package/dist/browser/excelts.esm.min.js +127 -0
- package/dist/browser/excelts.iife.js +13576 -46968
- package/dist/browser/excelts.iife.js.map +1 -1
- package/dist/browser/excelts.iife.min.js +25 -105
- package/dist/cjs/csv/csv-core.js +701 -0
- package/dist/cjs/csv/csv-stream.js +646 -0
- package/dist/cjs/csv/csv.base.js +154 -0
- package/dist/cjs/csv/csv.browser.js +68 -0
- package/dist/cjs/csv/csv.js +226 -162
- package/dist/cjs/doc/anchor.js +2 -2
- package/dist/cjs/doc/cell.js +22 -22
- package/dist/cjs/doc/column.js +7 -7
- package/dist/cjs/doc/data-validations.js +3 -3
- package/dist/cjs/doc/defined-names.js +13 -13
- package/dist/cjs/doc/image.js +7 -7
- package/dist/cjs/doc/modelcontainer.js +2 -2
- package/dist/cjs/doc/note.js +2 -2
- package/dist/cjs/doc/pivot-table.js +5 -5
- package/dist/cjs/doc/range.js +11 -11
- package/dist/cjs/doc/row.js +16 -16
- package/dist/cjs/doc/table.js +5 -5
- package/dist/cjs/doc/workbook.base.js +211 -0
- package/dist/cjs/doc/workbook.browser.js +62 -0
- package/dist/cjs/doc/workbook.js +68 -179
- package/dist/cjs/doc/worksheet.js +41 -41
- package/dist/cjs/index.js +49 -32
- package/dist/cjs/stream/xlsx/hyperlink-reader.js +6 -6
- package/dist/cjs/stream/xlsx/sheet-comments-writer.js +12 -12
- package/dist/cjs/stream/xlsx/sheet-rels-writer.js +4 -4
- package/dist/cjs/stream/xlsx/workbook-reader.js +29 -26
- package/dist/cjs/stream/xlsx/workbook-writer.js +71 -57
- package/dist/cjs/stream/xlsx/worksheet-reader.js +27 -23
- package/dist/cjs/stream/xlsx/worksheet-writer.js +72 -66
- package/dist/cjs/utils/browser-buffer.js +75 -0
- package/dist/cjs/utils/cell-format.js +2 -2
- package/dist/cjs/utils/cell-matrix.js +5 -5
- package/dist/cjs/utils/encryptor.browser.js +240 -0
- package/dist/cjs/utils/parse-sax.js +2 -2
- package/dist/cjs/utils/shared-formula.js +5 -5
- package/dist/cjs/utils/sheet-utils.js +13 -13
- package/dist/cjs/utils/stream-buf.browser.js +355 -0
- package/dist/cjs/utils/stream-buf.js +5 -5
- package/dist/cjs/utils/unzip/extract.js +11 -11
- package/dist/cjs/utils/unzip/index.js +21 -21
- package/dist/cjs/utils/unzip/parse-extra-field.js +3 -3
- package/dist/cjs/utils/unzip/parse.js +16 -16
- package/dist/cjs/utils/unzip/zip-parser.js +3 -3
- package/dist/cjs/utils/utils.base.js +161 -0
- package/dist/cjs/utils/utils.browser.js +89 -0
- package/dist/cjs/utils/utils.js +46 -154
- package/dist/cjs/utils/xml-stream.js +3 -3
- package/dist/cjs/utils/zip/compress.base.js +85 -0
- package/dist/cjs/utils/zip/compress.browser.js +83 -0
- package/dist/cjs/utils/zip/compress.js +18 -198
- package/dist/cjs/utils/zip/crc32.browser.js +88 -0
- package/dist/cjs/utils/zip/index.js +17 -17
- package/dist/cjs/utils/zip/zip-builder.js +10 -10
- package/dist/cjs/utils/zip-stream.browser.js +135 -0
- package/dist/cjs/utils/zip-stream.js +4 -4
- package/dist/cjs/xlsx/xform/base-xform.js +4 -4
- package/dist/cjs/xlsx/xform/book/defined-name-xform.js +4 -4
- package/dist/cjs/xlsx/xform/book/sheet-xform.js +4 -4
- package/dist/cjs/xlsx/xform/book/workbook-calc-properties-xform.js +2 -2
- package/dist/cjs/xlsx/xform/book/workbook-pivot-cache-xform.js +2 -2
- package/dist/cjs/xlsx/xform/book/workbook-properties-xform.js +2 -2
- package/dist/cjs/xlsx/xform/book/workbook-view-xform.js +2 -2
- package/dist/cjs/xlsx/xform/book/workbook-xform.js +24 -24
- package/dist/cjs/xlsx/xform/comment/comment-xform.js +4 -4
- package/dist/cjs/xlsx/xform/comment/comments-xform.js +6 -6
- package/dist/cjs/xlsx/xform/comment/style/vml-position-xform.js +2 -2
- package/dist/cjs/xlsx/xform/comment/style/vml-protection-xform.js +2 -2
- package/dist/cjs/xlsx/xform/comment/vml-anchor-xform.js +2 -2
- package/dist/cjs/xlsx/xform/comment/vml-client-data-xform.js +10 -10
- package/dist/cjs/xlsx/xform/comment/vml-notes-xform.js +6 -6
- package/dist/cjs/xlsx/xform/comment/vml-shape-xform.js +6 -6
- package/dist/cjs/xlsx/xform/comment/vml-textbox-xform.js +2 -2
- package/dist/cjs/xlsx/xform/composite-xform.js +2 -2
- package/dist/cjs/xlsx/xform/core/app-heading-pairs-xform.js +2 -2
- package/dist/cjs/xlsx/xform/core/app-titles-of-parts-xform.js +2 -2
- package/dist/cjs/xlsx/xform/core/app-xform.js +11 -11
- package/dist/cjs/xlsx/xform/core/content-types-xform.js +4 -4
- package/dist/cjs/xlsx/xform/core/core-xform.js +23 -23
- package/dist/cjs/xlsx/xform/core/relationship-xform.js +2 -2
- package/dist/cjs/xlsx/xform/core/relationships-xform.js +6 -6
- package/dist/cjs/xlsx/xform/drawing/base-cell-anchor-xform.js +2 -2
- package/dist/cjs/xlsx/xform/drawing/blip-fill-xform.js +4 -4
- package/dist/cjs/xlsx/xform/drawing/blip-xform.js +2 -2
- package/dist/cjs/xlsx/xform/drawing/c-nv-pic-pr-xform.js +2 -2
- package/dist/cjs/xlsx/xform/drawing/c-nv-pr-xform.js +6 -6
- package/dist/cjs/xlsx/xform/drawing/cell-position-xform.js +7 -7
- package/dist/cjs/xlsx/xform/drawing/drawing-xform.js +10 -10
- package/dist/cjs/xlsx/xform/drawing/ext-lst-xform.js +2 -2
- package/dist/cjs/xlsx/xform/drawing/ext-xform.js +2 -2
- package/dist/cjs/xlsx/xform/drawing/hlink-click-xform.js +2 -2
- package/dist/cjs/xlsx/xform/drawing/nv-pic-pr-xform.js +6 -6
- package/dist/cjs/xlsx/xform/drawing/one-cell-anchor-xform.js +10 -10
- package/dist/cjs/xlsx/xform/drawing/pic-xform.js +9 -9
- package/dist/cjs/xlsx/xform/drawing/two-cell-anchor-xform.js +9 -9
- package/dist/cjs/xlsx/xform/list-xform.js +2 -2
- package/dist/cjs/xlsx/xform/pivot-table/cache-field-xform.js +5 -5
- package/dist/cjs/xlsx/xform/pivot-table/cache-field.js +3 -3
- package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-definition-xform.js +10 -10
- package/dist/cjs/xlsx/xform/pivot-table/pivot-cache-records-xform.js +9 -9
- package/dist/cjs/xlsx/xform/pivot-table/pivot-table-xform.js +10 -11
- package/dist/cjs/xlsx/xform/sheet/auto-filter-xform.js +4 -4
- package/dist/cjs/xlsx/xform/sheet/cell-xform.js +65 -65
- package/dist/cjs/xlsx/xform/sheet/cf/cf-rule-xform.js +27 -27
- package/dist/cjs/xlsx/xform/sheet/cf/cfvo-xform.js +3 -3
- package/dist/cjs/xlsx/xform/sheet/cf/color-scale-xform.js +6 -6
- package/dist/cjs/xlsx/xform/sheet/cf/conditional-formatting-xform.js +6 -6
- package/dist/cjs/xlsx/xform/sheet/cf/conditional-formattings-xform.js +4 -4
- package/dist/cjs/xlsx/xform/sheet/cf/databar-xform.js +6 -6
- package/dist/cjs/xlsx/xform/sheet/cf/ext-lst-ref-xform.js +5 -5
- package/dist/cjs/xlsx/xform/sheet/cf/formula-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/cf/icon-set-xform.js +11 -11
- package/dist/cjs/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.js +3 -3
- package/dist/cjs/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +11 -12
- package/dist/cjs/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.js +4 -4
- package/dist/cjs/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.js +8 -8
- package/dist/cjs/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.js +6 -6
- package/dist/cjs/xlsx/xform/sheet/cf-ext/databar-ext-xform.js +26 -26
- package/dist/cjs/xlsx/xform/sheet/cf-ext/f-ext-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.js +14 -14
- package/dist/cjs/xlsx/xform/sheet/cf-ext/sqref-ext-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/col-xform.js +6 -6
- package/dist/cjs/xlsx/xform/sheet/data-validations-xform.js +18 -18
- package/dist/cjs/xlsx/xform/sheet/dimension-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/drawing-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/ext-lst-xform.js +5 -5
- package/dist/cjs/xlsx/xform/sheet/header-footer-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/hyperlink-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/merge-cell-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/merges.js +8 -8
- package/dist/cjs/xlsx/xform/sheet/outline-properties-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/page-breaks-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/page-margins-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/page-setup-properties-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/page-setup-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/picture-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/print-options-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/row-breaks-xform.js +4 -4
- package/dist/cjs/xlsx/xform/sheet/row-xform.js +11 -11
- package/dist/cjs/xlsx/xform/sheet/sheet-format-properties-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/sheet-properties-xform.js +8 -8
- package/dist/cjs/xlsx/xform/sheet/sheet-protection-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/sheet-view-xform.js +4 -4
- package/dist/cjs/xlsx/xform/sheet/table-part-xform.js +2 -2
- package/dist/cjs/xlsx/xform/sheet/worksheet-xform.js +68 -68
- package/dist/cjs/xlsx/xform/simple/boolean-xform.js +2 -2
- package/dist/cjs/xlsx/xform/simple/date-xform.js +2 -2
- package/dist/cjs/xlsx/xform/simple/float-xform.js +2 -2
- package/dist/cjs/xlsx/xform/simple/integer-xform.js +2 -2
- package/dist/cjs/xlsx/xform/simple/string-xform.js +2 -2
- package/dist/cjs/xlsx/xform/static-xform.js +4 -4
- package/dist/cjs/xlsx/xform/strings/phonetic-text-xform.js +6 -6
- package/dist/cjs/xlsx/xform/strings/rich-text-xform.js +6 -6
- package/dist/cjs/xlsx/xform/strings/shared-string-xform.js +8 -8
- package/dist/cjs/xlsx/xform/strings/shared-strings-xform.js +6 -6
- package/dist/cjs/xlsx/xform/strings/text-xform.js +2 -2
- package/dist/cjs/xlsx/xform/style/alignment-xform.js +8 -8
- package/dist/cjs/xlsx/xform/style/border-xform.js +8 -8
- package/dist/cjs/xlsx/xform/style/color-xform.js +2 -2
- package/dist/cjs/xlsx/xform/style/dxf-xform.js +14 -14
- package/dist/cjs/xlsx/xform/style/fill-xform.js +9 -9
- package/dist/cjs/xlsx/xform/style/font-xform.js +22 -22
- package/dist/cjs/xlsx/xform/style/numfmt-xform.js +5 -5
- package/dist/cjs/xlsx/xform/style/protection-xform.js +2 -2
- package/dist/cjs/xlsx/xform/style/style-xform.js +6 -6
- package/dist/cjs/xlsx/xform/style/styles-xform.js +39 -39
- package/dist/cjs/xlsx/xform/style/underline-xform.js +2 -2
- package/dist/cjs/xlsx/xform/table/auto-filter-xform.js +4 -4
- package/dist/cjs/xlsx/xform/table/custom-filter-xform.js +2 -2
- package/dist/cjs/xlsx/xform/table/filter-column-xform.js +9 -9
- package/dist/cjs/xlsx/xform/table/filter-xform.js +2 -2
- package/dist/cjs/xlsx/xform/table/table-column-xform.js +2 -2
- package/dist/cjs/xlsx/xform/table/table-style-info-xform.js +2 -2
- package/dist/cjs/xlsx/xform/table/table-xform.js +12 -12
- package/dist/cjs/xlsx/xlsx.base.js +742 -0
- package/dist/cjs/xlsx/xlsx.browser.js +205 -0
- package/dist/cjs/xlsx/xlsx.js +91 -833
- package/dist/esm/csv/csv-core.js +694 -0
- package/dist/esm/csv/csv-stream.js +638 -0
- package/dist/esm/csv/csv.base.js +141 -0
- package/dist/esm/csv/csv.browser.js +65 -0
- package/dist/esm/csv/csv.js +189 -159
- package/dist/esm/doc/workbook.base.js +207 -0
- package/dist/esm/doc/workbook.browser.js +59 -0
- package/dist/esm/doc/workbook.js +64 -175
- package/dist/esm/index.browser.js +33 -1
- package/dist/esm/index.js +23 -8
- package/dist/esm/local.js +0 -1
- package/dist/esm/stream/xlsx/hyperlink-reader.js +1 -1
- package/dist/esm/stream/xlsx/workbook-reader.js +7 -4
- package/dist/esm/stream/xlsx/workbook-writer.js +37 -23
- package/dist/esm/stream/xlsx/worksheet-reader.js +12 -8
- package/dist/esm/stream/xlsx/worksheet-writer.js +12 -6
- package/dist/esm/utils/browser-buffer.js +67 -0
- package/dist/esm/utils/encryptor.browser.js +237 -0
- package/dist/esm/utils/stream-buf.browser.js +352 -0
- package/dist/esm/utils/utils.base.js +142 -0
- package/dist/esm/utils/utils.browser.js +68 -0
- package/dist/esm/utils/utils.js +15 -123
- package/dist/esm/utils/zip/compress.base.js +80 -0
- package/dist/esm/utils/zip/compress.browser.js +76 -0
- package/dist/esm/utils/zip/compress.js +16 -164
- package/dist/esm/utils/zip/crc32.browser.js +82 -0
- package/dist/esm/utils/zip-stream.browser.js +132 -0
- package/dist/esm/xlsx/xform/pivot-table/pivot-table-xform.js +2 -3
- package/dist/esm/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.js +2 -3
- package/dist/esm/xlsx/xlsx.base.js +739 -0
- package/dist/esm/xlsx/xlsx.browser.js +202 -0
- package/dist/esm/xlsx/xlsx.js +87 -829
- package/dist/types/csv/csv-core.d.ts +207 -0
- package/dist/types/csv/csv-stream.d.ts +114 -0
- package/dist/types/csv/csv.base.d.ts +61 -0
- package/dist/types/csv/csv.browser.d.ts +33 -0
- package/dist/types/csv/csv.d.ts +97 -71
- package/dist/types/doc/anchor.d.ts +1 -1
- package/dist/types/doc/cell.d.ts +7 -7
- package/dist/types/doc/column.d.ts +3 -3
- package/dist/types/doc/defined-names.d.ts +4 -4
- package/dist/types/doc/image.d.ts +2 -2
- package/dist/types/doc/modelcontainer.d.ts +1 -1
- package/dist/types/doc/pivot-table.d.ts +1 -1
- package/dist/types/doc/range.d.ts +1 -1
- package/dist/types/doc/row.d.ts +3 -3
- package/dist/types/doc/table.d.ts +4 -4
- package/dist/types/doc/workbook.base.d.ts +111 -0
- package/dist/types/doc/workbook.browser.d.ts +38 -0
- package/dist/types/doc/workbook.d.ts +62 -92
- package/dist/types/doc/worksheet.d.ts +10 -10
- package/dist/types/index.browser.d.ts +19 -5
- package/dist/types/index.d.ts +24 -20
- package/dist/types/local.d.ts +0 -1
- package/dist/types/stream/xlsx/hyperlink-reader.d.ts +11 -11
- package/dist/types/stream/xlsx/workbook-reader.d.ts +125 -36
- package/dist/types/stream/xlsx/workbook-writer.d.ts +105 -22
- package/dist/types/stream/xlsx/worksheet-reader.d.ts +40 -22
- package/dist/types/stream/xlsx/worksheet-writer.d.ts +83 -49
- package/dist/types/types.d.ts +4 -16
- package/dist/types/utils/browser-buffer.d.ts +28 -0
- package/dist/types/utils/col-cache.d.ts +1 -1
- package/dist/types/utils/encryptor.browser.d.ts +28 -0
- package/dist/types/utils/sheet-utils.d.ts +3 -3
- package/dist/types/utils/stream-buf.browser.d.ts +41 -0
- package/dist/types/utils/unzip/extract.d.ts +6 -6
- package/dist/types/utils/unzip/index.d.ts +8 -8
- package/dist/types/utils/unzip/parse.d.ts +3 -3
- package/dist/types/utils/utils.base.d.ts +29 -0
- package/dist/types/utils/utils.browser.d.ts +29 -0
- package/dist/types/utils/utils.d.ts +6 -25
- package/dist/types/utils/zip/compress.base.d.ts +42 -0
- package/dist/types/utils/zip/compress.browser.d.ts +54 -0
- package/dist/types/utils/zip/compress.d.ts +13 -45
- package/dist/types/utils/zip/crc32.browser.d.ts +52 -0
- package/dist/types/utils/zip/index.d.ts +5 -5
- package/dist/types/utils/zip/zip-builder.d.ts +1 -1
- package/dist/types/utils/zip-stream.browser.d.ts +39 -0
- package/dist/types/xlsx/xform/base-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/defined-name-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/sheet-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/workbook-calc-properties-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/workbook-pivot-cache-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/workbook-properties-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/workbook-view-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/book/workbook-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/comment/comment-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/comment/comments-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/comment/style/vml-position-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/comment/style/vml-protection-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/comment/vml-anchor-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/comment/vml-client-data-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/comment/vml-notes-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/comment/vml-shape-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/comment/vml-textbox-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/composite-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/app-heading-pairs-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/app-titles-of-parts-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/app-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/content-types-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/core-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/relationship-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/core/relationships-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/base-cell-anchor-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/blip-fill-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/drawing/blip-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/c-nv-pic-pr-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/c-nv-pr-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/cell-position-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/drawing/drawing-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/ext-lst-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/ext-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/hlink-click-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/nv-pic-pr-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/one-cell-anchor-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/pic-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/drawing/two-cell-anchor-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/list-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/pivot-table/cache-field-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/pivot-table/pivot-cache-definition-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/pivot-table/pivot-cache-records-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/pivot-table/pivot-table-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/auto-filter-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cell-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf/cf-rule-xform.d.ts +6 -6
- package/dist/types/xlsx/xform/sheet/cf/cfvo-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf/color-scale-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/sheet/cf/conditional-formatting-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf/conditional-formattings-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/sheet/cf/databar-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/sheet/cf/ext-lst-ref-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf/formula-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf/icon-set-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/sheet/cf-ext/cf-icon-ext-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf-ext/cf-rule-ext-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/sheet/cf-ext/cfvo-ext-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/sheet/cf-ext/conditional-formatting-ext-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/sheet/cf-ext/conditional-formattings-ext-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/sheet/cf-ext/databar-ext-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/sheet/cf-ext/f-ext-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/cf-ext/icon-set-ext-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/sheet/cf-ext/sqref-ext-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/col-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/data-validations-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/dimension-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/drawing-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/ext-lst-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/header-footer-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/hyperlink-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/merge-cell-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/outline-properties-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/page-breaks-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/page-margins-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/page-setup-properties-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/page-setup-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/picture-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/print-options-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/row-breaks-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/row-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/sheet-format-properties-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/sheet-properties-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/sheet-protection-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/sheet-view-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/table-part-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/sheet/worksheet-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/simple/boolean-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/simple/date-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/simple/float-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/simple/integer-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/simple/string-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/static-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/strings/phonetic-text-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/strings/rich-text-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/strings/shared-string-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/strings/shared-strings-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/strings/text-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/alignment-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/border-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/style/color-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/dxf-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/fill-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/style/font-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/numfmt-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/protection-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/style/style-xform.d.ts +3 -3
- package/dist/types/xlsx/xform/style/styles-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/style/underline-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/table/auto-filter-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/table/custom-filter-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/table/filter-column-xform.d.ts +2 -2
- package/dist/types/xlsx/xform/table/filter-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/table/table-column-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/table/table-style-info-xform.d.ts +1 -1
- package/dist/types/xlsx/xform/table/table-xform.d.ts +1 -1
- package/dist/types/xlsx/xlsx.base.d.ts +134 -0
- package/dist/types/xlsx/xlsx.browser.d.ts +31 -0
- package/dist/types/xlsx/xlsx.d.ts +20 -80
- package/package.json +14 -16
package/dist/cjs/xlsx/xlsx.js
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* XLSX - Node.js version with full functionality
|
|
4
|
+
*
|
|
5
|
+
* Extends XLSXBase with:
|
|
6
|
+
* - readFile: Read from file path
|
|
7
|
+
* - writeFile: Write to file path
|
|
8
|
+
* - read: Read from stream
|
|
9
|
+
* - write: Write to stream
|
|
10
|
+
* - load: Load from buffer
|
|
11
|
+
* - writeBuffer: Write to buffer
|
|
12
|
+
*/
|
|
2
13
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
14
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
15
|
};
|
|
@@ -7,27 +18,10 @@ exports.XLSX = void 0;
|
|
|
7
18
|
const fs_1 = __importDefault(require("fs"));
|
|
8
19
|
const fflate_1 = require("fflate");
|
|
9
20
|
const stream_1 = require("stream");
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const styles_xform_js_1 = require("./xform/style/styles-xform");
|
|
15
|
-
const core_xform_js_1 = require("./xform/core/core-xform");
|
|
16
|
-
const shared_strings_xform_js_1 = require("./xform/strings/shared-strings-xform");
|
|
17
|
-
const relationships_xform_js_1 = require("./xform/core/relationships-xform");
|
|
18
|
-
const content_types_xform_js_1 = require("./xform/core/content-types-xform");
|
|
19
|
-
const app_xform_js_1 = require("./xform/core/app-xform");
|
|
20
|
-
const workbook_xform_js_1 = require("./xform/book/workbook-xform");
|
|
21
|
-
const worksheet_xform_js_1 = require("./xform/sheet/worksheet-xform");
|
|
22
|
-
const drawing_xform_js_1 = require("./xform/drawing/drawing-xform");
|
|
23
|
-
const table_xform_js_1 = require("./xform/table/table-xform");
|
|
24
|
-
const pivot_cache_records_xform_js_1 = require("./xform/pivot-table/pivot-cache-records-xform");
|
|
25
|
-
const pivot_cache_definition_xform_js_1 = require("./xform/pivot-table/pivot-cache-definition-xform");
|
|
26
|
-
const pivot_table_xform_js_1 = require("./xform/pivot-table/pivot-table-xform");
|
|
27
|
-
const comments_xform_js_1 = require("./xform/comment/comments-xform");
|
|
28
|
-
const vml_notes_xform_js_1 = require("./xform/comment/vml-notes-xform");
|
|
29
|
-
const theme1_js_1 = require("./xml/theme1");
|
|
30
|
-
const rel_type_js_1 = require("./rel-type");
|
|
21
|
+
const zip_stream_1 = require("../utils/zip-stream");
|
|
22
|
+
const stream_buf_1 = require("../utils/stream-buf");
|
|
23
|
+
const utils_1 = require("../utils/utils");
|
|
24
|
+
const xlsx_base_1 = require("./xlsx.base");
|
|
31
25
|
function fsReadFileAsync(filename, options) {
|
|
32
26
|
return new Promise((resolve, reject) => {
|
|
33
27
|
fs_1.default.readFile(filename, options, (error, data) => {
|
|
@@ -40,16 +34,34 @@ function fsReadFileAsync(filename, options) {
|
|
|
40
34
|
});
|
|
41
35
|
});
|
|
42
36
|
}
|
|
43
|
-
class XLSX {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
37
|
+
class XLSX extends xlsx_base_1.XLSXBase {
|
|
38
|
+
// ===========================================================================
|
|
39
|
+
// Abstract method implementations
|
|
40
|
+
// ===========================================================================
|
|
41
|
+
createStreamBuf() {
|
|
42
|
+
return new stream_buf_1.StreamBuf();
|
|
43
|
+
}
|
|
44
|
+
createBinaryStream(data) {
|
|
45
|
+
const stream = new stream_1.PassThrough();
|
|
46
|
+
stream.end(Buffer.from(data));
|
|
47
|
+
return stream;
|
|
48
|
+
}
|
|
49
|
+
createTextStream(content) {
|
|
50
|
+
const stream = new stream_1.PassThrough({
|
|
51
|
+
readableObjectMode: true,
|
|
52
|
+
writableObjectMode: true
|
|
53
|
+
});
|
|
54
|
+
stream.end(content);
|
|
55
|
+
return stream;
|
|
56
|
+
}
|
|
57
|
+
bufferToString(data) {
|
|
58
|
+
return (0, utils_1.bufferToString)(data);
|
|
59
|
+
}
|
|
60
|
+
// ===========================================================================
|
|
61
|
+
// Node.js specific: File operations
|
|
62
|
+
// ===========================================================================
|
|
51
63
|
async readFile(filename, options) {
|
|
52
|
-
if (!(await (0,
|
|
64
|
+
if (!(await (0, utils_1.fileExists)(filename))) {
|
|
53
65
|
throw new Error(`File not found: ${filename}`);
|
|
54
66
|
}
|
|
55
67
|
const stream = fs_1.default.createReadStream(filename);
|
|
@@ -63,349 +75,37 @@ class XLSX {
|
|
|
63
75
|
throw error;
|
|
64
76
|
}
|
|
65
77
|
}
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
parseWorkbook(stream) {
|
|
71
|
-
const xform = new workbook_xform_js_1.WorkbookXform();
|
|
72
|
-
return xform.parseStream(stream);
|
|
73
|
-
}
|
|
74
|
-
parseSharedStrings(stream) {
|
|
75
|
-
const xform = new shared_strings_xform_js_1.SharedStringsXform();
|
|
76
|
-
return xform.parseStream(stream);
|
|
77
|
-
}
|
|
78
|
-
reconcile(model, options) {
|
|
79
|
-
const workbookXform = new workbook_xform_js_1.WorkbookXform();
|
|
80
|
-
const worksheetXform = new worksheet_xform_js_1.WorkSheetXform(options);
|
|
81
|
-
const drawingXform = new drawing_xform_js_1.DrawingXform();
|
|
82
|
-
const tableXform = new table_xform_js_1.TableXform();
|
|
83
|
-
workbookXform.reconcile(model);
|
|
84
|
-
// reconcile drawings with their rels
|
|
85
|
-
const drawingOptions = {
|
|
86
|
-
media: model.media,
|
|
87
|
-
mediaIndex: model.mediaIndex
|
|
88
|
-
};
|
|
89
|
-
Object.keys(model.drawings).forEach(name => {
|
|
90
|
-
const drawing = model.drawings[name];
|
|
91
|
-
const drawingRel = model.drawingRels[name];
|
|
92
|
-
if (drawingRel) {
|
|
93
|
-
drawingOptions.rels = drawingRel.reduce((o, rel) => {
|
|
94
|
-
o[rel.Id] = rel;
|
|
95
|
-
return o;
|
|
96
|
-
}, {});
|
|
97
|
-
(drawing.anchors || []).forEach((anchor) => {
|
|
98
|
-
const hyperlinks = anchor.picture && anchor.picture.hyperlinks;
|
|
99
|
-
if (hyperlinks && drawingOptions.rels[hyperlinks.rId]) {
|
|
100
|
-
hyperlinks.hyperlink = drawingOptions.rels[hyperlinks.rId].Target;
|
|
101
|
-
delete hyperlinks.rId;
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
drawingXform.reconcile(drawing, drawingOptions);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
// reconcile tables with the default styles
|
|
108
|
-
const tableOptions = {
|
|
109
|
-
styles: model.styles
|
|
110
|
-
};
|
|
111
|
-
Object.values(model.tables).forEach((table) => {
|
|
112
|
-
tableXform.reconcile(table, tableOptions);
|
|
113
|
-
});
|
|
114
|
-
// Reconcile pivot tables - link pivot tables to worksheets and cache data
|
|
115
|
-
this._reconcilePivotTables(model);
|
|
116
|
-
const sheetOptions = {
|
|
117
|
-
styles: model.styles,
|
|
118
|
-
sharedStrings: model.sharedStrings,
|
|
119
|
-
media: model.media,
|
|
120
|
-
mediaIndex: model.mediaIndex,
|
|
121
|
-
date1904: model.properties && model.properties.date1904,
|
|
122
|
-
drawings: model.drawings,
|
|
123
|
-
comments: model.comments,
|
|
124
|
-
tables: model.tables,
|
|
125
|
-
vmlDrawings: model.vmlDrawings,
|
|
126
|
-
pivotTables: model.pivotTablesIndexed
|
|
127
|
-
};
|
|
128
|
-
model.worksheets.forEach((worksheet) => {
|
|
129
|
-
worksheet.relationships = model.worksheetRels[worksheet.sheetNo];
|
|
130
|
-
worksheetXform.reconcile(worksheet, sheetOptions);
|
|
131
|
-
});
|
|
132
|
-
// delete unnecessary parts
|
|
133
|
-
delete model.worksheetHash;
|
|
134
|
-
delete model.worksheetRels;
|
|
135
|
-
delete model.globalRels;
|
|
136
|
-
delete model.sharedStrings;
|
|
137
|
-
delete model.workbookRels;
|
|
138
|
-
delete model.sheetDefs;
|
|
139
|
-
delete model.styles;
|
|
140
|
-
delete model.mediaIndex;
|
|
141
|
-
delete model.drawings;
|
|
142
|
-
delete model.drawingRels;
|
|
143
|
-
delete model.vmlDrawings;
|
|
144
|
-
// Clean up raw pivot table data after reconciliation
|
|
145
|
-
delete model.pivotTableRels;
|
|
146
|
-
delete model.pivotCacheDefinitionRels;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* Reconcile pivot tables by linking them to worksheets and their cache data.
|
|
150
|
-
* This builds a complete pivot table model ready for writing.
|
|
151
|
-
*/
|
|
152
|
-
_reconcilePivotTables(model) {
|
|
153
|
-
// Skip if no pivot tables were loaded (object is empty or undefined)
|
|
154
|
-
const rawPivotTables = model.pivotTables || {};
|
|
155
|
-
if (typeof rawPivotTables !== "object" || Object.keys(rawPivotTables).length === 0) {
|
|
156
|
-
// Ensure pivotTables is an empty array (not an object)
|
|
157
|
-
model.pivotTables = [];
|
|
158
|
-
// Also create an empty indexed object for worksheet reconciliation
|
|
159
|
-
model.pivotTablesIndexed = {};
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
// Build mapping from definition name to cacheId
|
|
163
|
-
const definitionToCacheId = this._buildDefinitionToCacheIdMap(model);
|
|
164
|
-
// Build a map of cache IDs to their definitions and records
|
|
165
|
-
const cacheMap = new Map();
|
|
166
|
-
// Process cache definitions
|
|
167
|
-
Object.entries(model.pivotCacheDefinitions || {}).forEach(([name, definition]) => {
|
|
168
|
-
// Get the cacheId from the mapping (derived from workbook.xml pivotCaches)
|
|
169
|
-
const cacheId = definitionToCacheId.get(name);
|
|
170
|
-
if (cacheId !== undefined) {
|
|
171
|
-
const recordsName = name.replace("Definition", "Records");
|
|
172
|
-
cacheMap.set(cacheId, {
|
|
173
|
-
definition,
|
|
174
|
-
records: model.pivotCacheRecords?.[recordsName],
|
|
175
|
-
definitionName: name
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
// Process pivot tables and link to worksheets
|
|
180
|
-
const loadedPivotTables = [];
|
|
181
|
-
// Create indexed object for worksheet reconciliation (keyed by relative path)
|
|
182
|
-
const pivotTablesIndexed = {};
|
|
183
|
-
Object.entries(rawPivotTables).forEach(([pivotName, pivotTable]) => {
|
|
184
|
-
const pt = pivotTable;
|
|
185
|
-
const tableNumber = this._extractTableNumber(pivotName);
|
|
186
|
-
// Get cache data for this pivot table
|
|
187
|
-
const cacheData = cacheMap.get(pt.cacheId);
|
|
188
|
-
// Build complete pivot table model
|
|
189
|
-
const completePivotTable = {
|
|
190
|
-
// Core model data
|
|
191
|
-
...pt,
|
|
192
|
-
tableNumber,
|
|
193
|
-
// Link to cache data
|
|
194
|
-
cacheDefinition: cacheData?.definition,
|
|
195
|
-
cacheRecords: cacheData?.records,
|
|
196
|
-
// Reconstruct cacheFields from definition for compatibility
|
|
197
|
-
cacheFields: cacheData?.definition?.cacheFields || [],
|
|
198
|
-
// Determine rows, columns, values from parsed data
|
|
199
|
-
rows: pt.rowFields.filter(f => f >= 0),
|
|
200
|
-
columns: pt.colFields.filter(f => f >= 0 && f !== -2),
|
|
201
|
-
values: pt.dataFields.map(df => df.fld),
|
|
202
|
-
// Determine metric from dataFields
|
|
203
|
-
metric: this._determineMetric(pt.dataFields),
|
|
204
|
-
// Preserve formatting options
|
|
205
|
-
applyWidthHeightFormats: pt.applyWidthHeightFormats || "0"
|
|
206
|
-
};
|
|
207
|
-
loadedPivotTables.push(completePivotTable);
|
|
208
|
-
// Index by relative path for worksheet reconciliation
|
|
209
|
-
pivotTablesIndexed[`../pivotTables/${pivotName}.xml`] = completePivotTable;
|
|
210
|
-
});
|
|
211
|
-
// Sort by table number to maintain order
|
|
212
|
-
loadedPivotTables.sort((a, b) => a.tableNumber - b.tableNumber);
|
|
213
|
-
// Replace pivotTables object with the processed array
|
|
214
|
-
// This is what the Workbook model setter expects
|
|
215
|
-
model.pivotTables = loadedPivotTables;
|
|
216
|
-
// Also keep indexed version for worksheet reconciliation
|
|
217
|
-
model.pivotTablesIndexed = pivotTablesIndexed;
|
|
218
|
-
// Also keep as loadedPivotTables for backward compatibility
|
|
219
|
-
model.loadedPivotTables = loadedPivotTables;
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Extract table number from pivot table name (e.g., "pivotTable1" -> 1)
|
|
223
|
-
*/
|
|
224
|
-
_extractTableNumber(name) {
|
|
225
|
-
const match = name.match(/pivotTable(\d+)/);
|
|
226
|
-
return match ? parseInt(match[1], 10) : 1;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Build a mapping from rId to cacheId using pivotCaches from workbook.xml
|
|
230
|
-
* and workbookRels to determine which definition file corresponds to which cacheId
|
|
231
|
-
*/
|
|
232
|
-
_buildCacheIdMap(model) {
|
|
233
|
-
const rIdToCacheId = new Map();
|
|
234
|
-
// pivotCaches from workbook.xml contains {cacheId, rId} mappings
|
|
235
|
-
const pivotCaches = model.pivotCaches || [];
|
|
236
|
-
for (const cache of pivotCaches) {
|
|
237
|
-
if (cache.cacheId && cache.rId) {
|
|
238
|
-
rIdToCacheId.set(cache.rId, parseInt(cache.cacheId, 10));
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
return rIdToCacheId;
|
|
242
|
-
}
|
|
243
|
-
/**
|
|
244
|
-
* Build a mapping from definition name to cacheId
|
|
245
|
-
*/
|
|
246
|
-
_buildDefinitionToCacheIdMap(model) {
|
|
247
|
-
const definitionToCacheId = new Map();
|
|
248
|
-
const rIdToCacheId = this._buildCacheIdMap(model);
|
|
249
|
-
const workbookRels = model.workbookRels || [];
|
|
250
|
-
// Map workbook rels to get definitionNumber -> cacheId mapping
|
|
251
|
-
for (const rel of workbookRels) {
|
|
252
|
-
if (rel.Type === XLSX.RelType.PivotCacheDefinition && rel.Target) {
|
|
253
|
-
// Extract definition number from target (e.g., "pivotCache/pivotCacheDefinition1.xml" -> 1)
|
|
254
|
-
const match = rel.Target.match(/pivotCacheDefinition(\d+)\.xml/);
|
|
255
|
-
if (match) {
|
|
256
|
-
const defName = `pivotCacheDefinition${match[1]}`;
|
|
257
|
-
const cacheId = rIdToCacheId.get(rel.Id);
|
|
258
|
-
if (cacheId !== undefined) {
|
|
259
|
-
definitionToCacheId.set(defName, cacheId);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
return definitionToCacheId;
|
|
265
|
-
}
|
|
266
|
-
/**
|
|
267
|
-
* Determine the aggregation metric from dataFields
|
|
268
|
-
*/
|
|
269
|
-
_determineMetric(dataFields) {
|
|
270
|
-
if (dataFields.length > 0 && dataFields[0].subtotal === "count") {
|
|
271
|
-
return "count";
|
|
272
|
-
}
|
|
273
|
-
return "sum";
|
|
274
|
-
}
|
|
275
|
-
async _processWorksheetEntry(stream, model, sheetNo, options, path) {
|
|
276
|
-
const xform = new worksheet_xform_js_1.WorkSheetXform(options);
|
|
277
|
-
const worksheet = await xform.parseStream(stream);
|
|
278
|
-
if (!worksheet) {
|
|
279
|
-
throw new Error(`Failed to parse worksheet ${path}`);
|
|
280
|
-
}
|
|
281
|
-
worksheet.sheetNo = sheetNo;
|
|
282
|
-
model.worksheetHash[path] = worksheet;
|
|
283
|
-
model.worksheets.push(worksheet);
|
|
284
|
-
}
|
|
285
|
-
async _processCommentEntry(stream, model, name) {
|
|
286
|
-
const xform = new comments_xform_js_1.CommentsXform();
|
|
287
|
-
const comments = await xform.parseStream(stream);
|
|
288
|
-
model.comments[`../${name}.xml`] = comments;
|
|
289
|
-
}
|
|
290
|
-
async _processTableEntry(stream, model, name) {
|
|
291
|
-
const xform = new table_xform_js_1.TableXform();
|
|
292
|
-
const table = await xform.parseStream(stream);
|
|
293
|
-
model.tables[`../tables/${name}.xml`] = table;
|
|
294
|
-
}
|
|
295
|
-
async _processWorksheetRelsEntry(stream, model, sheetNo) {
|
|
296
|
-
const xform = new relationships_xform_js_1.RelationshipsXform();
|
|
297
|
-
const relationships = await xform.parseStream(stream);
|
|
298
|
-
model.worksheetRels[sheetNo] = relationships;
|
|
299
|
-
}
|
|
300
|
-
async _processMediaEntry(stream, model, filename) {
|
|
301
|
-
const lastDot = filename.lastIndexOf(".");
|
|
302
|
-
// if we can't determine extension, ignore it
|
|
303
|
-
if (lastDot >= 1) {
|
|
304
|
-
const extension = filename.substr(lastDot + 1);
|
|
305
|
-
const name = filename.substr(0, lastDot);
|
|
306
|
-
await new Promise((resolve, reject) => {
|
|
307
|
-
const streamBuf = new stream_buf_js_1.StreamBuf();
|
|
308
|
-
const cleanup = () => {
|
|
309
|
-
stream.removeListener("error", onError);
|
|
310
|
-
streamBuf.removeListener("error", onError);
|
|
311
|
-
streamBuf.removeListener("finish", onFinish);
|
|
312
|
-
};
|
|
313
|
-
const onFinish = () => {
|
|
314
|
-
cleanup();
|
|
315
|
-
model.mediaIndex[filename] = model.media.length;
|
|
316
|
-
model.mediaIndex[name] = model.media.length;
|
|
317
|
-
const medium = {
|
|
318
|
-
type: "image",
|
|
319
|
-
name,
|
|
320
|
-
extension,
|
|
321
|
-
buffer: streamBuf.toBuffer()
|
|
322
|
-
};
|
|
323
|
-
model.media.push(medium);
|
|
324
|
-
resolve();
|
|
325
|
-
};
|
|
326
|
-
const onError = (error) => {
|
|
327
|
-
cleanup();
|
|
328
|
-
reject(error);
|
|
329
|
-
};
|
|
330
|
-
streamBuf.once("finish", onFinish);
|
|
331
|
-
stream.on("error", onError);
|
|
332
|
-
streamBuf.on("error", onError);
|
|
333
|
-
stream.pipe(streamBuf);
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
async _processDrawingEntry(entry, model, name) {
|
|
338
|
-
const xform = new drawing_xform_js_1.DrawingXform();
|
|
339
|
-
const drawing = await xform.parseStream(entry);
|
|
340
|
-
model.drawings[name] = drawing;
|
|
341
|
-
}
|
|
342
|
-
async _processDrawingRelsEntry(entry, model, name) {
|
|
343
|
-
const xform = new relationships_xform_js_1.RelationshipsXform();
|
|
344
|
-
const relationships = await xform.parseStream(entry);
|
|
345
|
-
model.drawingRels[name] = relationships;
|
|
346
|
-
}
|
|
347
|
-
async _processVmlDrawingEntry(entry, model, name) {
|
|
348
|
-
const xform = new vml_notes_xform_js_1.VmlNotesXform();
|
|
349
|
-
const vmlDrawing = await xform.parseStream(entry);
|
|
350
|
-
model.vmlDrawings[`../drawings/${name}.vml`] = vmlDrawing;
|
|
351
|
-
}
|
|
352
|
-
async _processThemeEntry(stream, model, name) {
|
|
353
|
-
await new Promise((resolve, reject) => {
|
|
354
|
-
// TODO: stream entry into buffer and store the xml in the model.themes[]
|
|
355
|
-
const streamBuf = new stream_buf_js_1.StreamBuf();
|
|
78
|
+
writeFile(filename, options) {
|
|
79
|
+
const stream = fs_1.default.createWriteStream(filename);
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
356
81
|
const cleanup = () => {
|
|
82
|
+
stream.removeListener("finish", onFinish);
|
|
357
83
|
stream.removeListener("error", onError);
|
|
358
|
-
streamBuf.removeListener("error", onError);
|
|
359
|
-
streamBuf.removeListener("finish", onFinish);
|
|
360
84
|
};
|
|
361
85
|
const onFinish = () => {
|
|
362
86
|
cleanup();
|
|
363
|
-
model.themes[name] = streamBuf.read().toString();
|
|
364
87
|
resolve();
|
|
365
88
|
};
|
|
366
|
-
const onError = (
|
|
89
|
+
const onError = (error) => {
|
|
367
90
|
cleanup();
|
|
368
|
-
reject(
|
|
91
|
+
reject(error);
|
|
369
92
|
};
|
|
370
|
-
|
|
93
|
+
stream.once("finish", onFinish);
|
|
371
94
|
stream.on("error", onError);
|
|
372
|
-
|
|
373
|
-
|
|
95
|
+
this.write(stream, options)
|
|
96
|
+
.then(() => {
|
|
97
|
+
stream.end();
|
|
98
|
+
})
|
|
99
|
+
.catch(err => {
|
|
100
|
+
cleanup();
|
|
101
|
+
reject(err);
|
|
102
|
+
});
|
|
374
103
|
});
|
|
375
104
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
if (pivotTable) {
|
|
380
|
-
model.pivotTables[name] = pivotTable;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
async _processPivotTableRelsEntry(stream, model, name) {
|
|
384
|
-
const xform = new relationships_xform_js_1.RelationshipsXform();
|
|
385
|
-
const relationships = await xform.parseStream(stream);
|
|
386
|
-
model.pivotTableRels[name] = relationships;
|
|
387
|
-
}
|
|
388
|
-
async _processPivotCacheDefinitionEntry(stream, model, name) {
|
|
389
|
-
const xform = new pivot_cache_definition_xform_js_1.PivotCacheDefinitionXform();
|
|
390
|
-
const cacheDefinition = await xform.parseStream(stream);
|
|
391
|
-
if (cacheDefinition) {
|
|
392
|
-
model.pivotCacheDefinitions[name] = cacheDefinition;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
async _processPivotCacheDefinitionRelsEntry(stream, model, name) {
|
|
396
|
-
const xform = new relationships_xform_js_1.RelationshipsXform();
|
|
397
|
-
const relationships = await xform.parseStream(stream);
|
|
398
|
-
model.pivotCacheDefinitionRels[name] = relationships;
|
|
399
|
-
}
|
|
400
|
-
async _processPivotCacheRecordsEntry(stream, model, name) {
|
|
401
|
-
const xform = new pivot_cache_records_xform_js_1.PivotCacheRecordsXform();
|
|
402
|
-
const cacheRecords = await xform.parseStream(stream);
|
|
403
|
-
if (cacheRecords) {
|
|
404
|
-
model.pivotCacheRecords[name] = cacheRecords;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
105
|
+
// ===========================================================================
|
|
106
|
+
// Node.js specific: Stream operations
|
|
107
|
+
// ===========================================================================
|
|
407
108
|
async read(stream, options) {
|
|
408
|
-
// Use streaming unzip with fflate
|
|
409
109
|
const allFiles = {};
|
|
410
110
|
await new Promise((resolve, reject) => {
|
|
411
111
|
let filesProcessed = 0;
|
|
@@ -437,7 +137,6 @@ class XLSX {
|
|
|
437
137
|
totalLength += data.length;
|
|
438
138
|
}
|
|
439
139
|
if (final) {
|
|
440
|
-
// Optimize for single chunk case
|
|
441
140
|
if (fileChunks.length === 1) {
|
|
442
141
|
allFiles[file.name] = fileChunks[0];
|
|
443
142
|
}
|
|
@@ -479,9 +178,31 @@ class XLSX {
|
|
|
479
178
|
});
|
|
480
179
|
return this.loadFromFiles(allFiles, options);
|
|
481
180
|
}
|
|
181
|
+
async write(stream, options) {
|
|
182
|
+
options = options || {};
|
|
183
|
+
const { model } = this.workbook;
|
|
184
|
+
const zip = new zip_stream_1.ZipWriter(options.zip);
|
|
185
|
+
zip.pipe(stream);
|
|
186
|
+
this.prepareModel(model, options);
|
|
187
|
+
await this.addContentTypes(zip, model);
|
|
188
|
+
await this.addOfficeRels(zip, model);
|
|
189
|
+
await this.addWorkbookRels(zip, model);
|
|
190
|
+
await this.addWorksheets(zip, model);
|
|
191
|
+
await this.addSharedStrings(zip, model);
|
|
192
|
+
this.addDrawings(zip, model);
|
|
193
|
+
this.addTables(zip, model);
|
|
194
|
+
this.addPivotTables(zip, model);
|
|
195
|
+
await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
|
|
196
|
+
await this.addMedia(zip, model);
|
|
197
|
+
await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
|
|
198
|
+
await this.addWorkbook(zip, model);
|
|
199
|
+
return this._finalize(zip);
|
|
200
|
+
}
|
|
201
|
+
// ===========================================================================
|
|
202
|
+
// Node.js specific: Buffer operations
|
|
203
|
+
// ===========================================================================
|
|
482
204
|
async load(data, options) {
|
|
483
205
|
let buffer;
|
|
484
|
-
// Validate input type
|
|
485
206
|
if (!data ||
|
|
486
207
|
(typeof data === "object" &&
|
|
487
208
|
!Buffer.isBuffer(data) &&
|
|
@@ -495,299 +216,18 @@ class XLSX {
|
|
|
495
216
|
else {
|
|
496
217
|
buffer = data;
|
|
497
218
|
}
|
|
498
|
-
|
|
499
|
-
const PassThroughStream = stream_1.PassThrough;
|
|
500
|
-
const stream = new PassThroughStream();
|
|
219
|
+
const stream = new stream_1.PassThrough();
|
|
501
220
|
stream.end(buffer);
|
|
502
221
|
return this.read(stream, options);
|
|
503
222
|
}
|
|
504
|
-
async
|
|
505
|
-
const
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
worksheetRels: [],
|
|
509
|
-
themes: {},
|
|
510
|
-
media: [],
|
|
511
|
-
mediaIndex: {},
|
|
512
|
-
drawings: {},
|
|
513
|
-
drawingRels: {},
|
|
514
|
-
comments: {},
|
|
515
|
-
tables: {},
|
|
516
|
-
vmlDrawings: {},
|
|
517
|
-
// Pivot table storage for loaded files
|
|
518
|
-
pivotTables: {},
|
|
519
|
-
pivotTableRels: {},
|
|
520
|
-
pivotCacheDefinitions: {},
|
|
521
|
-
pivotCacheDefinitionRels: {},
|
|
522
|
-
pivotCacheRecords: {}
|
|
523
|
-
};
|
|
524
|
-
// Convert fflate format to JSZip-like structure for compatibility
|
|
525
|
-
const entries = Object.keys(zipData).map(name => ({
|
|
526
|
-
name,
|
|
527
|
-
dir: name.endsWith("/"),
|
|
528
|
-
data: zipData[name]
|
|
529
|
-
}));
|
|
530
|
-
for (const entry of entries) {
|
|
531
|
-
if (!entry.dir) {
|
|
532
|
-
let entryName = entry.name;
|
|
533
|
-
if (entryName[0] === "/") {
|
|
534
|
-
entryName = entryName.substr(1);
|
|
535
|
-
}
|
|
536
|
-
let stream;
|
|
537
|
-
if (entryName.match(/xl\/media\//) ||
|
|
538
|
-
// themes are not parsed as stream
|
|
539
|
-
entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/)) {
|
|
540
|
-
stream = new stream_1.PassThrough();
|
|
541
|
-
stream.end(Buffer.from(entry.data));
|
|
542
|
-
}
|
|
543
|
-
else {
|
|
544
|
-
// use object mode to avoid buffer-string convention
|
|
545
|
-
stream = new stream_1.PassThrough({
|
|
546
|
-
readableObjectMode: true,
|
|
547
|
-
writableObjectMode: true
|
|
548
|
-
});
|
|
549
|
-
const content = (0, utils_js_1.bufferToString)(Buffer.from(entry.data));
|
|
550
|
-
stream.end(content);
|
|
551
|
-
}
|
|
552
|
-
let match;
|
|
553
|
-
match = entryName.match(/xl\/worksheets\/sheet(\d+)[.]xml/);
|
|
554
|
-
if (match) {
|
|
555
|
-
const sheetNo = parseInt(match[1], 10);
|
|
556
|
-
await this._processWorksheetEntry(stream, model, sheetNo, options, entryName);
|
|
557
|
-
}
|
|
558
|
-
else {
|
|
559
|
-
switch (entryName) {
|
|
560
|
-
case "_rels/.rels":
|
|
561
|
-
model.globalRels = await this.parseRels(stream);
|
|
562
|
-
break;
|
|
563
|
-
case "xl/workbook.xml": {
|
|
564
|
-
const workbook = await this.parseWorkbook(stream);
|
|
565
|
-
model.sheets = workbook.sheets;
|
|
566
|
-
model.definedNames = workbook.definedNames;
|
|
567
|
-
model.views = workbook.views;
|
|
568
|
-
model.properties = workbook.properties;
|
|
569
|
-
model.calcProperties = workbook.calcProperties;
|
|
570
|
-
// pivotCaches contains the mapping from rId to cacheId
|
|
571
|
-
// needed for linking pivot tables to their cache data
|
|
572
|
-
model.pivotCaches = workbook.pivotCaches;
|
|
573
|
-
break;
|
|
574
|
-
}
|
|
575
|
-
case "xl/sharedStrings.xml":
|
|
576
|
-
model.sharedStrings = new shared_strings_xform_js_1.SharedStringsXform();
|
|
577
|
-
await model.sharedStrings.parseStream(stream);
|
|
578
|
-
break;
|
|
579
|
-
case "xl/_rels/workbook.xml.rels":
|
|
580
|
-
model.workbookRels = await this.parseRels(stream);
|
|
581
|
-
break;
|
|
582
|
-
case "docProps/app.xml": {
|
|
583
|
-
const appXform = new app_xform_js_1.AppXform();
|
|
584
|
-
const appProperties = await appXform.parseStream(stream);
|
|
585
|
-
model.company = appProperties.company;
|
|
586
|
-
model.manager = appProperties.manager;
|
|
587
|
-
break;
|
|
588
|
-
}
|
|
589
|
-
case "docProps/core.xml": {
|
|
590
|
-
const coreXform = new core_xform_js_1.CoreXform();
|
|
591
|
-
const coreProperties = await coreXform.parseStream(stream);
|
|
592
|
-
Object.assign(model, coreProperties);
|
|
593
|
-
break;
|
|
594
|
-
}
|
|
595
|
-
case "xl/styles.xml":
|
|
596
|
-
model.styles = new styles_xform_js_1.StylesXform();
|
|
597
|
-
await model.styles.parseStream(stream);
|
|
598
|
-
break;
|
|
599
|
-
default: {
|
|
600
|
-
match = entryName.match(/xl\/worksheets\/_rels\/sheet(\d+)[.]xml[.]rels/);
|
|
601
|
-
if (match) {
|
|
602
|
-
const sheetNo = parseInt(match[1], 10);
|
|
603
|
-
await this._processWorksheetRelsEntry(stream, model, sheetNo);
|
|
604
|
-
break;
|
|
605
|
-
}
|
|
606
|
-
match = entryName.match(/xl\/media\/([a-zA-Z0-9]+[.][a-zA-Z0-9]{3,4})$/);
|
|
607
|
-
if (match) {
|
|
608
|
-
await this._processMediaEntry(stream, model, match[1]);
|
|
609
|
-
break;
|
|
610
|
-
}
|
|
611
|
-
match = entryName.match(/xl\/drawings\/(drawing\d+)[.]xml/);
|
|
612
|
-
if (match) {
|
|
613
|
-
await this._processDrawingEntry(stream, model, match[1]);
|
|
614
|
-
break;
|
|
615
|
-
}
|
|
616
|
-
match = entryName.match(/xl\/drawings\/_rels\/(drawing\d+)[.]xml[.]rels/);
|
|
617
|
-
if (match) {
|
|
618
|
-
await this._processDrawingRelsEntry(stream, model, match[1]);
|
|
619
|
-
break;
|
|
620
|
-
}
|
|
621
|
-
match = entryName.match(/xl\/drawings\/(vmlDrawing\d+)[.]vml/);
|
|
622
|
-
if (match) {
|
|
623
|
-
await this._processVmlDrawingEntry(stream, model, match[1]);
|
|
624
|
-
break;
|
|
625
|
-
}
|
|
626
|
-
match = entryName.match(/xl\/comments(\d+)[.]xml/);
|
|
627
|
-
if (match) {
|
|
628
|
-
await this._processCommentEntry(stream, model, `comments${match[1]}`);
|
|
629
|
-
break;
|
|
630
|
-
}
|
|
631
|
-
match = entryName.match(/xl\/tables\/(table\d+)[.]xml/);
|
|
632
|
-
if (match) {
|
|
633
|
-
await this._processTableEntry(stream, model, match[1]);
|
|
634
|
-
break;
|
|
635
|
-
}
|
|
636
|
-
match = entryName.match(/xl\/theme\/([a-zA-Z0-9]+)[.]xml/);
|
|
637
|
-
if (match) {
|
|
638
|
-
await this._processThemeEntry(stream, model, match[1]);
|
|
639
|
-
break;
|
|
640
|
-
}
|
|
641
|
-
// Pivot table files
|
|
642
|
-
match = entryName.match(/xl\/pivotTables\/(pivotTable\d+)[.]xml/);
|
|
643
|
-
if (match) {
|
|
644
|
-
await this._processPivotTableEntry(stream, model, match[1]);
|
|
645
|
-
break;
|
|
646
|
-
}
|
|
647
|
-
match = entryName.match(/xl\/pivotTables\/_rels\/(pivotTable\d+)[.]xml[.]rels/);
|
|
648
|
-
if (match) {
|
|
649
|
-
await this._processPivotTableRelsEntry(stream, model, match[1]);
|
|
650
|
-
break;
|
|
651
|
-
}
|
|
652
|
-
// Pivot cache files
|
|
653
|
-
match = entryName.match(/xl\/pivotCache\/(pivotCacheDefinition\d+)[.]xml/);
|
|
654
|
-
if (match) {
|
|
655
|
-
await this._processPivotCacheDefinitionEntry(stream, model, match[1]);
|
|
656
|
-
break;
|
|
657
|
-
}
|
|
658
|
-
match = entryName.match(/xl\/pivotCache\/_rels\/(pivotCacheDefinition\d+)[.]xml[.]rels/);
|
|
659
|
-
if (match) {
|
|
660
|
-
await this._processPivotCacheDefinitionRelsEntry(stream, model, match[1]);
|
|
661
|
-
break;
|
|
662
|
-
}
|
|
663
|
-
match = entryName.match(/xl\/pivotCache\/(pivotCacheRecords\d+)[.]xml/);
|
|
664
|
-
if (match) {
|
|
665
|
-
await this._processPivotCacheRecordsEntry(stream, model, match[1]);
|
|
666
|
-
break;
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
this.reconcile(model, options);
|
|
674
|
-
// apply model
|
|
675
|
-
this.workbook.model = model;
|
|
676
|
-
return this.workbook;
|
|
677
|
-
}
|
|
678
|
-
// =========================================================================
|
|
679
|
-
// Write
|
|
680
|
-
async addContentTypes(zip, model) {
|
|
681
|
-
const xform = new content_types_xform_js_1.ContentTypesXform();
|
|
682
|
-
const xml = xform.toXml(model);
|
|
683
|
-
zip.append(xml, { name: "[Content_Types].xml" });
|
|
684
|
-
}
|
|
685
|
-
async addApp(zip, model) {
|
|
686
|
-
const xform = new app_xform_js_1.AppXform();
|
|
687
|
-
const xml = xform.toXml(model);
|
|
688
|
-
zip.append(xml, { name: "docProps/app.xml" });
|
|
689
|
-
}
|
|
690
|
-
async addCore(zip, model) {
|
|
691
|
-
const xform = new core_xform_js_1.CoreXform();
|
|
692
|
-
zip.append(xform.toXml(model), { name: "docProps/core.xml" });
|
|
693
|
-
}
|
|
694
|
-
async addThemes(zip, model) {
|
|
695
|
-
const themes = model.themes || { theme1: theme1_js_1.theme1Xml };
|
|
696
|
-
Object.keys(themes).forEach(name => {
|
|
697
|
-
const xml = themes[name];
|
|
698
|
-
const path = `xl/theme/${name}.xml`;
|
|
699
|
-
zip.append(xml, { name: path });
|
|
700
|
-
});
|
|
701
|
-
}
|
|
702
|
-
async addOfficeRels(zip, _model) {
|
|
703
|
-
const xform = new relationships_xform_js_1.RelationshipsXform();
|
|
704
|
-
const xml = xform.toXml([
|
|
705
|
-
{ Id: "rId1", Type: XLSX.RelType.OfficeDocument, Target: "xl/workbook.xml" },
|
|
706
|
-
{ Id: "rId2", Type: XLSX.RelType.CoreProperties, Target: "docProps/core.xml" },
|
|
707
|
-
{ Id: "rId3", Type: XLSX.RelType.ExtenderProperties, Target: "docProps/app.xml" }
|
|
708
|
-
]);
|
|
709
|
-
zip.append(xml, { name: "_rels/.rels" });
|
|
710
|
-
}
|
|
711
|
-
async addWorkbookRels(zip, model) {
|
|
712
|
-
let count = 1;
|
|
713
|
-
const relationships = [
|
|
714
|
-
{ Id: `rId${count++}`, Type: XLSX.RelType.Styles, Target: "styles.xml" },
|
|
715
|
-
{ Id: `rId${count++}`, Type: XLSX.RelType.Theme, Target: "theme/theme1.xml" }
|
|
716
|
-
];
|
|
717
|
-
if (model.sharedStrings.count) {
|
|
718
|
-
relationships.push({
|
|
719
|
-
Id: `rId${count++}`,
|
|
720
|
-
Type: XLSX.RelType.SharedStrings,
|
|
721
|
-
Target: "sharedStrings.xml"
|
|
722
|
-
});
|
|
723
|
-
}
|
|
724
|
-
// Add relationships for all pivot tables
|
|
725
|
-
(model.pivotTables || []).forEach((pivotTable) => {
|
|
726
|
-
pivotTable.rId = `rId${count++}`;
|
|
727
|
-
relationships.push({
|
|
728
|
-
Id: pivotTable.rId,
|
|
729
|
-
Type: XLSX.RelType.PivotCacheDefinition,
|
|
730
|
-
Target: `pivotCache/pivotCacheDefinition${pivotTable.tableNumber}.xml`
|
|
731
|
-
});
|
|
732
|
-
});
|
|
733
|
-
model.worksheets.forEach((worksheet, index) => {
|
|
734
|
-
// Use sequential index (1-based) for file naming, not worksheet.id (sheetId)
|
|
735
|
-
// sheetId can be non-sequential (e.g., 1, 3, 5) which would create gaps in filenames
|
|
736
|
-
worksheet.rId = `rId${count++}`;
|
|
737
|
-
worksheet.fileIndex = index + 1; // Store for use in addWorksheets and content types
|
|
738
|
-
relationships.push({
|
|
739
|
-
Id: worksheet.rId,
|
|
740
|
-
Type: XLSX.RelType.Worksheet,
|
|
741
|
-
Target: `worksheets/sheet${worksheet.fileIndex}.xml`
|
|
742
|
-
});
|
|
743
|
-
});
|
|
744
|
-
const xform = new relationships_xform_js_1.RelationshipsXform();
|
|
745
|
-
const xml = xform.toXml(relationships);
|
|
746
|
-
zip.append(xml, { name: "xl/_rels/workbook.xml.rels" });
|
|
747
|
-
}
|
|
748
|
-
async addSharedStrings(zip, model) {
|
|
749
|
-
if (model.sharedStrings && model.sharedStrings.count) {
|
|
750
|
-
zip.append(model.sharedStrings.xml, { name: "xl/sharedStrings.xml" });
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
async addStyles(zip, model) {
|
|
754
|
-
const { xml } = model.styles;
|
|
755
|
-
if (xml) {
|
|
756
|
-
zip.append(xml, { name: "xl/styles.xml" });
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
async addWorkbook(zip, model) {
|
|
760
|
-
const xform = new workbook_xform_js_1.WorkbookXform();
|
|
761
|
-
zip.append(xform.toXml(model), { name: "xl/workbook.xml" });
|
|
762
|
-
}
|
|
763
|
-
async addWorksheets(zip, model) {
|
|
764
|
-
// preparation phase
|
|
765
|
-
const worksheetXform = new worksheet_xform_js_1.WorkSheetXform();
|
|
766
|
-
const relationshipsXform = new relationships_xform_js_1.RelationshipsXform();
|
|
767
|
-
const commentsXform = new comments_xform_js_1.CommentsXform();
|
|
768
|
-
const vmlNotesXform = new vml_notes_xform_js_1.VmlNotesXform();
|
|
769
|
-
// write sheets
|
|
770
|
-
model.worksheets.forEach((worksheet, index) => {
|
|
771
|
-
// Use fileIndex if set by addWorkbookRels, otherwise use index + 1
|
|
772
|
-
const fileIndex = worksheet.fileIndex || index + 1;
|
|
773
|
-
let xmlStream = new xml_stream_js_1.XmlStream();
|
|
774
|
-
worksheetXform.render(xmlStream, worksheet);
|
|
775
|
-
zip.append(xmlStream.xml, { name: `xl/worksheets/sheet${fileIndex}.xml` });
|
|
776
|
-
if (worksheet.rels && worksheet.rels.length) {
|
|
777
|
-
xmlStream = new xml_stream_js_1.XmlStream();
|
|
778
|
-
relationshipsXform.render(xmlStream, worksheet.rels);
|
|
779
|
-
zip.append(xmlStream.xml, { name: `xl/worksheets/_rels/sheet${fileIndex}.xml.rels` });
|
|
780
|
-
}
|
|
781
|
-
if (worksheet.comments.length > 0) {
|
|
782
|
-
xmlStream = new xml_stream_js_1.XmlStream();
|
|
783
|
-
commentsXform.render(xmlStream, worksheet);
|
|
784
|
-
zip.append(xmlStream.xml, { name: `xl/comments${fileIndex}.xml` });
|
|
785
|
-
xmlStream = new xml_stream_js_1.XmlStream();
|
|
786
|
-
vmlNotesXform.render(xmlStream, worksheet);
|
|
787
|
-
zip.append(xmlStream.xml, { name: `xl/drawings/vmlDrawing${fileIndex}.vml` });
|
|
788
|
-
}
|
|
789
|
-
});
|
|
223
|
+
async writeBuffer(options) {
|
|
224
|
+
const stream = new stream_buf_1.StreamBuf();
|
|
225
|
+
await this.write(stream, options);
|
|
226
|
+
return stream.read();
|
|
790
227
|
}
|
|
228
|
+
// ===========================================================================
|
|
229
|
+
// Node.js specific: Media handling with file support
|
|
230
|
+
// ===========================================================================
|
|
791
231
|
async addMedia(zip, model) {
|
|
792
232
|
await Promise.all(model.media.map(async (medium) => {
|
|
793
233
|
if (medium.type === "image") {
|
|
@@ -808,187 +248,5 @@ class XLSX {
|
|
|
808
248
|
throw new Error("Unsupported media");
|
|
809
249
|
}));
|
|
810
250
|
}
|
|
811
|
-
addDrawings(zip, model) {
|
|
812
|
-
const drawingXform = new drawing_xform_js_1.DrawingXform();
|
|
813
|
-
const relsXform = new relationships_xform_js_1.RelationshipsXform();
|
|
814
|
-
model.worksheets.forEach((worksheet) => {
|
|
815
|
-
const { drawing } = worksheet;
|
|
816
|
-
if (drawing) {
|
|
817
|
-
drawingXform.prepare(drawing);
|
|
818
|
-
let xml = drawingXform.toXml(drawing);
|
|
819
|
-
zip.append(xml, { name: `xl/drawings/${drawing.name}.xml` });
|
|
820
|
-
xml = relsXform.toXml(drawing.rels);
|
|
821
|
-
zip.append(xml, { name: `xl/drawings/_rels/${drawing.name}.xml.rels` });
|
|
822
|
-
}
|
|
823
|
-
});
|
|
824
|
-
}
|
|
825
|
-
addTables(zip, model) {
|
|
826
|
-
const tableXform = new table_xform_js_1.TableXform();
|
|
827
|
-
model.worksheets.forEach((worksheet) => {
|
|
828
|
-
const { tables } = worksheet;
|
|
829
|
-
tables.forEach((table) => {
|
|
830
|
-
tableXform.prepare(table, {});
|
|
831
|
-
const tableXml = tableXform.toXml(table);
|
|
832
|
-
zip.append(tableXml, { name: `xl/tables/${table.target}` });
|
|
833
|
-
});
|
|
834
|
-
});
|
|
835
|
-
}
|
|
836
|
-
addPivotTables(zip, model) {
|
|
837
|
-
if (!model.pivotTables.length) {
|
|
838
|
-
return;
|
|
839
|
-
}
|
|
840
|
-
const pivotCacheRecordsXform = new pivot_cache_records_xform_js_1.PivotCacheRecordsXform();
|
|
841
|
-
const pivotCacheDefinitionXform = new pivot_cache_definition_xform_js_1.PivotCacheDefinitionXform();
|
|
842
|
-
const pivotTableXform = new pivot_table_xform_js_1.PivotTableXform();
|
|
843
|
-
const relsXform = new relationships_xform_js_1.RelationshipsXform();
|
|
844
|
-
// Generate files for each pivot table
|
|
845
|
-
model.pivotTables.forEach((pivotTable) => {
|
|
846
|
-
const n = pivotTable.tableNumber;
|
|
847
|
-
// For loaded pivot tables, use the stored cache data
|
|
848
|
-
// For new pivot tables, use the source data
|
|
849
|
-
const isLoaded = pivotTable.isLoaded;
|
|
850
|
-
if (isLoaded) {
|
|
851
|
-
// Loaded pivot table - use stored cache definition and records
|
|
852
|
-
if (pivotTable.cacheDefinition) {
|
|
853
|
-
const xml = pivotCacheDefinitionXform.toXml(pivotTable.cacheDefinition);
|
|
854
|
-
zip.append(xml, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
|
|
855
|
-
}
|
|
856
|
-
if (pivotTable.cacheRecords) {
|
|
857
|
-
const xml = pivotCacheRecordsXform.toXml(pivotTable.cacheRecords);
|
|
858
|
-
zip.append(xml, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
else {
|
|
862
|
-
// New pivot table - generate from source
|
|
863
|
-
let xml = pivotCacheRecordsXform.toXml(pivotTable);
|
|
864
|
-
zip.append(xml, { name: `xl/pivotCache/pivotCacheRecords${n}.xml` });
|
|
865
|
-
xml = pivotCacheDefinitionXform.toXml(pivotTable);
|
|
866
|
-
zip.append(xml, { name: `xl/pivotCache/pivotCacheDefinition${n}.xml` });
|
|
867
|
-
}
|
|
868
|
-
// pivot cache definition rels (same for both)
|
|
869
|
-
let xml = relsXform.toXml([
|
|
870
|
-
{
|
|
871
|
-
Id: "rId1",
|
|
872
|
-
Type: XLSX.RelType.PivotCacheRecords,
|
|
873
|
-
Target: `pivotCacheRecords${n}.xml`
|
|
874
|
-
}
|
|
875
|
-
]);
|
|
876
|
-
zip.append(xml, { name: `xl/pivotCache/_rels/pivotCacheDefinition${n}.xml.rels` });
|
|
877
|
-
// pivot table
|
|
878
|
-
xml = pivotTableXform.toXml(pivotTable);
|
|
879
|
-
zip.append(xml, { name: `xl/pivotTables/pivotTable${n}.xml` });
|
|
880
|
-
xml = relsXform.toXml([
|
|
881
|
-
{
|
|
882
|
-
Id: "rId1",
|
|
883
|
-
Type: XLSX.RelType.PivotCacheDefinition,
|
|
884
|
-
Target: `../pivotCache/pivotCacheDefinition${n}.xml`
|
|
885
|
-
}
|
|
886
|
-
]);
|
|
887
|
-
zip.append(xml, { name: `xl/pivotTables/_rels/pivotTable${n}.xml.rels` });
|
|
888
|
-
});
|
|
889
|
-
}
|
|
890
|
-
_finalize(zip) {
|
|
891
|
-
return new Promise((resolve, reject) => {
|
|
892
|
-
zip.on("finish", () => {
|
|
893
|
-
resolve(this);
|
|
894
|
-
});
|
|
895
|
-
zip.on("error", reject);
|
|
896
|
-
zip.finalize();
|
|
897
|
-
});
|
|
898
|
-
}
|
|
899
|
-
prepareModel(model, options) {
|
|
900
|
-
// ensure following properties have sane values
|
|
901
|
-
model.creator = model.creator || "ExcelTS";
|
|
902
|
-
model.lastModifiedBy = model.lastModifiedBy || "ExcelTS";
|
|
903
|
-
model.created = model.created || new Date();
|
|
904
|
-
model.modified = model.modified || new Date();
|
|
905
|
-
model.useSharedStrings =
|
|
906
|
-
options.useSharedStrings !== undefined ? options.useSharedStrings : true;
|
|
907
|
-
model.useStyles = options.useStyles !== undefined ? options.useStyles : true;
|
|
908
|
-
// Manage the shared strings
|
|
909
|
-
model.sharedStrings = new shared_strings_xform_js_1.SharedStringsXform();
|
|
910
|
-
// add a style manager to handle cell formats, fonts, etc.
|
|
911
|
-
model.styles = model.useStyles ? new styles_xform_js_1.StylesXform(true) : new styles_xform_js_1.StylesXform.Mock();
|
|
912
|
-
// prepare all of the things before the render
|
|
913
|
-
const workbookXform = new workbook_xform_js_1.WorkbookXform();
|
|
914
|
-
const worksheetXform = new worksheet_xform_js_1.WorkSheetXform();
|
|
915
|
-
workbookXform.prepare(model);
|
|
916
|
-
const worksheetOptions = {
|
|
917
|
-
sharedStrings: model.sharedStrings,
|
|
918
|
-
styles: model.styles,
|
|
919
|
-
date1904: model.properties.date1904,
|
|
920
|
-
drawingsCount: 0,
|
|
921
|
-
media: model.media
|
|
922
|
-
};
|
|
923
|
-
worksheetOptions.drawings = model.drawings = [];
|
|
924
|
-
worksheetOptions.commentRefs = model.commentRefs = [];
|
|
925
|
-
let tableCount = 0;
|
|
926
|
-
model.tables = [];
|
|
927
|
-
model.worksheets.forEach((worksheet) => {
|
|
928
|
-
// assign unique filenames to tables
|
|
929
|
-
worksheet.tables.forEach((table) => {
|
|
930
|
-
tableCount++;
|
|
931
|
-
table.target = `table${tableCount}.xml`;
|
|
932
|
-
table.id = tableCount;
|
|
933
|
-
model.tables.push(table);
|
|
934
|
-
});
|
|
935
|
-
worksheetXform.prepare(worksheet, worksheetOptions);
|
|
936
|
-
});
|
|
937
|
-
// TODO: workbook drawing list
|
|
938
|
-
}
|
|
939
|
-
async write(stream, options) {
|
|
940
|
-
options = options || {};
|
|
941
|
-
const { model } = this.workbook;
|
|
942
|
-
const zip = new zip_stream_js_1.ZipWriter(options.zip);
|
|
943
|
-
zip.pipe(stream);
|
|
944
|
-
this.prepareModel(model, options);
|
|
945
|
-
// render
|
|
946
|
-
await this.addContentTypes(zip, model);
|
|
947
|
-
await this.addOfficeRels(zip, model);
|
|
948
|
-
await this.addWorkbookRels(zip, model);
|
|
949
|
-
await this.addWorksheets(zip, model);
|
|
950
|
-
await this.addSharedStrings(zip, model); // always after worksheets
|
|
951
|
-
this.addDrawings(zip, model);
|
|
952
|
-
this.addTables(zip, model);
|
|
953
|
-
this.addPivotTables(zip, model);
|
|
954
|
-
await Promise.all([this.addThemes(zip, model), this.addStyles(zip, model)]);
|
|
955
|
-
await this.addMedia(zip, model);
|
|
956
|
-
await Promise.all([this.addApp(zip, model), this.addCore(zip, model)]);
|
|
957
|
-
await this.addWorkbook(zip, model);
|
|
958
|
-
return this._finalize(zip);
|
|
959
|
-
}
|
|
960
|
-
writeFile(filename, options) {
|
|
961
|
-
const stream = fs_1.default.createWriteStream(filename);
|
|
962
|
-
return new Promise((resolve, reject) => {
|
|
963
|
-
const cleanup = () => {
|
|
964
|
-
stream.removeListener("finish", onFinish);
|
|
965
|
-
stream.removeListener("error", onError);
|
|
966
|
-
};
|
|
967
|
-
const onFinish = () => {
|
|
968
|
-
cleanup();
|
|
969
|
-
resolve();
|
|
970
|
-
};
|
|
971
|
-
const onError = (error) => {
|
|
972
|
-
cleanup();
|
|
973
|
-
reject(error);
|
|
974
|
-
};
|
|
975
|
-
stream.once("finish", onFinish);
|
|
976
|
-
stream.on("error", onError);
|
|
977
|
-
this.write(stream, options)
|
|
978
|
-
.then(() => {
|
|
979
|
-
stream.end();
|
|
980
|
-
})
|
|
981
|
-
.catch(err => {
|
|
982
|
-
cleanup();
|
|
983
|
-
reject(err);
|
|
984
|
-
});
|
|
985
|
-
});
|
|
986
|
-
}
|
|
987
|
-
async writeBuffer(options) {
|
|
988
|
-
const stream = new stream_buf_js_1.StreamBuf();
|
|
989
|
-
await this.write(stream, options);
|
|
990
|
-
return stream.read();
|
|
991
|
-
}
|
|
992
251
|
}
|
|
993
252
|
exports.XLSX = XLSX;
|
|
994
|
-
XLSX.RelType = rel_type_js_1.RelType;
|