@rowsncolumns/toolkit 24.4.3 → 24.4.5

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.
Files changed (86) hide show
  1. package/dist/cjs/excel-parser/interface.d.ts +5 -1
  2. package/dist/cjs/excel-parser/interface.d.ts.map +1 -1
  3. package/dist/cjs/excel-parser/plugins/base/index.d.ts +2 -0
  4. package/dist/cjs/excel-parser/plugins/base/index.d.ts.map +1 -1
  5. package/dist/cjs/excel-parser/plugins/base/index.js +3 -0
  6. package/dist/cjs/excel-parser/plugins/xls/index.d.ts +55 -9
  7. package/dist/cjs/excel-parser/plugins/xls/index.d.ts.map +1 -1
  8. package/dist/cjs/excel-parser/plugins/xls/index.js +487 -24
  9. package/dist/cjs/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
  10. package/dist/cjs/excel-parser/plugins/xlsb/index.js +12 -5
  11. package/dist/cjs/excel-parser/plugins/xlsx/chartex.d.ts +37 -0
  12. package/dist/cjs/excel-parser/plugins/xlsx/chartex.d.ts.map +1 -0
  13. package/dist/cjs/excel-parser/plugins/xlsx/chartex.js +244 -0
  14. package/dist/cjs/excel-parser/plugins/xlsx/form-controls.d.ts +70 -0
  15. package/dist/cjs/excel-parser/plugins/xlsx/form-controls.d.ts.map +1 -0
  16. package/dist/cjs/excel-parser/plugins/xlsx/form-controls.js +295 -0
  17. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts +9 -1
  18. package/dist/cjs/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  19. package/dist/cjs/excel-parser/plugins/xlsx/index.js +251 -104
  20. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts +15 -1
  21. package/dist/cjs/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  22. package/dist/cjs/excel-parser/plugins/xlsx/styles.js +90 -4
  23. package/dist/cjs/excel-parser/registry.d.ts +7 -0
  24. package/dist/cjs/excel-parser/registry.d.ts.map +1 -1
  25. package/dist/cjs/excel-parser/registry.js +28 -1
  26. package/dist/cjs/excel-parser/types.d.ts +10 -1
  27. package/dist/cjs/excel-parser/types.d.ts.map +1 -1
  28. package/dist/cjs/excel-parser/workbook.d.ts +2 -0
  29. package/dist/cjs/excel-parser/workbook.d.ts.map +1 -1
  30. package/dist/cjs/excel-parser/workbook.js +20 -14
  31. package/dist/cjs/excel-parser/worker.js +128 -130
  32. package/dist/cjs/exporter/xlsx/chart-builder.d.ts.map +1 -1
  33. package/dist/cjs/exporter/xlsx/chart-builder.js +5 -33
  34. package/dist/cjs/exporter/xlsx/chartex-builder.d.ts +36 -0
  35. package/dist/cjs/exporter/xlsx/chartex-builder.d.ts.map +1 -0
  36. package/dist/cjs/exporter/xlsx/chartex-builder.js +109 -0
  37. package/dist/cjs/exporter/xlsx/form-controls-builder.d.ts +61 -0
  38. package/dist/cjs/exporter/xlsx/form-controls-builder.d.ts.map +1 -0
  39. package/dist/cjs/exporter/xlsx/form-controls-builder.js +197 -0
  40. package/dist/cjs/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  41. package/dist/cjs/exporter/xlsx/xlsx-export.js +431 -193
  42. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  43. package/dist/esm/excel-parser/interface.d.ts +5 -1
  44. package/dist/esm/excel-parser/interface.d.ts.map +1 -1
  45. package/dist/esm/excel-parser/plugins/base/index.d.ts +2 -0
  46. package/dist/esm/excel-parser/plugins/base/index.d.ts.map +1 -1
  47. package/dist/esm/excel-parser/plugins/base/index.js +3 -0
  48. package/dist/esm/excel-parser/plugins/xls/index.d.ts +55 -9
  49. package/dist/esm/excel-parser/plugins/xls/index.d.ts.map +1 -1
  50. package/dist/esm/excel-parser/plugins/xls/index.js +429 -23
  51. package/dist/esm/excel-parser/plugins/xlsb/index.d.ts.map +1 -1
  52. package/dist/esm/excel-parser/plugins/xlsb/index.js +10 -3
  53. package/dist/esm/excel-parser/plugins/xlsx/chartex.d.ts +37 -0
  54. package/dist/esm/excel-parser/plugins/xlsx/chartex.d.ts.map +1 -0
  55. package/dist/esm/excel-parser/plugins/xlsx/chartex.js +199 -0
  56. package/dist/esm/excel-parser/plugins/xlsx/form-controls.d.ts +70 -0
  57. package/dist/esm/excel-parser/plugins/xlsx/form-controls.d.ts.map +1 -0
  58. package/dist/esm/excel-parser/plugins/xlsx/form-controls.js +246 -0
  59. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts +9 -1
  60. package/dist/esm/excel-parser/plugins/xlsx/index.d.ts.map +1 -1
  61. package/dist/esm/excel-parser/plugins/xlsx/index.js +92 -6
  62. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts +15 -1
  63. package/dist/esm/excel-parser/plugins/xlsx/styles.d.ts.map +1 -1
  64. package/dist/esm/excel-parser/plugins/xlsx/styles.js +80 -0
  65. package/dist/esm/excel-parser/registry.d.ts +7 -0
  66. package/dist/esm/excel-parser/registry.d.ts.map +1 -1
  67. package/dist/esm/excel-parser/registry.js +18 -1
  68. package/dist/esm/excel-parser/types.d.ts +10 -1
  69. package/dist/esm/excel-parser/types.d.ts.map +1 -1
  70. package/dist/esm/excel-parser/workbook.d.ts +2 -0
  71. package/dist/esm/excel-parser/workbook.d.ts.map +1 -1
  72. package/dist/esm/excel-parser/workbook.js +16 -10
  73. package/dist/esm/excel-parser/worker.js +10 -18
  74. package/dist/esm/exporter/xlsx/chart-builder.d.ts.map +1 -1
  75. package/dist/esm/exporter/xlsx/chart-builder.js +0 -28
  76. package/dist/esm/exporter/xlsx/chartex-builder.d.ts +36 -0
  77. package/dist/esm/exporter/xlsx/chartex-builder.d.ts.map +1 -0
  78. package/dist/esm/exporter/xlsx/chartex-builder.js +97 -0
  79. package/dist/esm/exporter/xlsx/form-controls-builder.d.ts +61 -0
  80. package/dist/esm/exporter/xlsx/form-controls-builder.d.ts.map +1 -0
  81. package/dist/esm/exporter/xlsx/form-controls-builder.js +173 -0
  82. package/dist/esm/exporter/xlsx/xlsx-export.d.ts.map +1 -1
  83. package/dist/esm/exporter/xlsx/xlsx-export.js +228 -19
  84. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  85. package/package.json +5 -3
  86. package/xlsx.d.ts +14 -0
