@rowsncolumns/toolkit 24.4.1
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/LICENSE.md +100 -0
- package/Readme.md +27 -0
- package/dist/cjs/autofilter-condition.d.ts +43 -0
- package/dist/cjs/autofilter-condition.d.ts.map +1 -0
- package/dist/cjs/autofilter-condition.js +155 -0
- package/dist/cjs/csv-export.d.ts +49 -0
- package/dist/cjs/csv-export.d.ts.map +1 -0
- package/dist/cjs/csv-export.js +142 -0
- package/dist/cjs/csv-import-worker.d.ts +16 -0
- package/dist/cjs/csv-import-worker.d.ts.map +1 -0
- package/dist/cjs/csv-import-worker.js +60 -0
- package/dist/cjs/csv-import.d.ts +38 -0
- package/dist/cjs/csv-import.d.ts.map +1 -0
- package/dist/cjs/csv-import.js +166 -0
- package/dist/cjs/csv-parser/helpers.d.ts +14 -0
- package/dist/cjs/csv-parser/helpers.d.ts.map +1 -0
- package/dist/cjs/csv-parser/helpers.js +145 -0
- package/dist/cjs/csv-parser/types.d.ts +66 -0
- package/dist/cjs/csv-parser/types.d.ts.map +1 -0
- package/dist/cjs/csv-parser/types.js +14 -0
- package/dist/cjs/csv-parser/worker.d.ts +2 -0
- package/dist/cjs/csv-parser/worker.d.ts.map +1 -0
- package/dist/cjs/csv-parser/worker.js +200 -0
- package/dist/cjs/excel-export.d.ts +11 -0
- package/dist/cjs/excel-export.d.ts.map +1 -0
- package/dist/cjs/excel-export.js +22 -0
- package/dist/cjs/excel-import-session.d.ts +51 -0
- package/dist/cjs/excel-import-session.d.ts.map +1 -0
- package/dist/cjs/excel-import-session.js +307 -0
- package/dist/cjs/excel-import-worker.d.ts +7 -0
- package/dist/cjs/excel-import-worker.d.ts.map +1 -0
- package/dist/cjs/excel-import-worker.js +119 -0
- package/dist/cjs/excel-parser/builtin-numfmts.d.ts +24 -0
- package/dist/cjs/excel-parser/builtin-numfmts.d.ts.map +1 -0
- package/dist/cjs/excel-parser/builtin-numfmts.js +63 -0
- package/dist/cjs/excel-parser/cfb-decryptor.d.ts +53 -0
- package/dist/cjs/excel-parser/cfb-decryptor.d.ts.map +1 -0
- package/dist/cjs/excel-parser/cfb-decryptor.js +553 -0
- package/dist/cjs/excel-parser/cfb-encryptor.d.ts +23 -0
- package/dist/cjs/excel-parser/cfb-encryptor.d.ts.map +1 -0
- package/dist/cjs/excel-parser/cfb-encryptor.js +200 -0
- package/dist/cjs/excel-parser/dv-cell-stamp.d.ts +29 -0
- package/dist/cjs/excel-parser/dv-cell-stamp.d.ts.map +1 -0
- package/dist/cjs/excel-parser/dv-cell-stamp.js +239 -0
- package/dist/cjs/excel-parser/helpers.d.ts +28 -0
- package/dist/cjs/excel-parser/helpers.d.ts.map +1 -0
- package/dist/cjs/excel-parser/helpers.js +188 -0
- package/dist/cjs/excel-parser/interface.d.ts +179 -0
- package/dist/cjs/excel-parser/interface.d.ts.map +1 -0
- package/dist/cjs/excel-parser/interface.js +1 -0
- package/dist/cjs/excel-parser/plugins/base/index.d.ts +31 -0
- package/dist/cjs/excel-parser/plugins/base/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/base/index.js +101 -0
- package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
- package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/conditional-formatting.js +488 -0
- package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts +15 -0
- package/dist/cjs/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/data-validations.js +353 -0
- package/dist/cjs/excel-parser/plugins/ods/formula.d.ts +8 -0
- package/dist/cjs/excel-parser/plugins/ods/formula.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/formula.js +82 -0
- package/dist/cjs/excel-parser/plugins/ods/index.d.ts +122 -0
- package/dist/cjs/excel-parser/plugins/ods/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/index.js +3642 -0
- package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts +25 -0
- package/dist/cjs/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/sparklines.js +221 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.d.ts +60 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/styles.js +808 -0
- package/dist/cjs/excel-parser/plugins/ods/types.d.ts +7 -0
- package/dist/cjs/excel-parser/plugins/ods/types.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/ods/types.js +1 -0
- package/dist/cjs/excel-parser/plugins/xls/index.d.ts +5 -0
- package/dist/cjs/excel-parser/plugins/xls/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xls/index.js +19 -0
- package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
- package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/biff-record-reader.js +49 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts +117 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/index.js +2972 -0
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsb/rgce-parser.js +527 -0
- package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts +5 -0
- package/dist/cjs/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsm/index.js +10 -0
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts +60 -0
- package/dist/cjs/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/charts.js +2178 -0
- package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
- package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/conditional-formatting.js +620 -0
- package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
- package/dist/cjs/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/data-validations.js +515 -0
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/drawing.js +941 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +320 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/index.js +6056 -0
- package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
- package/dist/cjs/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/numfmt.js +3 -0
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/pivots.js +342 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/relationships.js +26 -0
- package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
- package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/sheet-views.js +59 -0
- package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +44 -0
- package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/styles.js +1377 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts +50 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/theme.js +150 -0
- package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
- package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/threaded-comments.js +141 -0
- package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
- package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
- package/dist/cjs/excel-parser/plugins/xlsx/value-type-detection.js +407 -0
- package/dist/cjs/excel-parser/registry.d.ts +5 -0
- package/dist/cjs/excel-parser/registry.d.ts.map +1 -0
- package/dist/cjs/excel-parser/registry.js +21 -0
- package/dist/cjs/excel-parser/style-registry.d.ts +51 -0
- package/dist/cjs/excel-parser/style-registry.d.ts.map +1 -0
- package/dist/cjs/excel-parser/style-registry.js +175 -0
- package/dist/cjs/excel-parser/theme-default.d.ts +3 -0
- package/dist/cjs/excel-parser/theme-default.d.ts.map +1 -0
- package/dist/cjs/excel-parser/theme-default.js +19 -0
- package/dist/cjs/excel-parser/types.d.ts +365 -0
- package/dist/cjs/excel-parser/types.d.ts.map +1 -0
- package/dist/cjs/excel-parser/types.js +59 -0
- package/dist/cjs/excel-parser/utils.d.ts +6 -0
- package/dist/cjs/excel-parser/utils.d.ts.map +1 -0
- package/dist/cjs/excel-parser/utils.js +30 -0
- package/dist/cjs/excel-parser/workbook.d.ts +51 -0
- package/dist/cjs/excel-parser/workbook.d.ts.map +1 -0
- package/dist/cjs/excel-parser/workbook.js +317 -0
- package/dist/cjs/excel-parser/worker.d.ts +2 -0
- package/dist/cjs/excel-parser/worker.d.ts.map +1 -0
- package/dist/cjs/excel-parser/worker.js +1149 -0
- package/dist/cjs/excel-parser/zip-parser-streaming.d.ts +13 -0
- package/dist/cjs/excel-parser/zip-parser-streaming.d.ts.map +1 -0
- package/dist/cjs/excel-parser/zip-parser-streaming.js +200 -0
- package/dist/cjs/excel-parser/zip-parser.d.ts +11 -0
- package/dist/cjs/excel-parser/zip-parser.d.ts.map +1 -0
- package/dist/cjs/excel-parser/zip-parser.js +49 -0
- package/dist/cjs/exporter/invalid-data-validation.d.ts +19 -0
- package/dist/cjs/exporter/invalid-data-validation.d.ts.map +1 -0
- package/dist/cjs/exporter/invalid-data-validation.js +39 -0
- package/dist/cjs/exporter/ods/ods-export.d.ts +26 -0
- package/dist/cjs/exporter/ods/ods-export.d.ts.map +1 -0
- package/dist/cjs/exporter/ods/ods-export.js +3714 -0
- package/dist/cjs/exporter/ods/sparkline-builder.d.ts +33 -0
- package/dist/cjs/exporter/ods/sparkline-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/ods/sparkline-builder.js +221 -0
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts +3 -0
- package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/chart-builder.js +1901 -0
- package/dist/cjs/exporter/xlsx/chart-templates.d.ts +1781 -0
- package/dist/cjs/exporter/xlsx/chart-templates.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/chart-templates.js +1798 -0
- package/dist/cjs/exporter/xlsx/future-functions.d.ts +10 -0
- package/dist/cjs/exporter/xlsx/future-functions.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/future-functions.js +264 -0
- package/dist/cjs/exporter/xlsx/pivot-builder.d.ts +58 -0
- package/dist/cjs/exporter/xlsx/pivot-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/pivot-builder.js +277 -0
- package/dist/cjs/exporter/xlsx/power-query-builder.d.ts +26 -0
- package/dist/cjs/exporter/xlsx/power-query-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/power-query-builder.js +306 -0
- package/dist/cjs/exporter/xlsx/slicer-builder.d.ts +11 -0
- package/dist/cjs/exporter/xlsx/slicer-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/slicer-builder.js +87 -0
- package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts +61 -0
- package/dist/cjs/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/sparkline-builder.js +489 -0
- package/dist/cjs/exporter/xlsx/style-builder.d.ts +93 -0
- package/dist/cjs/exporter/xlsx/style-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/style-builder.js +813 -0
- package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
- package/dist/cjs/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/threaded-comments-builder.js +189 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts +121 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -0
- package/dist/cjs/exporter/xlsx/xlsx-export.js +4596 -0
- package/dist/cjs/helpers/theme-xml-generator.d.ts +8 -0
- package/dist/cjs/helpers/theme-xml-generator.d.ts.map +1 -0
- package/dist/cjs/helpers/theme-xml-generator.js +33 -0
- package/dist/cjs/helpers.d.ts +34 -0
- package/dist/cjs/helpers.d.ts.map +1 -0
- package/dist/cjs/helpers.js +189 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +15 -0
- package/dist/cjs/indexed-colors.d.ts +2 -0
- package/dist/cjs/indexed-colors.d.ts.map +1 -0
- package/dist/cjs/indexed-colors.js +75 -0
- package/dist/cjs/ods-export.d.ts +24 -0
- package/dist/cjs/ods-export.d.ts.map +1 -0
- package/dist/cjs/ods-export.js +23 -0
- package/dist/cjs/parse.d.ts +24 -0
- package/dist/cjs/parse.d.ts.map +1 -0
- package/dist/cjs/parse.js +68 -0
- package/dist/cjs/power-query.d.ts +41 -0
- package/dist/cjs/power-query.d.ts.map +1 -0
- package/dist/cjs/power-query.js +22 -0
- package/dist/cjs/server.d.ts +9 -0
- package/dist/cjs/server.d.ts.map +1 -0
- package/dist/cjs/server.js +8 -0
- package/dist/cjs/theme1.d.ts +3 -0
- package/dist/cjs/theme1.d.ts.map +1 -0
- package/dist/cjs/theme1.js +2 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/cjs/types.d.ts +14 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +14 -0
- package/dist/cjs/vitest.config.d.ts +3 -0
- package/dist/cjs/vitest.config.d.ts.map +1 -0
- package/dist/cjs/vitest.config.js +16 -0
- package/dist/esm/autofilter-condition.d.ts +43 -0
- package/dist/esm/autofilter-condition.d.ts.map +1 -0
- package/dist/esm/autofilter-condition.js +145 -0
- package/dist/esm/csv-export.d.ts +49 -0
- package/dist/esm/csv-export.d.ts.map +1 -0
- package/dist/esm/csv-export.js +126 -0
- package/dist/esm/csv-import-worker.d.ts +16 -0
- package/dist/esm/csv-import-worker.d.ts.map +1 -0
- package/dist/esm/csv-import-worker.js +60 -0
- package/dist/esm/csv-import.d.ts +38 -0
- package/dist/esm/csv-import.d.ts.map +1 -0
- package/dist/esm/csv-import.js +132 -0
- package/dist/esm/csv-parser/helpers.d.ts +14 -0
- package/dist/esm/csv-parser/helpers.d.ts.map +1 -0
- package/dist/esm/csv-parser/helpers.js +0 -0
- package/dist/esm/csv-parser/types.d.ts +66 -0
- package/dist/esm/csv-parser/types.d.ts.map +1 -0
- package/dist/esm/csv-parser/types.js +14 -0
- package/dist/esm/csv-parser/worker.d.ts +2 -0
- package/dist/esm/csv-parser/worker.d.ts.map +1 -0
- package/dist/esm/csv-parser/worker.js +154 -0
- package/dist/esm/excel-export.d.ts +11 -0
- package/dist/esm/excel-export.d.ts.map +1 -0
- package/dist/esm/excel-export.js +13 -0
- package/dist/esm/excel-import-session.d.ts +51 -0
- package/dist/esm/excel-import-session.d.ts.map +1 -0
- package/dist/esm/excel-import-session.js +255 -0
- package/dist/esm/excel-import-worker.d.ts +7 -0
- package/dist/esm/excel-import-worker.d.ts.map +1 -0
- package/dist/esm/excel-import-worker.js +116 -0
- package/dist/esm/excel-parser/builtin-numfmts.d.ts +24 -0
- package/dist/esm/excel-parser/builtin-numfmts.d.ts.map +1 -0
- package/dist/esm/excel-parser/builtin-numfmts.js +59 -0
- package/dist/esm/excel-parser/cfb-decryptor.d.ts +53 -0
- package/dist/esm/excel-parser/cfb-decryptor.d.ts.map +1 -0
- package/dist/esm/excel-parser/cfb-decryptor.js +493 -0
- package/dist/esm/excel-parser/cfb-encryptor.d.ts +23 -0
- package/dist/esm/excel-parser/cfb-encryptor.d.ts.map +1 -0
- package/dist/esm/excel-parser/cfb-encryptor.js +181 -0
- package/dist/esm/excel-parser/dv-cell-stamp.d.ts +29 -0
- package/dist/esm/excel-parser/dv-cell-stamp.d.ts.map +1 -0
- package/dist/esm/excel-parser/dv-cell-stamp.js +155 -0
- package/dist/esm/excel-parser/helpers.d.ts +28 -0
- package/dist/esm/excel-parser/helpers.d.ts.map +1 -0
- package/dist/esm/excel-parser/helpers.js +160 -0
- package/dist/esm/excel-parser/interface.d.ts +179 -0
- package/dist/esm/excel-parser/interface.d.ts.map +1 -0
- package/dist/esm/excel-parser/interface.js +1 -0
- package/dist/esm/excel-parser/plugins/base/index.d.ts +31 -0
- package/dist/esm/excel-parser/plugins/base/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/base/index.js +64 -0
- package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts +16 -0
- package/dist/esm/excel-parser/plugins/ods/conditional-formatting.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/conditional-formatting.js +405 -0
- package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts +15 -0
- package/dist/esm/excel-parser/plugins/ods/data-validations.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/data-validations.js +331 -0
- package/dist/esm/excel-parser/plugins/ods/formula.d.ts +8 -0
- package/dist/esm/excel-parser/plugins/ods/formula.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/formula.js +82 -0
- package/dist/esm/excel-parser/plugins/ods/index.d.ts +122 -0
- package/dist/esm/excel-parser/plugins/ods/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/index.js +2896 -0
- package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts +25 -0
- package/dist/esm/excel-parser/plugins/ods/sparklines.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/sparklines.js +188 -0
- package/dist/esm/excel-parser/plugins/ods/styles.d.ts +60 -0
- package/dist/esm/excel-parser/plugins/ods/styles.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/styles.js +732 -0
- package/dist/esm/excel-parser/plugins/ods/types.d.ts +7 -0
- package/dist/esm/excel-parser/plugins/ods/types.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/ods/types.js +1 -0
- package/dist/esm/excel-parser/plugins/xls/index.d.ts +5 -0
- package/dist/esm/excel-parser/plugins/xls/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xls/index.js +7 -0
- package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts +13 -0
- package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/biff-record-reader.js +48 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts +117 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/index.js +2339 -0
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts +18 -0
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsb/rgce-parser.js +522 -0
- package/dist/esm/excel-parser/plugins/xlsm/index.d.ts +5 -0
- package/dist/esm/excel-parser/plugins/xlsm/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsm/index.js +6 -0
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts +60 -0
- package/dist/esm/excel-parser/plugins/xlsx/charts.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/charts.js +2036 -0
- package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts +18 -0
- package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/conditional-formatting.js +621 -0
- package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts +4 -0
- package/dist/esm/excel-parser/plugins/xlsx/data-validations.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/data-validations.js +493 -0
- package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts +39 -0
- package/dist/esm/excel-parser/plugins/xlsx/drawing.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/drawing.js +905 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +320 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/index.js +4654 -0
- package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts +2 -0
- package/dist/esm/excel-parser/plugins/xlsx/numfmt.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/numfmt.js +3 -0
- package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts +40 -0
- package/dist/esm/excel-parser/plugins/xlsx/pivots.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/pivots.js +254 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts +8 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/relationships.js +13 -0
- package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts +26 -0
- package/dist/esm/excel-parser/plugins/xlsx/sheet-views.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/sheet-views.js +64 -0
- package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +44 -0
- package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/styles.js +1365 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts +50 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/theme.js +127 -0
- package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts +47 -0
- package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/threaded-comments.js +103 -0
- package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts +44 -0
- package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.d.ts.map +1 -0
- package/dist/esm/excel-parser/plugins/xlsx/value-type-detection.js +399 -0
- package/dist/esm/excel-parser/registry.d.ts +5 -0
- package/dist/esm/excel-parser/registry.d.ts.map +1 -0
- package/dist/esm/excel-parser/registry.js +20 -0
- package/dist/esm/excel-parser/style-registry.d.ts +51 -0
- package/dist/esm/excel-parser/style-registry.d.ts.map +1 -0
- package/dist/esm/excel-parser/style-registry.js +163 -0
- package/dist/esm/excel-parser/theme-default.d.ts +3 -0
- package/dist/esm/excel-parser/theme-default.d.ts.map +1 -0
- package/dist/esm/excel-parser/theme-default.js +19 -0
- package/dist/esm/excel-parser/types.d.ts +365 -0
- package/dist/esm/excel-parser/types.d.ts.map +1 -0
- package/dist/esm/excel-parser/types.js +59 -0
- package/dist/esm/excel-parser/utils.d.ts +6 -0
- package/dist/esm/excel-parser/utils.d.ts.map +1 -0
- package/dist/esm/excel-parser/utils.js +25 -0
- package/dist/esm/excel-parser/workbook.d.ts +51 -0
- package/dist/esm/excel-parser/workbook.d.ts.map +1 -0
- package/dist/esm/excel-parser/workbook.js +192 -0
- package/dist/esm/excel-parser/worker.d.ts +2 -0
- package/dist/esm/excel-parser/worker.d.ts.map +1 -0
- package/dist/esm/excel-parser/worker.js +862 -0
- package/dist/esm/excel-parser/zip-parser-streaming.d.ts +13 -0
- package/dist/esm/excel-parser/zip-parser-streaming.d.ts.map +1 -0
- package/dist/esm/excel-parser/zip-parser-streaming.js +119 -0
- package/dist/esm/excel-parser/zip-parser.d.ts +11 -0
- package/dist/esm/excel-parser/zip-parser.d.ts.map +1 -0
- package/dist/esm/excel-parser/zip-parser.js +43 -0
- package/dist/esm/exporter/invalid-data-validation.d.ts +19 -0
- package/dist/esm/exporter/invalid-data-validation.d.ts.map +1 -0
- package/dist/esm/exporter/invalid-data-validation.js +37 -0
- package/dist/esm/exporter/ods/ods-export.d.ts +26 -0
- package/dist/esm/exporter/ods/ods-export.d.ts.map +1 -0
- package/dist/esm/exporter/ods/ods-export.js +3238 -0
- package/dist/esm/exporter/ods/sparkline-builder.d.ts +33 -0
- package/dist/esm/exporter/ods/sparkline-builder.d.ts.map +1 -0
- package/dist/esm/exporter/ods/sparkline-builder.js +165 -0
- package/dist/esm/exporter/xlsx/chart-builder.d.ts +3 -0
- package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/chart-builder.js +1805 -0
- package/dist/esm/exporter/xlsx/chart-templates.d.ts +1781 -0
- package/dist/esm/exporter/xlsx/chart-templates.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/chart-templates.js +1798 -0
- package/dist/esm/exporter/xlsx/future-functions.d.ts +10 -0
- package/dist/esm/exporter/xlsx/future-functions.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/future-functions.js +264 -0
- package/dist/esm/exporter/xlsx/pivot-builder.d.ts +58 -0
- package/dist/esm/exporter/xlsx/pivot-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/pivot-builder.js +230 -0
- package/dist/esm/exporter/xlsx/power-query-builder.d.ts +26 -0
- package/dist/esm/exporter/xlsx/power-query-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/power-query-builder.js +257 -0
- package/dist/esm/exporter/xlsx/slicer-builder.d.ts +11 -0
- package/dist/esm/exporter/xlsx/slicer-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/slicer-builder.js +84 -0
- package/dist/esm/exporter/xlsx/sparkline-builder.d.ts +61 -0
- package/dist/esm/exporter/xlsx/sparkline-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/sparkline-builder.js +437 -0
- package/dist/esm/exporter/xlsx/style-builder.d.ts +93 -0
- package/dist/esm/exporter/xlsx/style-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/style-builder.js +795 -0
- package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts +58 -0
- package/dist/esm/exporter/xlsx/threaded-comments-builder.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/threaded-comments-builder.js +175 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts +121 -0
- package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -0
- package/dist/esm/exporter/xlsx/xlsx-export.js +4062 -0
- package/dist/esm/helpers/theme-xml-generator.d.ts +8 -0
- package/dist/esm/helpers/theme-xml-generator.d.ts.map +1 -0
- package/dist/esm/helpers/theme-xml-generator.js +33 -0
- package/dist/esm/helpers.d.ts +34 -0
- package/dist/esm/helpers.d.ts.map +1 -0
- package/dist/esm/helpers.js +182 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/indexed-colors.d.ts +2 -0
- package/dist/esm/indexed-colors.d.ts.map +1 -0
- package/dist/esm/indexed-colors.js +75 -0
- package/dist/esm/ods-export.d.ts +24 -0
- package/dist/esm/ods-export.d.ts.map +1 -0
- package/dist/esm/ods-export.js +12 -0
- package/dist/esm/parse.d.ts +24 -0
- package/dist/esm/parse.d.ts.map +1 -0
- package/dist/esm/parse.js +55 -0
- package/dist/esm/power-query.d.ts +41 -0
- package/dist/esm/power-query.d.ts.map +1 -0
- package/dist/esm/power-query.js +19 -0
- package/dist/esm/server.d.ts +9 -0
- package/dist/esm/server.d.ts.map +1 -0
- package/dist/esm/server.js +8 -0
- package/dist/esm/theme1.d.ts +3 -0
- package/dist/esm/theme1.d.ts.map +1 -0
- package/dist/esm/theme1.js +2 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/esm/types.d.ts +14 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +14 -0
- package/dist/esm/vitest.config.d.ts +3 -0
- package/dist/esm/vitest.config.d.ts.map +1 -0
- package/dist/esm/vitest.config.js +16 -0
- package/package.json +62 -0
- package/xlsx.d.ts +52 -0
|
@@ -0,0 +1,862 @@
|
|
|
1
|
+
import { canonicalizeRichSharedString, contentHash } from "@rowsncolumns/utils";
|
|
2
|
+
import { CFBDecryptor, detectCfbContainerKind, LEGACY_XLS_UNSUPPORTED_MESSAGE, } from "./cfb-decryptor";
|
|
3
|
+
import { readExcelFile } from "./helpers";
|
|
4
|
+
import { RequestType, ResponseType } from "./types";
|
|
5
|
+
import { delay } from "./utils";
|
|
6
|
+
import { WorkBook } from "./workbook";
|
|
7
|
+
const workbook = new WorkBook();
|
|
8
|
+
const queuedRowAcks = [];
|
|
9
|
+
let pendingRowAck = null;
|
|
10
|
+
// Shared-string hash mapping. Cells emitted by the plugin layer reference the
|
|
11
|
+
// source SST by numeric index (`ss: "5"`). The worker rewrites those refs to
|
|
12
|
+
// stable content-hash ids before posting to the host so the wire format
|
|
13
|
+
// matches the CSV worker and the host's Map keys are session-stable.
|
|
14
|
+
let sharedStringHashIds = [];
|
|
15
|
+
let sharedStringHashByValue = new Map();
|
|
16
|
+
let sharedStringNextHashIndex = 0;
|
|
17
|
+
const resetSharedStringHashState = () => {
|
|
18
|
+
sharedStringHashIds = [];
|
|
19
|
+
sharedStringHashByValue = new Map();
|
|
20
|
+
sharedStringNextHashIndex = 0;
|
|
21
|
+
};
|
|
22
|
+
const ensureSharedStringHashIds = (sst, richRuns) => {
|
|
23
|
+
if (!sst)
|
|
24
|
+
return;
|
|
25
|
+
for (let i = sharedStringNextHashIndex; i < sst.length; i += 1) {
|
|
26
|
+
const value = sst[i] ?? "";
|
|
27
|
+
const runs = richRuns?.get(i);
|
|
28
|
+
// Plain entries hash text. Rich entries hash the canonical (text + runs)
|
|
29
|
+
// form so two SST slots with the same text but different runs get
|
|
30
|
+
// different ids (the bug was both collapsing to contentHash(text)), and
|
|
31
|
+
// a plain "abc" never collides with a rich `{ text: "abc", runs }`.
|
|
32
|
+
const hashInput = runs && runs.length > 0
|
|
33
|
+
? canonicalizeRichSharedString(value, runs)
|
|
34
|
+
: value;
|
|
35
|
+
let id = contentHash(hashInput);
|
|
36
|
+
let suffix = 0;
|
|
37
|
+
while (sharedStringHashByValue.has(id) &&
|
|
38
|
+
sharedStringHashByValue.get(id) !== hashInput) {
|
|
39
|
+
suffix += 1;
|
|
40
|
+
id = contentHash(`${hashInput} ${suffix}`);
|
|
41
|
+
}
|
|
42
|
+
if (!sharedStringHashByValue.has(id)) {
|
|
43
|
+
sharedStringHashByValue.set(id, hashInput);
|
|
44
|
+
}
|
|
45
|
+
sharedStringHashIds.push(id);
|
|
46
|
+
}
|
|
47
|
+
sharedStringNextHashIndex = sst.length;
|
|
48
|
+
};
|
|
49
|
+
const remapRowCells = (rows) => {
|
|
50
|
+
if (!rows)
|
|
51
|
+
return;
|
|
52
|
+
for (const row of rows) {
|
|
53
|
+
const values = row?.values;
|
|
54
|
+
if (!values)
|
|
55
|
+
continue;
|
|
56
|
+
for (const cell of values) {
|
|
57
|
+
if (cell && typeof cell.ss === "string") {
|
|
58
|
+
const idx = Number(cell.ss);
|
|
59
|
+
if (Number.isInteger(idx) &&
|
|
60
|
+
idx >= 0 &&
|
|
61
|
+
idx < sharedStringHashIds.length) {
|
|
62
|
+
cell.ss = sharedStringHashIds[idx];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const buildSstValue = (text, runs) => {
|
|
69
|
+
if (runs && runs.length > 0) {
|
|
70
|
+
return { text: text ?? "", runs };
|
|
71
|
+
}
|
|
72
|
+
return text ?? "";
|
|
73
|
+
};
|
|
74
|
+
const buildSstEntries = (sst, richRuns) => {
|
|
75
|
+
if (!sst)
|
|
76
|
+
return [];
|
|
77
|
+
ensureSharedStringHashIds(sst, richRuns);
|
|
78
|
+
const entries = new Array(sst.length);
|
|
79
|
+
for (let i = 0; i < sst.length; i += 1) {
|
|
80
|
+
entries[i] = [sharedStringHashIds[i], buildSstValue(sst[i], richRuns?.get(i))];
|
|
81
|
+
}
|
|
82
|
+
return entries;
|
|
83
|
+
};
|
|
84
|
+
const buildSstSlice = (sst, start, richRuns) => {
|
|
85
|
+
ensureSharedStringHashIds(sst, richRuns);
|
|
86
|
+
const out = [];
|
|
87
|
+
for (let i = start; i < sst.length; i += 1) {
|
|
88
|
+
out.push([sharedStringHashIds[i], buildSstValue(sst[i], richRuns?.get(i))]);
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
};
|
|
92
|
+
// Store file for password retry
|
|
93
|
+
let currentFile = null;
|
|
94
|
+
let currentFileName = null;
|
|
95
|
+
let currentMinRowCount;
|
|
96
|
+
let currentMinColumnCount;
|
|
97
|
+
const isIncorrectPasswordError = (error) => {
|
|
98
|
+
const message = error.message.toLowerCase();
|
|
99
|
+
return (message.includes("wrong password") ||
|
|
100
|
+
message.includes("invalid password") ||
|
|
101
|
+
message.includes("bad password") ||
|
|
102
|
+
message.includes("incorrect password"));
|
|
103
|
+
};
|
|
104
|
+
const isEncryptedArchiveError = (error) => {
|
|
105
|
+
const message = error.message.toLowerCase();
|
|
106
|
+
return (message.includes("encrypted") ||
|
|
107
|
+
message.includes("decrypt") ||
|
|
108
|
+
message.includes("password required") ||
|
|
109
|
+
message.includes("unsupported_ooxml_encryption") ||
|
|
110
|
+
message.includes("end of central directory"));
|
|
111
|
+
};
|
|
112
|
+
const CFB_SIGNATURE = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];
|
|
113
|
+
const isCFBFile = async (source) => {
|
|
114
|
+
let header;
|
|
115
|
+
if (source instanceof File) {
|
|
116
|
+
const buffer = await source.slice(0, CFB_SIGNATURE.length).arrayBuffer();
|
|
117
|
+
header = new Uint8Array(buffer);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
header = new Uint8Array(source, 0, CFB_SIGNATURE.length);
|
|
121
|
+
}
|
|
122
|
+
if (header.length < CFB_SIGNATURE.length) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return CFB_SIGNATURE.every((value, index) => header[index] === value);
|
|
126
|
+
};
|
|
127
|
+
const isSameAck = (a, b) => a.sheetId === b.sheetId &&
|
|
128
|
+
a.chunkIndex === b.chunkIndex &&
|
|
129
|
+
(a.requestId ?? null) === (b.requestId ?? null);
|
|
130
|
+
const resolveRowAck = (ack) => {
|
|
131
|
+
if (pendingRowAck && isSameAck(pendingRowAck.key, ack)) {
|
|
132
|
+
const { resolve } = pendingRowAck;
|
|
133
|
+
pendingRowAck = null;
|
|
134
|
+
resolve();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
queuedRowAcks.push(ack);
|
|
138
|
+
};
|
|
139
|
+
const waitForRowAck = async (key) => {
|
|
140
|
+
const queuedIndex = queuedRowAcks.findIndex((ack) => isSameAck(ack, key));
|
|
141
|
+
if (queuedIndex >= 0) {
|
|
142
|
+
queuedRowAcks.splice(queuedIndex, 1);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
await new Promise((resolve) => {
|
|
146
|
+
pendingRowAck = { key, resolve };
|
|
147
|
+
});
|
|
148
|
+
};
|
|
149
|
+
/** Unblock a stream stuck waiting for an ack that will never arrive. */
|
|
150
|
+
const releaseRowAckForRequest = (requestId) => {
|
|
151
|
+
if (pendingRowAck &&
|
|
152
|
+
(requestId === undefined || pendingRowAck.key.requestId === requestId)) {
|
|
153
|
+
const { resolve } = pendingRowAck;
|
|
154
|
+
pendingRowAck = null;
|
|
155
|
+
resolve();
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
let session = null;
|
|
159
|
+
const disposeSession = (s) => {
|
|
160
|
+
for (const requestId of s.activeStreams.keys()) {
|
|
161
|
+
s.cancelledRequests.add(requestId);
|
|
162
|
+
releaseRowAckForRequest(requestId);
|
|
163
|
+
}
|
|
164
|
+
s.workbook.dispose();
|
|
165
|
+
if (session === s) {
|
|
166
|
+
session = null;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const postOpenWorkbookComplete = async (s) => {
|
|
170
|
+
self.postMessage({
|
|
171
|
+
responseType: ResponseType.OPEN_WORKBOOK_COMPLETE,
|
|
172
|
+
generation: s.generation,
|
|
173
|
+
catalog: await s.workbook.getSheetCatalog(),
|
|
174
|
+
theme: s.workbook.getTheme(),
|
|
175
|
+
fonts: s.workbook.getFonts(),
|
|
176
|
+
namedRanges: s.workbook.getNamedRanges(),
|
|
177
|
+
requiresRecalc: s.workbook.requiresRecalc(),
|
|
178
|
+
iterativeCalculationOptions: s.workbook.getIterativeCalculationOptions(),
|
|
179
|
+
use1904: s.workbook.getUse1904Epoch(),
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Shared strings newly referenced by this chunk, collected BEFORE
|
|
184
|
+
* `remapRowCells` rewrites `cell.ss` from source-index strings to
|
|
185
|
+
* content-hash ids. Only entries whose id hasn't been posted for this
|
|
186
|
+
* generation are included — the full SST never crosses the boundary.
|
|
187
|
+
*/
|
|
188
|
+
const collectChunkSharedStrings = (s, rows) => {
|
|
189
|
+
const sst = s.workbook.sharedStrings;
|
|
190
|
+
if (!sst || !rows)
|
|
191
|
+
return undefined;
|
|
192
|
+
ensureSharedStringHashIds(sst, s.workbook.richSharedStringRuns);
|
|
193
|
+
const entries = [];
|
|
194
|
+
for (const row of rows) {
|
|
195
|
+
const values = row?.values;
|
|
196
|
+
if (!values)
|
|
197
|
+
continue;
|
|
198
|
+
for (const cell of values) {
|
|
199
|
+
if (!cell || typeof cell.ss !== "string")
|
|
200
|
+
continue;
|
|
201
|
+
const idx = Number(cell.ss);
|
|
202
|
+
if (!Number.isInteger(idx) ||
|
|
203
|
+
idx < 0 ||
|
|
204
|
+
idx >= sharedStringHashIds.length) {
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
const id = sharedStringHashIds[idx];
|
|
208
|
+
if (s.sentSharedStringIds.has(id))
|
|
209
|
+
continue;
|
|
210
|
+
s.sentSharedStringIds.add(id);
|
|
211
|
+
entries.push([
|
|
212
|
+
id,
|
|
213
|
+
buildSstValue(sst[idx], s.workbook.richSharedStringRuns?.get(idx)),
|
|
214
|
+
]);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return entries.length ? entries : undefined;
|
|
218
|
+
};
|
|
219
|
+
const runLoadSheet = async (s, msg) => {
|
|
220
|
+
const { requestId, sheetId } = msg;
|
|
221
|
+
const isStale = () => session !== s ||
|
|
222
|
+
s.generation !== msg.generation ||
|
|
223
|
+
s.cancelledRequests.has(requestId);
|
|
224
|
+
if (isStale()) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const options = msg.options ?? {};
|
|
228
|
+
const enableBackpressure = options.enableBackpressure ?? false;
|
|
229
|
+
const wb = s.workbook;
|
|
230
|
+
try {
|
|
231
|
+
const postProgress = (phase, sheetTitle) => {
|
|
232
|
+
self.postMessage({
|
|
233
|
+
responseType: ResponseType.IMPORT_PROGRESS,
|
|
234
|
+
generation: s.generation,
|
|
235
|
+
phase,
|
|
236
|
+
sheetTitle,
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
postProgress("sheet-metadata");
|
|
240
|
+
const [sheet, tables] = await wb.getSheet(sheetId, s.minRowCount, s.minColumnCount);
|
|
241
|
+
if (isStale()) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
for await (const result of wb.processSheetDataForSheet({
|
|
245
|
+
sheetId,
|
|
246
|
+
chunkSize: options.chunkSize,
|
|
247
|
+
enableCellXfsRegistry: options.enableCellXfsRegistry,
|
|
248
|
+
enableSharedStrings: options.enableSharedStrings,
|
|
249
|
+
onPhase: postProgress,
|
|
250
|
+
})) {
|
|
251
|
+
if (isStale()) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const sharedStringsChunk = options.enableSharedStrings === false
|
|
255
|
+
? undefined
|
|
256
|
+
: collectChunkSharedStrings(s, result.rows);
|
|
257
|
+
remapRowCells(result.rows);
|
|
258
|
+
self.postMessage({
|
|
259
|
+
responseType: ResponseType.SHEET_CHUNK,
|
|
260
|
+
generation: s.generation,
|
|
261
|
+
requestId,
|
|
262
|
+
...result,
|
|
263
|
+
sharedStringsChunk,
|
|
264
|
+
});
|
|
265
|
+
if (enableBackpressure) {
|
|
266
|
+
await waitForRowAck({
|
|
267
|
+
sheetId: result.sheetId,
|
|
268
|
+
chunkIndex: result.chunkIndex,
|
|
269
|
+
requestId,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
await delay();
|
|
273
|
+
}
|
|
274
|
+
if (isStale()) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
postProgress("conditional-formatting", sheet.title);
|
|
278
|
+
const conditionalFormatting = await wb.getConditionalFormatting(sheetId);
|
|
279
|
+
postProgress("data-validations", sheet.title);
|
|
280
|
+
const dataValidations = await wb.getDataValidations(sheetId);
|
|
281
|
+
postProgress("comment-threads", sheet.title);
|
|
282
|
+
const commentThreads = await wb.getCommentThreads(sheetId);
|
|
283
|
+
if (isStale()) {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
self.postMessage({
|
|
287
|
+
responseType: ResponseType.SHEET_COMPLETE,
|
|
288
|
+
generation: s.generation,
|
|
289
|
+
requestId,
|
|
290
|
+
sheet,
|
|
291
|
+
tables,
|
|
292
|
+
conditionalFormatting,
|
|
293
|
+
dataValidations,
|
|
294
|
+
commentThreads,
|
|
295
|
+
cellXfs: wb.getCellXfs(),
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
if (!isStale()) {
|
|
300
|
+
console.trace(error);
|
|
301
|
+
self.postMessage({
|
|
302
|
+
responseType: ResponseType.ERROR,
|
|
303
|
+
generation: s.generation,
|
|
304
|
+
requestId,
|
|
305
|
+
error: error instanceof Error ? error.message : String(error),
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
finally {
|
|
310
|
+
s.activeStreams.delete(requestId);
|
|
311
|
+
s.cancelledRequests.delete(requestId);
|
|
312
|
+
if (session === s) {
|
|
313
|
+
wb.releaseSheetCaches(sheetId);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const openSessionWorkbook = async (s, password) => {
|
|
318
|
+
const buffer = s.file instanceof File ? s.file : await readExcelFile(s.file);
|
|
319
|
+
if (await isCFBFile(buffer)) {
|
|
320
|
+
if ((await detectCfbContainerKind(buffer)) === "legacy-xls") {
|
|
321
|
+
self.postMessage({
|
|
322
|
+
responseType: ResponseType.ERROR,
|
|
323
|
+
generation: s.generation,
|
|
324
|
+
error: LEGACY_XLS_UNSUPPORTED_MESSAGE,
|
|
325
|
+
});
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (!password) {
|
|
329
|
+
s.pendingPassword = true;
|
|
330
|
+
self.postMessage({
|
|
331
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
332
|
+
generation: s.generation,
|
|
333
|
+
message: "This file uses Office encryption and requires a password.",
|
|
334
|
+
});
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
let decryptedBuffer;
|
|
338
|
+
try {
|
|
339
|
+
decryptedBuffer = await CFBDecryptor.decrypt(buffer, password);
|
|
340
|
+
}
|
|
341
|
+
catch (decryptError) {
|
|
342
|
+
if (decryptError instanceof Error &&
|
|
343
|
+
isIncorrectPasswordError(decryptError)) {
|
|
344
|
+
s.pendingPassword = true;
|
|
345
|
+
self.postMessage({
|
|
346
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
347
|
+
generation: s.generation,
|
|
348
|
+
message: "Incorrect password. Please try again.",
|
|
349
|
+
});
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
throw decryptError;
|
|
353
|
+
}
|
|
354
|
+
resetSharedStringHashState();
|
|
355
|
+
s.sentSharedStringIds.clear();
|
|
356
|
+
await s.workbook.load(decryptedBuffer, s.fileName);
|
|
357
|
+
s.pendingPassword = false;
|
|
358
|
+
await postOpenWorkbookComplete(s);
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
resetSharedStringHashState();
|
|
362
|
+
s.sentSharedStringIds.clear();
|
|
363
|
+
try {
|
|
364
|
+
await s.workbook.load(buffer, s.fileName, password);
|
|
365
|
+
}
|
|
366
|
+
catch (loadError) {
|
|
367
|
+
if (loadError instanceof Error) {
|
|
368
|
+
if (loadError.message === "PASSWORD_REQUIRED" ||
|
|
369
|
+
(password && isIncorrectPasswordError(loadError))) {
|
|
370
|
+
s.pendingPassword = true;
|
|
371
|
+
self.postMessage({
|
|
372
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
373
|
+
generation: s.generation,
|
|
374
|
+
message: password
|
|
375
|
+
? "Incorrect password. Please try again."
|
|
376
|
+
: "This file is password protected. Please enter the password.",
|
|
377
|
+
});
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
if (loadError.message === "UNSUPPORTED_OOXML_ENCRYPTION") {
|
|
381
|
+
self.postMessage({
|
|
382
|
+
responseType: ResponseType.ERROR,
|
|
383
|
+
generation: s.generation,
|
|
384
|
+
error: "This XLSX file uses Office encryption that is not supported yet, so it cannot be opened even with the correct password.",
|
|
385
|
+
});
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
throw loadError;
|
|
390
|
+
}
|
|
391
|
+
s.pendingPassword = false;
|
|
392
|
+
await postOpenWorkbookComplete(s);
|
|
393
|
+
};
|
|
394
|
+
// Handle messages from the main thread
|
|
395
|
+
self.onmessage = async (e) => {
|
|
396
|
+
const { requestType } = e.data;
|
|
397
|
+
try {
|
|
398
|
+
// Guard against undefined requestType
|
|
399
|
+
if (!requestType) {
|
|
400
|
+
console.error("Received message with undefined requestType:", e.data);
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
if (requestType === RequestType.ACK_ROW_DATA) {
|
|
404
|
+
resolveRowAck({
|
|
405
|
+
sheetId: e.data.sheetId,
|
|
406
|
+
chunkIndex: e.data.chunkIndex,
|
|
407
|
+
requestId: e.data.requestId,
|
|
408
|
+
});
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
// Process different action types
|
|
412
|
+
switch (requestType) {
|
|
413
|
+
case RequestType.OPEN_WORKBOOK: {
|
|
414
|
+
const { generation } = e.data;
|
|
415
|
+
if (session) {
|
|
416
|
+
disposeSession(session);
|
|
417
|
+
}
|
|
418
|
+
const newSession = {
|
|
419
|
+
generation,
|
|
420
|
+
workbook: new WorkBook(),
|
|
421
|
+
file: e.data.file,
|
|
422
|
+
fileName: e.data.file instanceof File ? e.data.file.name : "unknown.xlsx",
|
|
423
|
+
minRowCount: e.data.minRowCount,
|
|
424
|
+
minColumnCount: e.data.minColumnCount,
|
|
425
|
+
sentSharedStringIds: new Set(),
|
|
426
|
+
cancelledRequests: new Set(),
|
|
427
|
+
activeStreams: new Map(),
|
|
428
|
+
pendingPassword: false,
|
|
429
|
+
queue: Promise.resolve(),
|
|
430
|
+
};
|
|
431
|
+
session = newSession;
|
|
432
|
+
try {
|
|
433
|
+
await openSessionWorkbook(newSession);
|
|
434
|
+
}
|
|
435
|
+
catch (error) {
|
|
436
|
+
console.trace(error);
|
|
437
|
+
self.postMessage({
|
|
438
|
+
responseType: ResponseType.ERROR,
|
|
439
|
+
generation,
|
|
440
|
+
error: error instanceof Error ? error.message : String(error),
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
break;
|
|
444
|
+
}
|
|
445
|
+
case RequestType.LOAD_SHEET: {
|
|
446
|
+
const msg = e.data;
|
|
447
|
+
const s = session;
|
|
448
|
+
if (!s || s.generation !== msg.generation) {
|
|
449
|
+
// Stale request from a previous generation — ignore.
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
s.activeStreams.set(msg.requestId, { sheetId: msg.sheetId });
|
|
453
|
+
// Serialize streams so two LOAD_SHEETs never interleave chunks.
|
|
454
|
+
s.queue = s.queue.then(() => runLoadSheet(s, msg));
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
case RequestType.CANCEL_REQUEST: {
|
|
458
|
+
const s = session;
|
|
459
|
+
if (!s || s.generation !== e.data.generation) {
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
s.cancelledRequests.add(e.data.requestId);
|
|
463
|
+
releaseRowAckForRequest(e.data.requestId);
|
|
464
|
+
break;
|
|
465
|
+
}
|
|
466
|
+
case RequestType.DISPOSE_WORKBOOK: {
|
|
467
|
+
const s = session;
|
|
468
|
+
if (!s || s.generation !== e.data.generation) {
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
disposeSession(s);
|
|
472
|
+
break;
|
|
473
|
+
}
|
|
474
|
+
case RequestType.PARSE_EXCEL: {
|
|
475
|
+
currentFile = e.data.file;
|
|
476
|
+
currentMinRowCount = e.data.minRowCount;
|
|
477
|
+
currentMinColumnCount = e.data.minColumnCount;
|
|
478
|
+
const buffer = e.data.file instanceof File
|
|
479
|
+
? e.data.file
|
|
480
|
+
: await readExcelFile(e.data.file);
|
|
481
|
+
currentFileName =
|
|
482
|
+
e.data.file instanceof File ? e.data.file.name : "unknown.xlsx";
|
|
483
|
+
// Check if file uses Office encryption (CFB format)
|
|
484
|
+
if (await isCFBFile(buffer)) {
|
|
485
|
+
if ((await detectCfbContainerKind(buffer)) === "legacy-xls") {
|
|
486
|
+
self.postMessage({
|
|
487
|
+
responseType: ResponseType.ERROR,
|
|
488
|
+
error: LEGACY_XLS_UNSUPPORTED_MESSAGE,
|
|
489
|
+
});
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
self.postMessage({
|
|
493
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
494
|
+
message: "This file uses Office encryption and requires a password.",
|
|
495
|
+
});
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
// Load workbook (fresh state — clear stale hash mappings from prior import)
|
|
499
|
+
resetSharedStringHashState();
|
|
500
|
+
try {
|
|
501
|
+
await workbook.load(buffer, currentFileName);
|
|
502
|
+
}
|
|
503
|
+
catch (loadError) {
|
|
504
|
+
if (loadError instanceof Error &&
|
|
505
|
+
loadError.message === "PASSWORD_REQUIRED") {
|
|
506
|
+
self.postMessage({
|
|
507
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
508
|
+
message: "This file is password protected. Please enter the password.",
|
|
509
|
+
});
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
if (loadError instanceof Error &&
|
|
513
|
+
loadError.message === "UNSUPPORTED_OOXML_ENCRYPTION") {
|
|
514
|
+
self.postMessage({
|
|
515
|
+
responseType: ResponseType.ERROR,
|
|
516
|
+
error: "This XLSX file uses Office encryption that is not supported yet, so it cannot be opened even with the correct password.",
|
|
517
|
+
});
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
throw loadError;
|
|
521
|
+
}
|
|
522
|
+
// Send the result back
|
|
523
|
+
self.postMessage({
|
|
524
|
+
responseType: ResponseType.PARSE_EXCEL_SUCCESS,
|
|
525
|
+
requiresRecalc: workbook.requiresRecalc(),
|
|
526
|
+
iterativeCalculationOptions: workbook.getIterativeCalculationOptions(),
|
|
527
|
+
use1904: workbook.getUse1904Epoch(),
|
|
528
|
+
});
|
|
529
|
+
// Pass theme back
|
|
530
|
+
self.postMessage({
|
|
531
|
+
responseType: ResponseType.GET_THEME_SUCCESS,
|
|
532
|
+
theme: workbook.getTheme(),
|
|
533
|
+
});
|
|
534
|
+
try {
|
|
535
|
+
self.postMessage({
|
|
536
|
+
responseType: ResponseType.BEGIN_GET_SHEETS,
|
|
537
|
+
totalSheets: workbook.getSheetCount(),
|
|
538
|
+
});
|
|
539
|
+
const [sheets, tables] = await workbook.getSheets(e.data.minRowCount, e.data.minColumnCount);
|
|
540
|
+
self.postMessage({
|
|
541
|
+
responseType: ResponseType.GET_SHEETS_SUCCESS,
|
|
542
|
+
sheets,
|
|
543
|
+
});
|
|
544
|
+
self.postMessage({
|
|
545
|
+
responseType: ResponseType.GET_TABLES_SUCCESS,
|
|
546
|
+
tables,
|
|
547
|
+
});
|
|
548
|
+
// Preload fonts
|
|
549
|
+
self.postMessage({
|
|
550
|
+
responseType: ResponseType.GET_FONTS_SUCCESS,
|
|
551
|
+
fonts: workbook.getFonts(),
|
|
552
|
+
});
|
|
553
|
+
// named ranges
|
|
554
|
+
self.postMessage({
|
|
555
|
+
responseType: ResponseType.GET_NAMEDRANGES_SUCCESS,
|
|
556
|
+
namedRanges: workbook.getNamedRanges(),
|
|
557
|
+
});
|
|
558
|
+
// shared strings (emit as [hashId, value][] so cells and ids stay
|
|
559
|
+
// self-consistent across the worker→host boundary).
|
|
560
|
+
self.postMessage({
|
|
561
|
+
responseType: ResponseType.GET_SHARED_STRINGS_SUCCESS,
|
|
562
|
+
sharedStrings: buildSstEntries(workbook.sharedStrings, workbook.richSharedStringRuns),
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
console.error(err);
|
|
567
|
+
}
|
|
568
|
+
break;
|
|
569
|
+
}
|
|
570
|
+
case RequestType.GET_SHEET_DATA: {
|
|
571
|
+
const enableBackpressure = e.data.enableBackpressure ?? false;
|
|
572
|
+
let lastSharedStringsLength = workbook.sharedStrings?.length ?? 0;
|
|
573
|
+
// Make sure hash ids exist for any strings loaded before this request
|
|
574
|
+
// (e.g. XLSX populates the full SST upfront).
|
|
575
|
+
ensureSharedStringHashIds(workbook.sharedStrings, workbook.richSharedStringRuns);
|
|
576
|
+
// Long silent phases (per-sheet scans, feature extraction) would trip
|
|
577
|
+
// the host bridge's inactivity watchdog on large files; emit liveness
|
|
578
|
+
// heartbeats the host can ignore.
|
|
579
|
+
const postProgress = (phase, sheetTitle) => {
|
|
580
|
+
self.postMessage({
|
|
581
|
+
responseType: ResponseType.IMPORT_PROGRESS,
|
|
582
|
+
phase,
|
|
583
|
+
sheetTitle,
|
|
584
|
+
});
|
|
585
|
+
};
|
|
586
|
+
// Process sheet data
|
|
587
|
+
for await (const result of workbook.processSheetData(e.data.pageSize, e.data.enableCellXfsRegistry, e.data.enableSharedStrings, postProgress)) {
|
|
588
|
+
let sharedStringsChunk;
|
|
589
|
+
if (e.data.enableSharedStrings) {
|
|
590
|
+
const currentSharedStrings = workbook.sharedStrings ?? [];
|
|
591
|
+
if (currentSharedStrings.length > lastSharedStringsLength) {
|
|
592
|
+
sharedStringsChunk = buildSstSlice(currentSharedStrings, lastSharedStringsLength, workbook.richSharedStringRuns);
|
|
593
|
+
lastSharedStringsLength = currentSharedStrings.length;
|
|
594
|
+
}
|
|
595
|
+
else {
|
|
596
|
+
// Ensure hash ids stay in sync even when no new strings appeared
|
|
597
|
+
ensureSharedStringHashIds(currentSharedStrings, workbook.richSharedStringRuns);
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
// Rewrite cell.ss from source-index strings to content-hash ids so
|
|
601
|
+
// cells the host sees agree with the chunk + final SST it receives.
|
|
602
|
+
remapRowCells(result.rows);
|
|
603
|
+
self.postMessage({
|
|
604
|
+
responseType: ResponseType.ROW_DATA_CHUNK,
|
|
605
|
+
...result,
|
|
606
|
+
sharedStringsChunk,
|
|
607
|
+
});
|
|
608
|
+
if (enableBackpressure) {
|
|
609
|
+
await waitForRowAck({
|
|
610
|
+
sheetId: result.sheetId,
|
|
611
|
+
chunkIndex: result.chunkIndex,
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
await delay();
|
|
615
|
+
}
|
|
616
|
+
self.postMessage({
|
|
617
|
+
responseType: ResponseType.GET_SHEET_DATA_SUCCESS,
|
|
618
|
+
});
|
|
619
|
+
// Send cell format registry
|
|
620
|
+
self.postMessage({
|
|
621
|
+
responseType: ResponseType.CELL_XFS,
|
|
622
|
+
cellXfs: workbook.getCellXfs(),
|
|
623
|
+
});
|
|
624
|
+
// Shared strings — final SST as [id, value][]
|
|
625
|
+
self.postMessage({
|
|
626
|
+
responseType: ResponseType.GET_SHARED_STRINGS_SUCCESS,
|
|
627
|
+
sharedStrings: buildSstEntries(workbook.sharedStrings, workbook.richSharedStringRuns),
|
|
628
|
+
});
|
|
629
|
+
// Process drawing
|
|
630
|
+
postProgress("drawings");
|
|
631
|
+
const drawings = await workbook.getDrawings();
|
|
632
|
+
self.postMessage({
|
|
633
|
+
responseType: ResponseType.GET_DRAWINGS_SUCCESS,
|
|
634
|
+
drawings,
|
|
635
|
+
});
|
|
636
|
+
// Charts
|
|
637
|
+
postProgress("charts");
|
|
638
|
+
const charts = await workbook.getCharts();
|
|
639
|
+
self.postMessage({
|
|
640
|
+
responseType: ResponseType.GET_CHARTS_SUCCESS,
|
|
641
|
+
charts,
|
|
642
|
+
});
|
|
643
|
+
// Slicers
|
|
644
|
+
const slicers = await workbook.getSlicers();
|
|
645
|
+
self.postMessage({
|
|
646
|
+
responseType: ResponseType.GET_SLICERS_SUCCESS,
|
|
647
|
+
slicers,
|
|
648
|
+
});
|
|
649
|
+
// Pivot tables (Phase D1 — import path)
|
|
650
|
+
postProgress("pivot-tables");
|
|
651
|
+
try {
|
|
652
|
+
const pivotTables = await workbook.getPivotTables();
|
|
653
|
+
self.postMessage({
|
|
654
|
+
responseType: ResponseType.GET_PIVOT_TABLES_SUCCESS,
|
|
655
|
+
pivotTables,
|
|
656
|
+
});
|
|
657
|
+
}
|
|
658
|
+
catch (e) {
|
|
659
|
+
// Pivot parsing is best-effort — never block the rest of
|
|
660
|
+
// the import on a single malformed pivot. Worker emits an
|
|
661
|
+
// empty list so the host can clear any stale pivots.
|
|
662
|
+
self.postMessage({
|
|
663
|
+
responseType: ResponseType.GET_PIVOT_TABLES_SUCCESS,
|
|
664
|
+
pivotTables: [],
|
|
665
|
+
});
|
|
666
|
+
// eslint-disable-next-line no-console
|
|
667
|
+
console.warn("[excel-parser] pivot table import failed:", e);
|
|
668
|
+
}
|
|
669
|
+
// External links (for formulas referencing other workbooks)
|
|
670
|
+
const externalLinks = await workbook.getExternalLinks();
|
|
671
|
+
self.postMessage({
|
|
672
|
+
responseType: ResponseType.GET_EXTERNAL_LINKS_SUCCESS,
|
|
673
|
+
externalLinks,
|
|
674
|
+
});
|
|
675
|
+
// Threaded comments (anchor cells already carry `commentThreadId`
|
|
676
|
+
// from the row chunks; this delivers the thread contents).
|
|
677
|
+
postProgress("comment-threads");
|
|
678
|
+
const commentThreads = await workbook.getCommentThreads();
|
|
679
|
+
self.postMessage({
|
|
680
|
+
responseType: ResponseType.GET_COMMENT_THREADS_SUCCESS,
|
|
681
|
+
commentThreads,
|
|
682
|
+
});
|
|
683
|
+
// Start conditional formatting
|
|
684
|
+
self.postMessage({
|
|
685
|
+
responseType: ResponseType.GET_CONDITIONAL_FORMATTING,
|
|
686
|
+
});
|
|
687
|
+
// Conditional formatting
|
|
688
|
+
const conditionalFormatting = await workbook.getConditionalFormatting();
|
|
689
|
+
self.postMessage({
|
|
690
|
+
responseType: ResponseType.GET_CONDITIONAL_FORMATTING_SUCCESS,
|
|
691
|
+
conditionalFormatting,
|
|
692
|
+
});
|
|
693
|
+
// Start data validation
|
|
694
|
+
self.postMessage({
|
|
695
|
+
responseType: ResponseType.GET_DATAVALIDATION,
|
|
696
|
+
});
|
|
697
|
+
// Data validations
|
|
698
|
+
const dataValidations = await workbook.getDataValidations();
|
|
699
|
+
// data validations ranges
|
|
700
|
+
self.postMessage({
|
|
701
|
+
responseType: ResponseType.GET_DATAVALIDATION_SUCCESS,
|
|
702
|
+
dataValidations: dataValidations,
|
|
703
|
+
});
|
|
704
|
+
// // Send end
|
|
705
|
+
self.postMessage({
|
|
706
|
+
responseType: ResponseType.PARSE_EXCEL_COMPLETE,
|
|
707
|
+
});
|
|
708
|
+
workbook.dispose();
|
|
709
|
+
break;
|
|
710
|
+
}
|
|
711
|
+
case RequestType.PROVIDE_PASSWORD: {
|
|
712
|
+
// Session-mode retry — an OPEN_WORKBOOK hit an encrypted file.
|
|
713
|
+
if (session?.pendingPassword) {
|
|
714
|
+
const s = session;
|
|
715
|
+
const password = e.data.password;
|
|
716
|
+
if (!password || password.trim() === "") {
|
|
717
|
+
self.postMessage({
|
|
718
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
719
|
+
generation: s.generation,
|
|
720
|
+
message: "Password cannot be empty. Please enter a password.",
|
|
721
|
+
});
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
try {
|
|
725
|
+
await openSessionWorkbook(s, password);
|
|
726
|
+
}
|
|
727
|
+
catch (error) {
|
|
728
|
+
console.trace(error);
|
|
729
|
+
self.postMessage({
|
|
730
|
+
responseType: ResponseType.ERROR,
|
|
731
|
+
generation: s.generation,
|
|
732
|
+
error: error instanceof Error && isEncryptedArchiveError(error)
|
|
733
|
+
? "Unable to decrypt this file with the provided password. The file may use an unsupported encryption format."
|
|
734
|
+
: error instanceof Error
|
|
735
|
+
? error.message
|
|
736
|
+
: String(error),
|
|
737
|
+
});
|
|
738
|
+
}
|
|
739
|
+
return;
|
|
740
|
+
}
|
|
741
|
+
if (!currentFile || !currentFileName) {
|
|
742
|
+
throw new Error("No file loaded to retry with password");
|
|
743
|
+
}
|
|
744
|
+
// Validate password was provided
|
|
745
|
+
const password = e.data.password;
|
|
746
|
+
if (!password || password.trim() === "") {
|
|
747
|
+
console.warn("Empty password provided");
|
|
748
|
+
self.postMessage({
|
|
749
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
750
|
+
message: "Password cannot be empty. Please enter a password.",
|
|
751
|
+
});
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
const buffer = currentFile instanceof File
|
|
755
|
+
? currentFile
|
|
756
|
+
: await readExcelFile(currentFile);
|
|
757
|
+
// Check if file uses Office encryption (CFB format)
|
|
758
|
+
const isCFB = await isCFBFile(buffer);
|
|
759
|
+
// Fresh hash state for this load attempt.
|
|
760
|
+
resetSharedStringHashState();
|
|
761
|
+
// Retry loading with password
|
|
762
|
+
try {
|
|
763
|
+
if (isCFB) {
|
|
764
|
+
// Decrypt CFB-encrypted file
|
|
765
|
+
try {
|
|
766
|
+
const decryptedBuffer = await CFBDecryptor.decrypt(buffer, password);
|
|
767
|
+
// Load the decrypted file (no password needed now)
|
|
768
|
+
await workbook.load(decryptedBuffer, currentFileName);
|
|
769
|
+
}
|
|
770
|
+
catch (decryptError) {
|
|
771
|
+
console.error("CFB decryption error:", decryptError);
|
|
772
|
+
if (decryptError instanceof Error && isIncorrectPasswordError(decryptError)) {
|
|
773
|
+
self.postMessage({
|
|
774
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
775
|
+
message: "Incorrect password. Please try again.",
|
|
776
|
+
});
|
|
777
|
+
return;
|
|
778
|
+
}
|
|
779
|
+
// Re-throw with more context
|
|
780
|
+
if (decryptError instanceof Error) {
|
|
781
|
+
throw new Error(`CFB decryption failed: ${decryptError.message}`);
|
|
782
|
+
}
|
|
783
|
+
throw decryptError;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
// ZIP-encrypted file - pass password to workbook
|
|
788
|
+
await workbook.load(buffer, currentFileName, password);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
catch (loadError) {
|
|
792
|
+
if (loadError instanceof Error && isIncorrectPasswordError(loadError)) {
|
|
793
|
+
self.postMessage({
|
|
794
|
+
responseType: ResponseType.PASSWORD_REQUIRED,
|
|
795
|
+
message: "Incorrect password. Please try again.",
|
|
796
|
+
});
|
|
797
|
+
return;
|
|
798
|
+
}
|
|
799
|
+
if (loadError instanceof Error && isEncryptedArchiveError(loadError)) {
|
|
800
|
+
self.postMessage({
|
|
801
|
+
responseType: ResponseType.ERROR,
|
|
802
|
+
error: "Unable to decrypt this file with the provided password. The file may use an unsupported encryption format.",
|
|
803
|
+
});
|
|
804
|
+
return;
|
|
805
|
+
}
|
|
806
|
+
throw loadError;
|
|
807
|
+
}
|
|
808
|
+
// If successful, continue with normal parsing flow
|
|
809
|
+
self.postMessage({
|
|
810
|
+
responseType: ResponseType.PARSE_EXCEL_SUCCESS,
|
|
811
|
+
requiresRecalc: workbook.requiresRecalc(),
|
|
812
|
+
iterativeCalculationOptions: workbook.getIterativeCalculationOptions(),
|
|
813
|
+
});
|
|
814
|
+
self.postMessage({
|
|
815
|
+
responseType: ResponseType.GET_THEME_SUCCESS,
|
|
816
|
+
theme: workbook.getTheme(),
|
|
817
|
+
});
|
|
818
|
+
try {
|
|
819
|
+
self.postMessage({
|
|
820
|
+
responseType: ResponseType.BEGIN_GET_SHEETS,
|
|
821
|
+
totalSheets: workbook.getSheetCount(),
|
|
822
|
+
});
|
|
823
|
+
const [sheets, tables] = await workbook.getSheets(currentMinRowCount, currentMinColumnCount);
|
|
824
|
+
self.postMessage({
|
|
825
|
+
responseType: ResponseType.GET_SHEETS_SUCCESS,
|
|
826
|
+
sheets,
|
|
827
|
+
});
|
|
828
|
+
self.postMessage({
|
|
829
|
+
responseType: ResponseType.GET_TABLES_SUCCESS,
|
|
830
|
+
tables,
|
|
831
|
+
});
|
|
832
|
+
self.postMessage({
|
|
833
|
+
responseType: ResponseType.GET_FONTS_SUCCESS,
|
|
834
|
+
fonts: workbook.getFonts(),
|
|
835
|
+
});
|
|
836
|
+
self.postMessage({
|
|
837
|
+
responseType: ResponseType.GET_NAMEDRANGES_SUCCESS,
|
|
838
|
+
namedRanges: workbook.getNamedRanges(),
|
|
839
|
+
});
|
|
840
|
+
self.postMessage({
|
|
841
|
+
responseType: ResponseType.GET_SHARED_STRINGS_SUCCESS,
|
|
842
|
+
sharedStrings: buildSstEntries(workbook.sharedStrings, workbook.richSharedStringRuns),
|
|
843
|
+
});
|
|
844
|
+
}
|
|
845
|
+
catch (err) {
|
|
846
|
+
console.error(err);
|
|
847
|
+
}
|
|
848
|
+
break;
|
|
849
|
+
}
|
|
850
|
+
default:
|
|
851
|
+
throw new Error(`Unknown action: ${requestType}`);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
catch (error) {
|
|
855
|
+
console.trace(error);
|
|
856
|
+
// Send back the error
|
|
857
|
+
self.postMessage({
|
|
858
|
+
responseType: ResponseType.ERROR,
|
|
859
|
+
error: error instanceof Error ? error.message : String(error),
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
};
|