@@ -1 +1 @@
1
- {"root":["../../autofilter-condition.ts","../../csv-export.ts","../../csv-import-worker.ts","../../csv-import.ts","../../excel-export.ts","../../excel-import-session.ts","../../excel-import-worker.ts","../../helpers.ts","../../index.ts","../../indexed-colors.ts","../../ods-export.ts","../../parse.ts","../../power-query.ts","../../print-settings.ts","../../server.ts","../../theme1.ts","../../types.ts","../../vitest.config.ts","../../xlsx.d.ts","../../csv-parser/helpers.ts","../../csv-parser/types.ts","../../csv-parser/worker.ts","../../excel-parser/builtin-numfmts.ts","../../excel-parser/cfb-decryptor.ts","../../excel-parser/cfb-encryptor.ts","../../excel-parser/dv-cell-stamp.ts","../../excel-parser/helpers.ts","../../excel-parser/interface.ts","../../excel-parser/registry.ts","../../excel-parser/style-registry.ts","../../excel-parser/theme-default.ts","../../excel-parser/types.ts","../../excel-parser/utils.ts","../../excel-parser/workbook.ts","../../excel-parser/worker.ts","../../excel-parser/zip-parser-streaming.ts","../../excel-parser/zip-parser.ts","../../excel-parser/plugins/base/index.ts","../../excel-parser/plugins/ods/conditional-formatting.ts","../../excel-parser/plugins/ods/data-validations.ts","../../excel-parser/plugins/ods/formula.ts","../../excel-parser/plugins/ods/index.ts","../../excel-parser/plugins/ods/sparklines.ts","../../excel-parser/plugins/ods/styles.ts","../../excel-parser/plugins/ods/types.ts","../../excel-parser/plugins/xls/index.ts","../../excel-parser/plugins/xlsb/biff-record-reader.ts","../../excel-parser/plugins/xlsb/index.ts","../../excel-parser/plugins/xlsb/rgce-parser.ts","../../excel-parser/plugins/xlsm/index.ts","../../excel-parser/plugins/xlsx/charts.ts","../../excel-parser/plugins/xlsx/conditional-formatting.ts","../../excel-parser/plugins/xlsx/data-validations.ts","../../excel-parser/plugins/xlsx/drawing.ts","../../excel-parser/plugins/xlsx/index.ts","../../excel-parser/plugins/xlsx/numfmt.ts","../../excel-parser/plugins/xlsx/pivots.ts","../../excel-parser/plugins/xlsx/relationships.ts","../../excel-parser/plugins/xlsx/sheet-views.ts","../../excel-parser/plugins/xlsx/styles.ts","../../excel-parser/plugins/xlsx/theme.ts","../../excel-parser/plugins/xlsx/threaded-comments.ts","../../excel-parser/plugins/xlsx/value-type-detection.ts","../../exporter/invalid-data-validation.ts","../../exporter/ods/ods-export.ts","../../exporter/ods/sparkline-builder.ts","../../exporter/xlsx/chart-builder.ts","../../exporter/xlsx/chart-templates.ts","../../exporter/xlsx/future-functions.ts","../../exporter/xlsx/pivot-builder.ts","../../exporter/xlsx/power-query-builder.ts","../../exporter/xlsx/slicer-builder.ts","../../exporter/xlsx/sparkline-builder.ts","../../exporter/xlsx/style-builder.ts","../../exporter/xlsx/threaded-comments-builder.ts","../../exporter/xlsx/xlsx-export.ts","../../helpers/implicit-intersection.ts","../../helpers/theme-xml-generator.ts"],"version":"5.8.3"}
1
+ {"root":["../../autofilter-condition.ts","../../csv-export.ts","../../csv-import-worker.ts","../../csv-import.ts","../../excel-export.ts","../../excel-import-session.ts","../../excel-import-worker.ts","../../helpers.ts","../../index.ts","../../indexed-colors.ts","../../ods-export.ts","../../parse.ts","../../power-query.ts","../../print-settings.ts","../../server.ts","../../theme1.ts","../../types.ts","../../vitest.config.ts","../../xlsx.d.ts","../../csv-parser/helpers.ts","../../csv-parser/types.ts","../../csv-parser/worker.ts","../../excel-parser/builtin-numfmts.ts","../../excel-parser/cfb-decryptor.ts","../../excel-parser/cfb-encryptor.ts","../../excel-parser/dv-cell-stamp.ts","../../excel-parser/helpers.ts","../../excel-parser/interface.ts","../../excel-parser/registry.ts","../../excel-parser/style-registry.ts","../../excel-parser/theme-default.ts","../../excel-parser/types.ts","../../excel-parser/utils.ts","../../excel-parser/workbook.ts","../../excel-parser/worker.ts","../../excel-parser/zip-parser-streaming.ts","../../excel-parser/zip-parser.ts","../../excel-parser/plugins/base/index.ts","../../excel-parser/plugins/ods/conditional-formatting.ts","../../excel-parser/plugins/ods/data-validations.ts","../../excel-parser/plugins/ods/formula.ts","../../excel-parser/plugins/ods/index.ts","../../excel-parser/plugins/ods/sparklines.ts","../../excel-parser/plugins/ods/styles.ts","../../excel-parser/plugins/ods/types.ts","../../excel-parser/plugins/xls/index.ts","../../excel-parser/plugins/xlsb/biff-record-reader.ts","../../excel-parser/plugins/xlsb/index.ts","../../excel-parser/plugins/xlsb/rgce-parser.ts","../../excel-parser/plugins/xlsm/index.ts","../../excel-parser/plugins/xlsx/chartex.ts","../../excel-parser/plugins/xlsx/charts.ts","../../excel-parser/plugins/xlsx/conditional-formatting.ts","../../excel-parser/plugins/xlsx/data-validations.ts","../../excel-parser/plugins/xlsx/drawing.ts","../../excel-parser/plugins/xlsx/form-controls.ts","../../excel-parser/plugins/xlsx/index.ts","../../excel-parser/plugins/xlsx/numfmt.ts","../../excel-parser/plugins/xlsx/pivots.ts","../../excel-parser/plugins/xlsx/relationships.ts","../../excel-parser/plugins/xlsx/sheet-views.ts","../../excel-parser/plugins/xlsx/styles.ts","../../excel-parser/plugins/xlsx/theme.ts","../../excel-parser/plugins/xlsx/threaded-comments.ts","../../excel-parser/plugins/xlsx/value-type-detection.ts","../../exporter/invalid-data-validation.ts","../../exporter/ods/ods-export.ts","../../exporter/ods/sparkline-builder.ts","../../exporter/xlsx/chart-builder.ts","../../exporter/xlsx/chart-templates.ts","../../exporter/xlsx/chartex-builder.ts","../../exporter/xlsx/form-controls-builder.ts","../../exporter/xlsx/future-functions.ts","../../exporter/xlsx/pivot-builder.ts","../../exporter/xlsx/power-query-builder.ts","../../exporter/xlsx/slicer-builder.ts","../../exporter/xlsx/sparkline-builder.ts","../../exporter/xlsx/style-builder.ts","../../exporter/xlsx/threaded-comments-builder.ts","../../exporter/xlsx/xlsx-export.ts","../../helpers/implicit-intersection.ts","../../helpers/theme-xml-generator.ts"],"version":"5.8.3"}
@@ -1,5 +1,5 @@
1
1
  import type { ConditionalFormatRule, DataValidationRuleRecord, EmbeddedChart, NamedRange, ProtectedRange, Sheet, Slicer, SpreadsheetTheme, TableView } from "@rowsncolumns/spreadsheet";
2
- import type { CommentThread, IterativeCalculationOptions, TextFormat, TextFormatRun } from "@rowsncolumns/common-types";
2
+ import type { CommentThread, IterativeCalculationOptions, NamedCellStyle, TextFormat, TextFormatRun } from "@rowsncolumns/common-types";
3
3
  import type { EmbeddedObjectWithPosition, ExternalLink, ProcessSheetDataForSheetOptions, ProcessSheetDataResult, SheetCatalogEntry, WorkbookProperties } from "./types";
4
4
  export interface IWorkbookPlugin {
5
5
  /**
@@ -58,6 +58,10 @@ export interface IWorkbookPlugin {
58
58
  * Get spreadsheet theme
59
59
  */
60
60
  getTheme(): SpreadsheetTheme;
61
+ /**
62
+ * Workbook named cell styles (`<cellStyles>`) resolved to cell formats.
63
+ */
64
+ getNamedCellStyles?(): NamedCellStyle[];
61
65
  /**
62
66
  * Get the workbook default font (styles.xml fonts[0]) when the source
63
67
  * format has one; null/undefined otherwise.
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../excel-parser/interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../excel-parser/interface.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { NamedCellStyle } from "@rowsncolumns/common-types";
1
2
  import type { ConditionalFormatRule, DataValidationRuleRecord, EmbeddedChart, NamedRange, Sheet, Slicer, SpreadsheetTheme, TableView } from "@rowsncolumns/spreadsheet";
2
3
  import type { IterativeCalculationOptions } from "@rowsncolumns/common-types";
3
4
  import type { IWorkbookPlugin } from "../../interface";
@@ -8,6 +9,7 @@ export declare abstract class BaseWorkbookPlugin implements IWorkbookPlugin {
8
9
  getSheetCount(): number;
9
10
  getSheets(minRowCount?: number, minColumnCount?: number): Promise<[Sheet[], TableView[]]>;
10
11
  getTheme(): SpreadsheetTheme;
12
+ getNamedCellStyles(): NamedCellStyle[];
11
13
  getStyles(): any;
12
14
  getFonts(): string[];
13
15
  getCellXfs(): Map<string | number, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/base/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EACb,UAAU,EACV,KAAK,EACL,MAAM,EACN,gBAAgB,EAChB,SAAS,EACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EACV,0BAA0B,EAC1B,YAAY,EACZ,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAErB,8BAAsB,kBAAmB,YAAW,eAAe;IACjE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3E,OAAO,IAAI,IAAI;IAIf,aAAa,IAAI,MAAM;IAIjB,SAAS,CACb,WAAW,CAAC,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAIlC,QAAQ,IAAI,gBAAgB;IAI5B,SAAS,IAAI,GAAG;IAIhB,QAAQ,IAAI,MAAM,EAAE;IAIpB,UAAU,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAIvC,cAAc,IAAI,OAAO;IAIzB,8BAA8B,IAC1B,2BAA2B,GAC3B,SAAS;IAIb;;;OAGG;IACH,eAAe,IAAI,OAAO;IAI1B,gBAAgB,IAAI,MAAM,EAAE;IAIrB,gBAAgB,CACrB,SAAS,CAAC,EAAE,MAAM,EAClB,qBAAqB,CAAC,EAAE,OAAO,EAC/B,oBAAoB,CAAC,EAAE,OAAO,EAC9B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,GACtD,cAAc,CAAC,sBAAsB,EAAE,IAAI,EAAE,OAAO,CAAC;IAIlD,WAAW,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAIpD,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAIrC,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAI5D,kBAAkB,IAAI,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAI/D,cAAc,IAAI,UAAU,EAAE;IAIxB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/B,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;CAGlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/base/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,KAAK,EACV,qBAAqB,EACrB,wBAAwB,EACxB,aAAa,EACb,UAAU,EACV,KAAK,EACL,MAAM,EACN,gBAAgB,EAChB,SAAS,EACV,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,KAAK,EACV,0BAA0B,EAC1B,YAAY,EACZ,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAErB,8BAAsB,kBAAmB,YAAW,eAAe;IACjE,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAE3E,OAAO,IAAI,IAAI;IAIf,aAAa,IAAI,MAAM;IAIjB,SAAS,CACb,WAAW,CAAC,EAAE,MAAM,EACpB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAIlC,QAAQ,IAAI,gBAAgB;IAI5B,kBAAkB,IAAI,cAAc,EAAE;IAItC,SAAS,IAAI,GAAG;IAIhB,QAAQ,IAAI,MAAM,EAAE;IAIpB,UAAU,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAIvC,cAAc,IAAI,OAAO;IAIzB,8BAA8B,IAC1B,2BAA2B,GAC3B,SAAS;IAIb;;;OAGG;IACH,eAAe,IAAI,OAAO;IAI1B,gBAAgB,IAAI,MAAM,EAAE;IAIrB,gBAAgB,CACrB,SAAS,CAAC,EAAE,MAAM,EAClB,qBAAqB,CAAC,EAAE,OAAO,EAC/B,oBAAoB,CAAC,EAAE,OAAO,EAC9B,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,GACtD,cAAc,CAAC,sBAAsB,EAAE,IAAI,EAAE,OAAO,CAAC;IAIlD,WAAW,IAAI,OAAO,CAAC,0BAA0B,EAAE,CAAC;IAIpD,SAAS,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAIrC,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,EAAE,CAAC;IAI5D,kBAAkB,IAAI,OAAO,CAAC,wBAAwB,EAAE,CAAC;IAI/D,cAAc,IAAI,UAAU,EAAE;IAIxB,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/B,gBAAgB,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;CAGlD"}
@@ -12,6 +12,9 @@ export class BaseWorkbookPlugin {
12
12
  getTheme() {
13
13
  return defaultSpreadsheetTheme;
14
14
  }
15
+ getNamedCellStyles() {
16
+ return [];
17
+ }
15
18
  getStyles() {
16
19
  return {};
17
20
  }
@@ -1,13 +1,59 @@
1
- import { XlsxPlugin } from "../xlsx/index";
1
+ import type { NamedRange, Sheet, TableView } from "@rowsncolumns/spreadsheet";
2
+ import { type DefinedName } from "xlsx/xlsx.mjs";
3
+ import type { ProcessSheetDataResult } from "../../types";
4
+ import { BaseWorkbookPlugin } from "../base/index";
5
+ export declare const ZIP_SIGNATURE: number[];
6
+ export declare const CFB_SIGNATURE: number[];
7
+ export declare const readHeader: (source: ArrayBuffer | File, length: number) => Promise<Uint8Array>;
8
+ export declare const startsWith: (header: Uint8Array, signature: number[]) => boolean;
2
9
  /**
3
- * `.xls` handler. The BIFF (Excel 97-2003) binary format is not parsed;
4
- * this plugin exists so a `.xls` file gets a clear, actionable error
5
- * instead of falling through to the xlsx zip reader (which fails with an
6
- * opaque "not a zip" error) or stalling in the password prompt. The one
7
- * `.xls` shape that does load is an OOXML package saved with the wrong
8
- * extension — Excel opens those too, so they are handed to the xlsx parser.
10
+ * BIFF `NAME` records (SheetJS `Workbook.Names`) → `NamedRange`s. Builtin
11
+ * names (`_xlnm.Print_Area`, `_xlnm._FilterDatabase`, …) are print / filter
12
+ * metadata, not user names, and are skipped. A reference that parses as a
13
+ * range becomes `range` (pinned to the sheet the ref names, else the name's
14
+ * own sheet scope, else the first sheet); anything else is kept as a
15
+ * formula `value`.
9
16
  */
10
- export declare class XlsPlugin extends XlsxPlugin {
11
- load(buffer: ArrayBuffer | File, password?: string): Promise<void>;
17
+ export declare const mapDefinedNames: (names: ReadonlyArray<DefinedName | undefined>, sheets: ReadonlyArray<{
18
+ sheetId: number;
19
+ title: string;
20
+ }>) => NamedRange[];
21
+ /**
22
+ * Legacy `.xls` (BIFF8, Excel 97-2003) reader.
23
+ *
24
+ * The BIFF record stream is decoded by SheetJS (`xlsx`, already a toolkit
25
+ * dependency for the CFB container reader used by the password decryptor),
26
+ * and the decoded workbook is mapped onto the same plugin contract the
27
+ * xlsx / xlsb readers implement: sheet names + visibility, cell values with
28
+ * their number formats, formulas with their cached results, merges, column
29
+ * widths / row heights, hyperlinks, cell notes, defined names and the 1904
30
+ * date-system flag. Cell fonts / fills / borders are not decoded (BIFF XF
31
+ * styling is outside SheetJS's open-source decoder), so a `.xls` opens with
32
+ * its data and number formatting; export goes through XLSX like XLSB.
33
+ *
34
+ * `load` also keeps the previous routing guards: an OOXML package saved with a
35
+ * `.xls` name is rejected here so `WorkBook` hands it to the xlsx parser, an
36
+ * encrypted container still asks for a password, and an HTML / text export
37
+ * saved as `.xls` fails with an actionable message.
38
+ */
39
+ export declare class XlsPlugin extends BaseWorkbookPlugin {
40
+ private sheets;
41
+ private namedRanges;
42
+ private cellXfs;
43
+ private formatIds;
44
+ private use1904;
45
+ load(buffer: ArrayBuffer | File, _password?: string): Promise<void>;
46
+ dispose(): void;
47
+ getSheetCount(): number;
48
+ getSheets(minRowCount?: number, minColumnCount?: number): Promise<[Sheet[], TableView[]]>;
49
+ getCellXfs(): Map<string | number, any>;
50
+ registerFormat(format: any): string;
51
+ getNamedRanges(): NamedRange[];
52
+ /** `WBProps.date1904` — Mac-origin workbooks shift every date serial. */
53
+ getUse1904Epoch(): boolean;
54
+ /** Formulas carry their BIFF cached results, so no load-time recalc. */
55
+ requiresRecalc(): boolean;
56
+ private toCellData;
57
+ processSheetData(chunkSize?: number, enableCellXfsRegistry?: boolean, _enableSharedStrings?: boolean): AsyncGenerator<ProcessSheetDataResult, void, unknown>;
12
58
  }
13
59
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xls/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAoB3C;;;;;;;GAOG;AACH,qBAAa,SAAU,SAAQ,UAAU;IACjC,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM;CAiBzD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../excel-parser/plugins/xls/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,UAAU,EACV,KAAK,EACL,SAAS,EACV,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAIL,KAAK,WAAW,EAGjB,MAAM,eAAe,CAAC;AAQvB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,eAAO,MAAM,aAAa,UAA2B,CAAC;AACtD,eAAO,MAAM,aAAa,UAAmD,CAAC;AAE9E,eAAO,MAAM,UAAU,GACrB,QAAQ,WAAW,GAAG,IAAI,EAC1B,QAAQ,MAAM,KACb,OAAO,CAAC,UAAU,CAMpB,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,QAAQ,UAAU,EAAE,WAAW,MAAM,EAAE,YAER,CAAC;AAqC3D;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,GAC1B,OAAO,aAAa,CAAC,WAAW,GAAG,SAAS,CAAC,EAC7C,QAAQ,aAAa,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,KACxD,UAAU,EA+BT,CAAC;AAeL;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,SAAU,SAAQ,kBAAkB;IAC/C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,OAAO,CAAmC;IAClD,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,OAAO,CAAS;IAElB,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0HzE,OAAO,IAAI,IAAI;IAOf,aAAa,IAAI,MAAM;IAIjB,SAAS,CACb,WAAW,SAAI,EACf,cAAc,SAAI,GACjB,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;IAiBlC,UAAU,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC;IAIvC,cAAc,CAAC,MAAM,EAAE,GAAG,GAAG,MAAM;IAQnC,cAAc,IAAI,UAAU,EAAE;IAI9B,yEAAyE;IACzE,eAAe,IAAI,OAAO;IAI1B,wEAAwE;IACxE,cAAc,IAAI,OAAO;IAIzB,OAAO,CAAC,UAAU;IAoHX,gBAAgB,CACrB,SAAS,SAAM,EACf,qBAAqB,UAAQ,EAC7B,oBAAoB,CAAC,EAAE,OAAO,GAC7B,cAAc,CAAC,sBAAsB,EAAE,IAAI,EAAE,OAAO,CAAC;CAiEzD"}
@@ -1,39 +1,445 @@
1
+ import { getCellXfsKey, ssfFormat, uuid } from "@rowsncolumns/utils";
2
+ import { read as readSheetJsWorkbook, utils as sheetJsUtils, } from "xlsx/xlsx.mjs";
1
3
  import { detectCfbContainerKind, LEGACY_XLS_UNSUPPORTED_MESSAGE, XLS_NOT_A_WORKBOOK_MESSAGE, } from "../../cfb-decryptor";
2
- import { XlsxPlugin } from "../xlsx/index";
3
- const ZIP_SIGNATURE = [0x50, 0x4b, 0x03, 0x04];
4
- const CFB_SIGNATURE = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];
5
- const readHeader = async (source, length) => {
4
+ import { excelColumnWidthToPixels, getRangeFromAddressRef } from "../../helpers";
5
+ import { BaseWorkbookPlugin } from "../base/index";
6
+ export const ZIP_SIGNATURE = [0x50, 0x4b, 0x03, 0x04];
7
+ export const CFB_SIGNATURE = [0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1];
8
+ export const readHeader = async (source, length) => {
6
9
  const slice = source instanceof File
7
10
  ? await source.slice(0, length).arrayBuffer()
8
11
  : source.slice(0, length);
9
12
  return new Uint8Array(slice);
10
13
  };
11
- const startsWith = (header, signature) => header.length >= signature.length &&
14
+ export const startsWith = (header, signature) => header.length >= signature.length &&
12
15
  signature.every((byte, index) => header[index] === byte);
13
16
  /**
14
- * `.xls` handler. The BIFF (Excel 97-2003) binary format is not parsed;
15
- * this plugin exists so a `.xls` file gets a clear, actionable error
16
- * instead of falling through to the xlsx zip reader (which fails with an
17
- * opaque "not a zip" error) or stalling in the password prompt. The one
18
- * `.xls` shape that does load is an OOXML package saved with the wrong
19
- * extension — Excel opens those too, so they are handed to the xlsx parser.
17
+ * BIFF8 error codes (MS-XLS 2.5.97 `BErr`) → Excel error literals. SheetJS
18
+ * surfaces an error cell as `{ t: "e", v: <code>, w: "#DIV/0!" }`.
20
19
  */
21
- export class XlsPlugin extends XlsxPlugin {
22
- async load(buffer, password) {
20
+ const BIFF_ERROR_CODES = {
21
+ 0x00: "#NULL!",
22
+ 0x07: "#DIV/0!",
23
+ 0x0f: "#VALUE!",
24
+ 0x17: "#REF!",
25
+ 0x1d: "#NAME?",
26
+ 0x24: "#NUM!",
27
+ 0x2a: "#N/A",
28
+ 0x2b: "#GETTING_DATA",
29
+ };
30
+ const getNumberFormatType = (pattern) => {
31
+ const lower = pattern.toLowerCase();
32
+ if (lower.includes("yy") || lower.includes("dd"))
33
+ return "DATE";
34
+ if (lower.includes("h:") || lower.includes("am/pm"))
35
+ return "TIME";
36
+ if (lower.includes("%"))
37
+ return "PERCENT";
38
+ // Excel's builtin 49 (`@`) and any text-placeholder format — same facet
39
+ // type the xlsx styles reader yields for the cell.
40
+ if (lower.includes("@"))
41
+ return "TEXT";
42
+ if (lower.includes("$") ||
43
+ lower.includes("€") ||
44
+ lower.includes("£") ||
45
+ lower.includes("¥")) {
46
+ return "CURRENCY";
47
+ }
48
+ if (lower.includes("0") || lower.includes("#"))
49
+ return "NUMBER";
50
+ return "GENERAL";
51
+ };
52
+ /**
53
+ * BIFF `NAME` records (SheetJS `Workbook.Names`) → `NamedRange`s. Builtin
54
+ * names (`_xlnm.Print_Area`, `_xlnm._FilterDatabase`, …) are print / filter
55
+ * metadata, not user names, and are skipped. A reference that parses as a
56
+ * range becomes `range` (pinned to the sheet the ref names, else the name's
57
+ * own sheet scope, else the first sheet); anything else is kept as a
58
+ * formula `value`.
59
+ */
60
+ export const mapDefinedNames = (names, sheets) => names.flatMap((name) => {
61
+ if (!name?.Name || !name.Ref)
62
+ return [];
63
+ if (name.Name.startsWith("_xlnm."))
64
+ return [];
65
+ const namedRange = {
66
+ namedRangeId: uuid(),
67
+ name: name.Name,
68
+ };
69
+ const scopedSheetId = name.Sheet != null ? sheets[name.Sheet]?.sheetId : undefined;
70
+ const ref = name.Ref.replace(/^=/, "");
71
+ const bang = ref.lastIndexOf("!");
72
+ const sheetPart = bang >= 0 ? ref.slice(0, bang) : undefined;
73
+ const refPart = bang >= 0 ? ref.slice(bang + 1) : ref;
74
+ const targetTitle = sheetPart
75
+ ?.replace(/^'(.*)'$/, "$1")
76
+ .replace(/''/g, "'");
77
+ const targetSheetId = (targetTitle
78
+ ? sheets.find((s) => s.title === targetTitle)?.sheetId
79
+ : undefined) ??
80
+ scopedSheetId ??
81
+ sheets[0]?.sheetId ??
82
+ 1;
83
+ const gridRange = getRangeFromAddressRef(refPart);
84
+ if (gridRange) {
85
+ namedRange.range = { ...gridRange, sheetId: targetSheetId };
86
+ }
87
+ else {
88
+ namedRange.value = `=${ref}`;
89
+ }
90
+ return [namedRange];
91
+ });
92
+ /**
93
+ * Legacy `.xls` (BIFF8, Excel 97-2003) reader.
94
+ *
95
+ * The BIFF record stream is decoded by SheetJS (`xlsx`, already a toolkit
96
+ * dependency for the CFB container reader used by the password decryptor),
97
+ * and the decoded workbook is mapped onto the same plugin contract the
98
+ * xlsx / xlsb readers implement: sheet names + visibility, cell values with
99
+ * their number formats, formulas with their cached results, merges, column
100
+ * widths / row heights, hyperlinks, cell notes, defined names and the 1904
101
+ * date-system flag. Cell fonts / fills / borders are not decoded (BIFF XF
102
+ * styling is outside SheetJS's open-source decoder), so a `.xls` opens with
103
+ * its data and number formatting; export goes through XLSX like XLSB.
104
+ *
105
+ * `load` also keeps the previous routing guards: an OOXML package saved with a
106
+ * `.xls` name is rejected here so `WorkBook` hands it to the xlsx parser, an
107
+ * encrypted container still asks for a password, and an HTML / text export
108
+ * saved as `.xls` fails with an actionable message.
109
+ */
110
+ export class XlsPlugin extends BaseWorkbookPlugin {
111
+ sheets = [];
112
+ namedRanges = [];
113
+ cellXfs = new Map();
114
+ formatIds = new Map();
115
+ use1904 = false;
116
+ async load(buffer, _password) {
23
117
  const header = await readHeader(buffer, CFB_SIGNATURE.length);
24
118
  if (startsWith(header, ZIP_SIGNATURE)) {
25
- return super.load(buffer, password);
119
+ // An OOXML package mislabelled `.xls` — `WorkBook.load` routes these
120
+ // to the xlsx parser before reaching here; guard direct callers.
121
+ throw new Error("NOT_A_BIFF_WORKBOOK");
122
+ }
123
+ if (!startsWith(header, CFB_SIGNATURE)) {
124
+ throw new Error(XLS_NOT_A_WORKBOOK_MESSAGE);
125
+ }
126
+ const kind = await detectCfbContainerKind(buffer);
127
+ if (kind === "encrypted-ooxml") {
128
+ throw new Error("PASSWORD_REQUIRED");
129
+ }
130
+ if (kind !== "legacy-xls") {
131
+ throw new Error(XLS_NOT_A_WORKBOOK_MESSAGE);
132
+ }
133
+ const bytes = new Uint8Array(buffer instanceof File ? await buffer.arrayBuffer() : buffer);
134
+ let workbook;
135
+ try {
136
+ workbook = readSheetJsWorkbook(bytes, {
137
+ type: "array",
138
+ cellNF: true,
139
+ cellStyles: true,
140
+ cellDates: false,
141
+ cellText: false,
142
+ sheetStubs: false,
143
+ dense: false,
144
+ });
145
+ }
146
+ catch (error) {
147
+ // A password-protected BIFF workbook (RC4 / XOR obfuscation) surfaces
148
+ // here — SheetJS refuses it. There is no BIFF decryptor, so the only
149
+ // actionable guidance is the save-as-xlsx one.
150
+ const message = error instanceof Error ? error.message : String(error);
151
+ if (/password/i.test(message) || /encrypt/i.test(message)) {
152
+ throw new Error(LEGACY_XLS_UNSUPPORTED_MESSAGE);
153
+ }
154
+ throw new Error(`${LEGACY_XLS_UNSUPPORTED_MESSAGE} (${message})`);
155
+ }
156
+ this.use1904 = Boolean(workbook.Workbook?.WBProps?.date1904);
157
+ this.sheets = workbook.SheetNames.map((title, index) => {
158
+ const worksheet = workbook.Sheets[title] ?? {};
159
+ const props = workbook.Workbook?.Sheets?.[index];
160
+ const hiddenState = props?.Hidden ?? 0;
161
+ const visibility = hiddenState === 2
162
+ ? "veryHidden"
163
+ : hiddenState === 1
164
+ ? "hidden"
165
+ : "visible";
166
+ const ref = worksheet["!ref"];
167
+ const range = ref ? sheetJsUtils.decode_range(ref) : undefined;
168
+ const rowCount = range ? range.e.r + 1 : 0;
169
+ const columnCount = range ? range.e.c + 1 : 0;
170
+ const merges = (worksheet["!merges"] ?? []).map((merge) => ({
171
+ startRowIndex: merge.s.r + 1,
172
+ endRowIndex: merge.e.r + 1,
173
+ startColumnIndex: merge.s.c + 1,
174
+ endColumnIndex: merge.e.c + 1,
175
+ }));
176
+ const columnMetadata = [];
177
+ (worksheet["!cols"] ?? []).forEach((col, colIndex) => {
178
+ if (!col)
179
+ return;
180
+ const props = {};
181
+ if (col.hidden)
182
+ props.hiddenByUser = true;
183
+ const size = col.wpx ??
184
+ (col.wch != null ? excelColumnWidthToPixels(col.wch) : undefined) ??
185
+ (col.width != null ? excelColumnWidthToPixels(col.width) : undefined);
186
+ if (size != null && size > 0) {
187
+ props.size = size;
188
+ props.resizedByUser = true;
189
+ }
190
+ if (Object.keys(props).length > 0) {
191
+ columnMetadata[colIndex + 1] = props;
192
+ }
193
+ });
194
+ const rowMetadata = [];
195
+ (worksheet["!rows"] ?? []).forEach((row, rowIndex) => {
196
+ if (!row)
197
+ return;
198
+ const props = {};
199
+ if (row.hidden)
200
+ props.hiddenByUser = true;
201
+ const size = row.hpx ?? (row.hpt != null ? (row.hpt * 96) / 72 : undefined);
202
+ if (size != null && size > 0) {
203
+ props.size = Math.round(size);
204
+ props.resizedByUser = true;
205
+ }
206
+ if (Object.keys(props).length > 0) {
207
+ rowMetadata[rowIndex + 1] = props;
208
+ }
209
+ });
210
+ return {
211
+ sheetId: index + 1,
212
+ title,
213
+ hidden: visibility !== "visible",
214
+ visibility,
215
+ worksheet,
216
+ rowCount,
217
+ columnCount,
218
+ merges,
219
+ rowMetadata,
220
+ columnMetadata,
221
+ };
222
+ });
223
+ this.namedRanges = mapDefinedNames(workbook.Workbook?.Names ?? [], this.sheets.map((s) => ({ sheetId: s.sheetId, title: s.title })));
224
+ }
225
+ dispose() {
226
+ this.sheets = [];
227
+ this.namedRanges = [];
228
+ this.cellXfs.clear();
229
+ this.formatIds.clear();
230
+ }
231
+ getSheetCount() {
232
+ return this.sheets.length;
233
+ }
234
+ async getSheets(minRowCount = 0, minColumnCount = 0) {
235
+ const sheets = this.sheets.map((sheet) => ({
236
+ sheetId: sheet.sheetId,
237
+ title: sheet.title,
238
+ hidden: sheet.hidden,
239
+ ...(sheet.visibility !== "visible"
240
+ ? { visibility: sheet.visibility }
241
+ : {}),
242
+ rowCount: Math.max(minRowCount, sheet.rowCount),
243
+ columnCount: Math.max(minColumnCount, sheet.columnCount),
244
+ rowMetadata: sheet.rowMetadata,
245
+ columnMetadata: sheet.columnMetadata,
246
+ merges: sheet.merges,
247
+ }));
248
+ return [sheets, []];
249
+ }
250
+ getCellXfs() {
251
+ return this.cellXfs;
252
+ }
253
+ registerFormat(format) {
254
+ const key = getCellXfsKey(format);
255
+ if (!this.cellXfs.has(key)) {
256
+ this.cellXfs.set(key, format);
257
+ }
258
+ return key;
259
+ }
260
+ getNamedRanges() {
261
+ return this.namedRanges;
262
+ }
263
+ /** `WBProps.date1904` — Mac-origin workbooks shift every date serial. */
264
+ getUse1904Epoch() {
265
+ return this.use1904;
266
+ }
267
+ /** Formulas carry their BIFF cached results, so no load-time recalc. */
268
+ requiresRecalc() {
269
+ return false;
270
+ }
271
+ toCellData(cell, enableCellXfsRegistry) {
272
+ const format = {};
273
+ const pattern = typeof cell.z === "string" && cell.z.toLowerCase() !== "general"
274
+ ? cell.z
275
+ : undefined;
276
+ if (pattern) {
277
+ format.numberFormat = { type: getNumberFormatType(pattern), pattern };
278
+ }
279
+ const hasFormat = Object.keys(format).length > 0;
280
+ let style;
281
+ if (enableCellXfsRegistry && hasFormat && pattern) {
282
+ let id = this.formatIds.get(pattern);
283
+ if (id === undefined) {
284
+ id = this.formatIds.size;
285
+ this.formatIds.set(pattern, id);
286
+ }
287
+ style = { sid: `xls:${id}` };
288
+ if (!this.cellXfs.has(style.sid)) {
289
+ this.cellXfs.set(style.sid, format);
290
+ }
291
+ }
292
+ const formatFields = style
293
+ ? { ef: style, uf: style }
294
+ : hasFormat
295
+ ? { ef: format, uf: format }
296
+ : {};
297
+ const formula = typeof cell.f === "string" && cell.f.length > 0
298
+ ? `=${cell.f.replace(/^=/, "")}`
299
+ : undefined;
300
+ let cellData = null;
301
+ switch (cell.t) {
302
+ case "s":
303
+ case "d": {
304
+ const text = cell.v == null ? "" : String(cell.v);
305
+ cellData = {
306
+ ...formatFields,
307
+ ue: formula ? { fv: formula } : { sv: text },
308
+ ev: { sv: text },
309
+ ...(formula ? {} : { fv: text }),
310
+ };
311
+ break;
312
+ }
313
+ case "n": {
314
+ const value = Number(cell.v);
315
+ if (!Number.isFinite(value))
316
+ return null;
317
+ cellData = {
318
+ ...formatFields,
319
+ ue: formula ? { fv: formula } : { nv: value },
320
+ ev: { nv: value },
321
+ ...(formula ? {} : { fv: ssfFormat(pattern ?? "GENERAL", value) }),
322
+ };
323
+ break;
324
+ }
325
+ case "b": {
326
+ const value = Boolean(cell.v);
327
+ cellData = {
328
+ ...formatFields,
329
+ ue: formula ? { fv: formula } : { bv: value },
330
+ ev: { bv: value },
331
+ ...(formula ? {} : { fv: value ? "TRUE" : "FALSE" }),
332
+ };
333
+ break;
334
+ }
335
+ case "e": {
336
+ const code = (typeof cell.v === "number" ? BIFF_ERROR_CODES[cell.v] : undefined) ??
337
+ (typeof cell.w === "string" && cell.w.startsWith("#")
338
+ ? cell.w
339
+ : "#VALUE!");
340
+ const errorValue = {
341
+ ev: { type: "Error", name: code, message: code },
342
+ };
343
+ cellData = {
344
+ ...formatFields,
345
+ ue: formula ? { fv: formula } : errorValue,
346
+ ev: errorValue,
347
+ ...(formula ? {} : { fv: code }),
348
+ };
349
+ break;
350
+ }
351
+ case "z":
352
+ default: {
353
+ if (formula) {
354
+ cellData = { ...formatFields, ue: { fv: formula } };
355
+ }
356
+ else if (hasFormat) {
357
+ cellData = { ...formatFields };
358
+ }
359
+ else {
360
+ return null;
361
+ }
362
+ }
26
363
  }
27
- if (startsWith(header, CFB_SIGNATURE)) {
28
- // A CFB container: a BIFF workbook, or (when the caller skipped the
29
- // WorkBook-level decryption) an encrypted package. Either way the
30
- // legacy-workbook guidance is the actionable one for a .xls name.
31
- const kind = await detectCfbContainerKind(buffer);
32
- if (kind === "encrypted-ooxml") {
33
- throw new Error("PASSWORD_REQUIRED");
364
+ if (cell.l?.Target) {
365
+ const target = cell.l.Target;
366
+ const tooltip = cell.l.Tooltip ? { tooltip: cell.l.Tooltip } : {};
367
+ cellData.hyperlink = target.startsWith("#")
368
+ ? { kind: "internal", location: target.slice(1), ...tooltip }
369
+ : { kind: "external", url: target, ...tooltip };
370
+ }
371
+ if (Array.isArray(cell.c) && cell.c.length > 0) {
372
+ const note = cell.c
373
+ .map((comment) => comment?.t ?? "")
374
+ .filter((text) => text.length > 0)
375
+ .join("\n");
376
+ if (note)
377
+ cellData.note = note;
378
+ }
379
+ return cellData;
380
+ }
381
+ async *processSheetData(chunkSize = 100, enableCellXfsRegistry = false, _enableSharedStrings) {
382
+ const totalSheets = this.sheets.length;
383
+ for (let index = 0; index < this.sheets.length; index++) {
384
+ const sheet = this.sheets[index];
385
+ const rows = new Map();
386
+ for (const address of Object.keys(sheet.worksheet)) {
387
+ if (address.startsWith("!"))
388
+ continue;
389
+ const cell = sheet.worksheet[address];
390
+ if (!cell || typeof cell !== "object")
391
+ continue;
392
+ const { r, c } = sheetJsUtils.decode_cell(address);
393
+ if (r < 0 || c < 0)
394
+ continue;
395
+ const cellData = this.toCellData(cell, enableCellXfsRegistry);
396
+ if (!cellData)
397
+ continue;
398
+ let row = rows.get(r + 1);
399
+ if (!row) {
400
+ row = { values: [] };
401
+ rows.set(r + 1, row);
402
+ }
403
+ row.values[c + 1] = cellData;
404
+ }
405
+ const sortedRows = Array.from(rows.entries()).sort((a, b) => a[0] - b[0]);
406
+ let chunkRows = [];
407
+ let chunkRowIndices = [];
408
+ let chunkIndex = 0;
409
+ let startRowIndex = -1;
410
+ let endRowIndex = -1;
411
+ const emit = (isLastChunk) => ({
412
+ sheetId: sheet.sheetId,
413
+ title: sheet.title,
414
+ currentSheetIndex: index,
415
+ totalSheets,
416
+ chunkIndex,
417
+ rows: chunkRows,
418
+ rowIndices: chunkRowIndices,
419
+ startRowIndex,
420
+ endRowIndex,
421
+ totalRows: sheet.rowCount,
422
+ isLastChunk,
423
+ cellXfs: this.cellXfs,
424
+ });
425
+ for (const [rowIndex, rowData] of sortedRows) {
426
+ if (chunkRows.length === 0)
427
+ startRowIndex = rowIndex;
428
+ chunkRows.push(rowData);
429
+ chunkRowIndices.push(rowIndex);
430
+ endRowIndex = rowIndex;
431
+ if (chunkRows.length >= chunkSize) {
432
+ yield emit(false);
433
+ chunkRows = [];
434
+ chunkRowIndices = [];
435
+ chunkIndex += 1;
436
+ startRowIndex = -1;
437
+ endRowIndex = -1;
438
+ }
439
+ }
440
+ if (chunkRows.length) {
441
+ yield emit(true);
34
442
  }
35
- throw new Error(LEGACY_XLS_UNSUPPORTED_MESSAGE);
36
443
  }
37
- throw new Error(XLS_NOT_A_WORKBOOK_MESSAGE);
38
444
  }
39
445
  }