@bilig/excel-import 0.14.14

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 (198) hide show
  1. package/LICENSE +1 -0
  2. package/README.md +165 -0
  3. package/dist/index.d.ts +31 -0
  4. package/dist/index.js +748 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/workbook-import-content-types.d.ts +10 -0
  7. package/dist/workbook-import-content-types.js +30 -0
  8. package/dist/workbook-import-content-types.js.map +1 -0
  9. package/dist/workbook-import-helpers.d.ts +21 -0
  10. package/dist/workbook-import-helpers.js +77 -0
  11. package/dist/workbook-import-helpers.js.map +1 -0
  12. package/dist/workbook-import-preview.d.ts +19 -0
  13. package/dist/workbook-import-preview.js +12 -0
  14. package/dist/workbook-import-preview.js.map +1 -0
  15. package/dist/xlsx-array-formulas.d.ts +6 -0
  16. package/dist/xlsx-array-formulas.js +186 -0
  17. package/dist/xlsx-array-formulas.js.map +1 -0
  18. package/dist/xlsx-axis-entries.d.ts +3 -0
  19. package/dist/xlsx-axis-entries.js +90 -0
  20. package/dist/xlsx-axis-entries.js.map +1 -0
  21. package/dist/xlsx-calculation-settings.d.ts +9 -0
  22. package/dist/xlsx-calculation-settings.js +198 -0
  23. package/dist/xlsx-calculation-settings.js.map +1 -0
  24. package/dist/xlsx-cell-insertion.d.ts +11 -0
  25. package/dist/xlsx-cell-insertion.js +164 -0
  26. package/dist/xlsx-cell-insertion.js.map +1 -0
  27. package/dist/xlsx-cell-metadata.d.ts +15 -0
  28. package/dist/xlsx-cell-metadata.js +380 -0
  29. package/dist/xlsx-cell-metadata.js.map +1 -0
  30. package/dist/xlsx-chart-artifacts.d.ts +7 -0
  31. package/dist/xlsx-chart-artifacts.js +327 -0
  32. package/dist/xlsx-chart-artifacts.js.map +1 -0
  33. package/dist/xlsx-charts.d.ts +4 -0
  34. package/dist/xlsx-charts.js +671 -0
  35. package/dist/xlsx-charts.js.map +1 -0
  36. package/dist/xlsx-comment-vml.d.ts +11 -0
  37. package/dist/xlsx-comment-vml.js +292 -0
  38. package/dist/xlsx-comment-vml.js.map +1 -0
  39. package/dist/xlsx-comments.d.ts +7 -0
  40. package/dist/xlsx-comments.js +120 -0
  41. package/dist/xlsx-comments.js.map +1 -0
  42. package/dist/xlsx-conditional-formats.d.ts +5 -0
  43. package/dist/xlsx-conditional-formats.js +513 -0
  44. package/dist/xlsx-conditional-formats.js.map +1 -0
  45. package/dist/xlsx-control-artifacts.d.ts +7 -0
  46. package/dist/xlsx-control-artifacts.js +404 -0
  47. package/dist/xlsx-control-artifacts.js.map +1 -0
  48. package/dist/xlsx-data-model-artifacts.d.ts +4 -0
  49. package/dist/xlsx-data-model-artifacts.js +240 -0
  50. package/dist/xlsx-data-model-artifacts.js.map +1 -0
  51. package/dist/xlsx-data-table-formulas.d.ts +4 -0
  52. package/dist/xlsx-data-table-formulas.js +138 -0
  53. package/dist/xlsx-data-table-formulas.js.map +1 -0
  54. package/dist/xlsx-defined-names.d.ts +7 -0
  55. package/dist/xlsx-defined-names.js +292 -0
  56. package/dist/xlsx-defined-names.js.map +1 -0
  57. package/dist/xlsx-dimensions.d.ts +4 -0
  58. package/dist/xlsx-dimensions.js +495 -0
  59. package/dist/xlsx-dimensions.js.map +1 -0
  60. package/dist/xlsx-drawing-artifacts.d.ts +7 -0
  61. package/dist/xlsx-drawing-artifacts.js +477 -0
  62. package/dist/xlsx-drawing-artifacts.js.map +1 -0
  63. package/dist/xlsx-escaped-text.d.ts +2 -0
  64. package/dist/xlsx-escaped-text.js +22 -0
  65. package/dist/xlsx-escaped-text.js.map +1 -0
  66. package/dist/xlsx-export-xml.d.ts +8 -0
  67. package/dist/xlsx-export-xml.js +99 -0
  68. package/dist/xlsx-export-xml.js.map +1 -0
  69. package/dist/xlsx-export.d.ts +2 -0
  70. package/dist/xlsx-export.js +800 -0
  71. package/dist/xlsx-export.js.map +1 -0
  72. package/dist/xlsx-external-link-artifacts.d.ts +4 -0
  73. package/dist/xlsx-external-link-artifacts.js +317 -0
  74. package/dist/xlsx-external-link-artifacts.js.map +1 -0
  75. package/dist/xlsx-external-references.d.ts +29 -0
  76. package/dist/xlsx-external-references.js +356 -0
  77. package/dist/xlsx-external-references.js.map +1 -0
  78. package/dist/xlsx-filters.d.ts +4 -0
  79. package/dist/xlsx-filters.js +273 -0
  80. package/dist/xlsx-filters.js.map +1 -0
  81. package/dist/xlsx-formula-translation.d.ts +10 -0
  82. package/dist/xlsx-formula-translation.js +391 -0
  83. package/dist/xlsx-formula-translation.js.map +1 -0
  84. package/dist/xlsx-formulas.d.ts +2 -0
  85. package/dist/xlsx-formulas.js +136 -0
  86. package/dist/xlsx-formulas.js.map +1 -0
  87. package/dist/xlsx-freeze-panes.d.ts +4 -0
  88. package/dist/xlsx-freeze-panes.js +206 -0
  89. package/dist/xlsx-freeze-panes.js.map +1 -0
  90. package/dist/xlsx-hyperlinks.d.ts +5 -0
  91. package/dist/xlsx-hyperlinks.js +64 -0
  92. package/dist/xlsx-hyperlinks.js.map +1 -0
  93. package/dist/xlsx-ignored-errors.d.ts +4 -0
  94. package/dist/xlsx-ignored-errors.js +106 -0
  95. package/dist/xlsx-ignored-errors.js.map +1 -0
  96. package/dist/xlsx-import-cell-styles.d.ts +8 -0
  97. package/dist/xlsx-import-cell-styles.js +255 -0
  98. package/dist/xlsx-import-cell-styles.js.map +1 -0
  99. package/dist/xlsx-import-sheet-metadata.d.ts +40 -0
  100. package/dist/xlsx-import-sheet-metadata.js +41 -0
  101. package/dist/xlsx-import-sheet-metadata.js.map +1 -0
  102. package/dist/xlsx-import-warnings.d.ts +8 -0
  103. package/dist/xlsx-import-warnings.js +44 -0
  104. package/dist/xlsx-import-warnings.js.map +1 -0
  105. package/dist/xlsx-import-workbook-metadata.d.ts +28 -0
  106. package/dist/xlsx-import-workbook-metadata.js +29 -0
  107. package/dist/xlsx-import-workbook-metadata.js.map +1 -0
  108. package/dist/xlsx-macros.d.ts +10 -0
  109. package/dist/xlsx-macros.js +63 -0
  110. package/dist/xlsx-macros.js.map +1 -0
  111. package/dist/xlsx-merge-entries.d.ts +3 -0
  112. package/dist/xlsx-merge-entries.js +17 -0
  113. package/dist/xlsx-merge-entries.js.map +1 -0
  114. package/dist/xlsx-number-formats.d.ts +7 -0
  115. package/dist/xlsx-number-formats.js +222 -0
  116. package/dist/xlsx-number-formats.js.map +1 -0
  117. package/dist/xlsx-pivot-artifacts.d.ts +29 -0
  118. package/dist/xlsx-pivot-artifacts.js +292 -0
  119. package/dist/xlsx-pivot-artifacts.js.map +1 -0
  120. package/dist/xlsx-pivots.d.ts +10 -0
  121. package/dist/xlsx-pivots.js +589 -0
  122. package/dist/xlsx-pivots.js.map +1 -0
  123. package/dist/xlsx-print-page-setup.d.ts +6 -0
  124. package/dist/xlsx-print-page-setup.js +224 -0
  125. package/dist/xlsx-print-page-setup.js.map +1 -0
  126. package/dist/xlsx-printer-settings.d.ts +4 -0
  127. package/dist/xlsx-printer-settings.js +279 -0
  128. package/dist/xlsx-printer-settings.js.map +1 -0
  129. package/dist/xlsx-protected-ranges.d.ts +4 -0
  130. package/dist/xlsx-protected-ranges.js +183 -0
  131. package/dist/xlsx-protected-ranges.js.map +1 -0
  132. package/dist/xlsx-rich-text-artifacts.d.ts +4 -0
  133. package/dist/xlsx-rich-text-artifacts.js +303 -0
  134. package/dist/xlsx-rich-text-artifacts.js.map +1 -0
  135. package/dist/xlsx-sheet-properties.d.ts +4 -0
  136. package/dist/xlsx-sheet-properties.js +89 -0
  137. package/dist/xlsx-sheet-properties.js.map +1 -0
  138. package/dist/xlsx-sheet-protection.d.ts +4 -0
  139. package/dist/xlsx-sheet-protection.js +153 -0
  140. package/dist/xlsx-sheet-protection.js.map +1 -0
  141. package/dist/xlsx-sheet-visibility.d.ts +4 -0
  142. package/dist/xlsx-sheet-visibility.js +53 -0
  143. package/dist/xlsx-sheet-visibility.js.map +1 -0
  144. package/dist/xlsx-slicer-connection-artifacts.d.ts +4 -0
  145. package/dist/xlsx-slicer-connection-artifacts.js +426 -0
  146. package/dist/xlsx-slicer-connection-artifacts.js.map +1 -0
  147. package/dist/xlsx-sorts.d.ts +5 -0
  148. package/dist/xlsx-sorts.js +216 -0
  149. package/dist/xlsx-sorts.js.map +1 -0
  150. package/dist/xlsx-sparklines.d.ts +4 -0
  151. package/dist/xlsx-sparklines.js +115 -0
  152. package/dist/xlsx-sparklines.js.map +1 -0
  153. package/dist/xlsx-style-only-blank-cells.d.ts +3 -0
  154. package/dist/xlsx-style-only-blank-cells.js +96 -0
  155. package/dist/xlsx-style-only-blank-cells.js.map +1 -0
  156. package/dist/xlsx-style-runs.d.ts +12 -0
  157. package/dist/xlsx-style-runs.js +35 -0
  158. package/dist/xlsx-style-runs.js.map +1 -0
  159. package/dist/xlsx-styles.d.ts +25 -0
  160. package/dist/xlsx-styles.js +857 -0
  161. package/dist/xlsx-styles.js.map +1 -0
  162. package/dist/xlsx-tab-colors.d.ts +4 -0
  163. package/dist/xlsx-tab-colors.js +166 -0
  164. package/dist/xlsx-tab-colors.js.map +1 -0
  165. package/dist/xlsx-tables.d.ts +4 -0
  166. package/dist/xlsx-tables.js +371 -0
  167. package/dist/xlsx-tables.js.map +1 -0
  168. package/dist/xlsx-theme-artifacts.d.ts +6 -0
  169. package/dist/xlsx-theme-artifacts.js +126 -0
  170. package/dist/xlsx-theme-artifacts.js.map +1 -0
  171. package/dist/xlsx-threaded-comment-artifacts.d.ts +8 -0
  172. package/dist/xlsx-threaded-comment-artifacts.js +329 -0
  173. package/dist/xlsx-threaded-comment-artifacts.js.map +1 -0
  174. package/dist/xlsx-validations.d.ts +4 -0
  175. package/dist/xlsx-validations.js +542 -0
  176. package/dist/xlsx-validations.js.map +1 -0
  177. package/dist/xlsx-view-state.d.ts +8 -0
  178. package/dist/xlsx-view-state.js +144 -0
  179. package/dist/xlsx-view-state.js.map +1 -0
  180. package/dist/xlsx-workbook-properties.d.ts +5 -0
  181. package/dist/xlsx-workbook-properties.js +388 -0
  182. package/dist/xlsx-workbook-properties.js.map +1 -0
  183. package/dist/xlsx-workbook-protection.d.ts +4 -0
  184. package/dist/xlsx-workbook-protection.js +147 -0
  185. package/dist/xlsx-workbook-protection.js.map +1 -0
  186. package/dist/xlsx-workbook-sheet-paths.d.ts +4 -0
  187. package/dist/xlsx-workbook-sheet-paths.js +96 -0
  188. package/dist/xlsx-workbook-sheet-paths.js.map +1 -0
  189. package/dist/xlsx-worksheet-cells.d.ts +16 -0
  190. package/dist/xlsx-worksheet-cells.js +104 -0
  191. package/dist/xlsx-worksheet-cells.js.map +1 -0
  192. package/dist/xlsx-worksheet-text-values.d.ts +2 -0
  193. package/dist/xlsx-worksheet-text-values.js +136 -0
  194. package/dist/xlsx-worksheet-text-values.js.map +1 -0
  195. package/dist/xlsx-zip.d.ts +6 -0
  196. package/dist/xlsx-zip.js +12 -0
  197. package/dist/xlsx-zip.js.map +1 -0
  198. package/package.json +56 -0
@@ -0,0 +1,800 @@
1
+ import * as XLSX from 'xlsx';
2
+ import { unzipSync, zipSync } from 'fflate';
3
+ import { addExportArrayFormulasToXlsxBytes } from './xlsx-array-formulas.js';
4
+ import { addExportCellMetadataToXlsxBytes } from './xlsx-cell-metadata.js';
5
+ import { addMissingBlankCells, addMissingFormattedCells } from './xlsx-cell-insertion.js';
6
+ import { addExportCalculationSettingsToXlsxBytes } from './xlsx-calculation-settings.js';
7
+ import { addExportChartArtifactsToXlsxBytes } from './xlsx-chart-artifacts.js';
8
+ import { addExportChartsToXlsxBytes } from './xlsx-charts.js';
9
+ import { addExportLegacyCommentVmlToXlsxBytes } from './xlsx-comment-vml.js';
10
+ import { addExportCommentsToWorksheet } from './xlsx-comments.js';
11
+ import { addExportConditionalFormatsToXlsxBytes } from './xlsx-conditional-formats.js';
12
+ import { addExportControlArtifactsToXlsxBytes } from './xlsx-control-artifacts.js';
13
+ import { addExportDataModelArtifactsToXlsxBytes } from './xlsx-data-model-artifacts.js';
14
+ import { addExportDataTableFormulasToXlsxBytes } from './xlsx-data-table-formulas.js';
15
+ import { buildExportDefinedNames } from './xlsx-defined-names.js';
16
+ import { addExportDrawingArtifactsToXlsxBytes } from './xlsx-drawing-artifacts.js';
17
+ import { addExportExternalLinkArtifactsToXlsxBytes } from './xlsx-external-link-artifacts.js';
18
+ import { addExportWorksheetDimensionsToXlsxBytes, applyExportWorksheetDimensionsToWorksheetXml } from './xlsx-dimensions.js';
19
+ import { addExportFiltersToXlsxBytes } from './xlsx-filters.js';
20
+ import { addExportFreezePanesToXlsxBytes } from './xlsx-freeze-panes.js';
21
+ import { addExportPivotsToXlsxBytes } from './xlsx-pivots.js';
22
+ import { addExportPrintPageSetupToXlsxBytes } from './xlsx-print-page-setup.js';
23
+ import { addExportProtectedRangesToXlsxBytes } from './xlsx-protected-ranges.js';
24
+ import { addExportRichTextArtifactsToXlsxBytes } from './xlsx-rich-text-artifacts.js';
25
+ import { addExportSheetProtectionsToXlsxBytes } from './xlsx-sheet-protection.js';
26
+ import { addExportSortsToXlsxBytes } from './xlsx-sorts.js';
27
+ import { addExportSheetTabColorsToXlsxBytes } from './xlsx-tab-colors.js';
28
+ import { addExportTablesToXlsxBytes } from './xlsx-tables.js';
29
+ import { addExportThreadedCommentArtifactsToXlsxBytes } from './xlsx-threaded-comment-artifacts.js';
30
+ import { addExportThemeArtifactToXlsxBytes } from './xlsx-theme-artifacts.js';
31
+ import { addExportDataValidationsToXlsxBytes } from './xlsx-validations.js';
32
+ import { addExportViewStateToXlsxBytes } from './xlsx-view-state.js';
33
+ import { addExportWorkbookProtectionToXlsxBytes } from './xlsx-workbook-protection.js';
34
+ import { addExportWorkbookPropertiesToXlsxBytes } from './xlsx-workbook-properties.js';
35
+ import { addExportIgnoredErrorsToXlsxBytes } from './xlsx-ignored-errors.js';
36
+ import { decodePreservedVbaProjectPayload } from './xlsx-macros.js';
37
+ import { addExportPrinterSettingsToXlsxBytes } from './xlsx-printer-settings.js';
38
+ import { addExportWorksheetPropertiesToXlsxBytes } from './xlsx-sheet-properties.js';
39
+ import { applyExportSheetVisibilitiesToWorkbook } from './xlsx-sheet-visibility.js';
40
+ import { addExportSlicerConnectionArtifactsToXlsxBytes } from './xlsx-slicer-connection-artifacts.js';
41
+ import { addExportSparklinesToXlsxBytes } from './xlsx-sparklines.js';
42
+ import { addExportHyperlinksToWorksheet, hasExportHyperlinks } from './xlsx-hyperlinks.js';
43
+ import { addCustomNumberFormatsToStylesXml, customNumberFormatStartId, escapeXmlAttribute, getZipText, readXmlNumberAttribute, repairLeadingZeroNumberFormatIds, setXmlAttribute, setZipText, } from './xlsx-export-xml.js';
44
+ const worksheetCellElementPattern = /<(?:[A-Za-z_][\w.-]*:)?c\b(?:[^>"']|"[^"]*"|'[^']*')*\/>|<((?:[A-Za-z_][\w.-]*:)?c)\b(?:[^>"']|"[^"]*"|'[^']*')*>[\s\S]*?<\/\1>/gu;
45
+ const worksheetCellOpeningTagPattern = /<(?:[A-Za-z_][\w.-]*:)?c\b(?:[^>"']|"[^"]*"|'[^']*')*(?:\/>|>)/u;
46
+ function buildExportColumns(columns) {
47
+ if (!columns || columns.length === 0) {
48
+ return undefined;
49
+ }
50
+ const maxIndex = columns.reduce((max, column) => Math.max(max, column.index), -1);
51
+ if (maxIndex < 0) {
52
+ return undefined;
53
+ }
54
+ const output = Array.from({ length: maxIndex + 1 }, () => ({}));
55
+ for (const column of columns) {
56
+ const target = output[column.index];
57
+ if (!target) {
58
+ continue;
59
+ }
60
+ if (typeof column.size === 'number' && Number.isFinite(column.size) && column.size > 0) {
61
+ target.wpx = column.size;
62
+ }
63
+ if (column.hidden === true) {
64
+ target.hidden = true;
65
+ }
66
+ }
67
+ return output.some((column) => Object.keys(column).length > 0) ? output : undefined;
68
+ }
69
+ function buildExportRows(rows) {
70
+ if (!rows || rows.length === 0) {
71
+ return undefined;
72
+ }
73
+ const maxIndex = rows.reduce((max, row) => Math.max(max, row.index), -1);
74
+ if (maxIndex < 0) {
75
+ return undefined;
76
+ }
77
+ const output = Array.from({ length: maxIndex + 1 }, () => ({}));
78
+ for (const row of rows) {
79
+ const target = output[row.index];
80
+ if (!target) {
81
+ continue;
82
+ }
83
+ if (typeof row.size === 'number' && Number.isFinite(row.size) && row.size > 0) {
84
+ target.hpx = row.size;
85
+ }
86
+ if (row.hidden === true) {
87
+ target.hidden = true;
88
+ }
89
+ }
90
+ return output.some((row) => Object.keys(row).length > 0) ? output : undefined;
91
+ }
92
+ function readCellXfs(stylesXml) {
93
+ const match = /<((?:[A-Za-z_][\w.-]*:)?cellXfs)\b[^>]*>([\s\S]*?)<\/\1>/u.exec(stylesXml);
94
+ if (!match) {
95
+ return [];
96
+ }
97
+ const body = match[2] ?? '';
98
+ const entries = [];
99
+ let cursor = 0;
100
+ const nextXf = /<(?:[A-Za-z_][\w.-]*:)?xf\b/gu;
101
+ while (cursor < body.length) {
102
+ nextXf.lastIndex = cursor;
103
+ const startMatch = nextXf.exec(body);
104
+ if (!startMatch) {
105
+ break;
106
+ }
107
+ const start = startMatch.index;
108
+ const openingEnd = body.indexOf('>', start);
109
+ if (openingEnd < 0) {
110
+ break;
111
+ }
112
+ const tagName = /^<([^\s/>]+)/u.exec(body.slice(start, openingEnd + 1))?.[1];
113
+ if (!tagName) {
114
+ break;
115
+ }
116
+ if (body[openingEnd - 1] === '/') {
117
+ entries.push(body.slice(start, openingEnd + 1));
118
+ cursor = openingEnd + 1;
119
+ continue;
120
+ }
121
+ const closingTag = `</${tagName}>`;
122
+ const closingStart = body.indexOf(closingTag, openingEnd + 1);
123
+ if (closingStart < 0) {
124
+ break;
125
+ }
126
+ entries.push(body.slice(start, closingStart + closingTag.length));
127
+ cursor = closingStart + closingTag.length;
128
+ }
129
+ return entries;
130
+ }
131
+ function updateElementCount(openingAttributes, count) {
132
+ return /\scount="[^"]*"/u.test(openingAttributes)
133
+ ? openingAttributes.replace(/\scount="[^"]*"/u, ` count="${String(count)}"`)
134
+ : `${openingAttributes} count="${String(count)}"`;
135
+ }
136
+ function appendCustomCellXfsToStylesXml(stylesXml, xfs) {
137
+ if (xfs.length === 0) {
138
+ return stylesXml;
139
+ }
140
+ return stylesXml.replace(/<((?:[A-Za-z_][\w.-]*:)?cellXfs)\b([^>]*)>([\s\S]*?)<\/\1>/u, (_match, tagName, attributes, body) => {
141
+ const count = Array.from(body.matchAll(/<(?:[A-Za-z_][\w.-]*:)?xf\b/gu)).length + xfs.length;
142
+ return `<${tagName}${updateElementCount(attributes, count)}>${body}${xfs.join('')}</${tagName}>`;
143
+ });
144
+ }
145
+ function styleXfWithNumberFormat(xf, numberFormatId) {
146
+ return xf.replace(/<(?:[A-Za-z_][\w.-]*:)?xf\b[^>]*(?:\/>|>)/u, (openingTag) => setXmlAttribute(setXmlAttribute(setXmlAttribute(openingTag, 'numFmtId', String(numberFormatId)), 'applyNumberFormat', '1'), 'xfId', '0'));
147
+ }
148
+ class ExportNumberFormatRegistry {
149
+ baseXfs;
150
+ numberFormatIdsByCode = new Map();
151
+ styleIndexesByKey = new Map();
152
+ addedFormatIdsByCode = new Map();
153
+ addedXfs = [];
154
+ nextNumberFormatId;
155
+ constructor(stylesXml) {
156
+ this.baseXfs = readCellXfs(stylesXml);
157
+ const usedIds = [...stylesXml.matchAll(/\bnumFmtId="([0-9]+)"/gu)].map((match) => Number(match[1])).filter(Number.isSafeInteger);
158
+ this.nextNumberFormatId = Math.max(customNumberFormatStartId, ...usedIds.map((id) => id + 1));
159
+ }
160
+ styleIndexFor(baseStyleIndex, formatCode) {
161
+ const key = `${String(baseStyleIndex)}\u0000${formatCode}`;
162
+ const existingStyleIndex = this.styleIndexesByKey.get(key);
163
+ if (existingStyleIndex !== undefined) {
164
+ return existingStyleIndex;
165
+ }
166
+ const numberFormatId = this.numberFormatIdFor(formatCode);
167
+ const baseXf = this.baseXfs[baseStyleIndex] ?? '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" xfId="0"/>';
168
+ const styleIndex = this.baseXfs.length + this.addedXfs.length;
169
+ this.addedXfs.push(styleXfWithNumberFormat(baseXf, numberFormatId));
170
+ this.styleIndexesByKey.set(key, styleIndex);
171
+ return styleIndex;
172
+ }
173
+ apply(stylesXml) {
174
+ return appendCustomCellXfsToStylesXml(addCustomNumberFormatsToStylesXml(stylesXml, this.addedFormatIdsByCode), this.addedXfs);
175
+ }
176
+ numberFormatIdFor(formatCode) {
177
+ const existingId = this.numberFormatIdsByCode.get(formatCode);
178
+ if (existingId !== undefined) {
179
+ return existingId;
180
+ }
181
+ const id = this.nextNumberFormatId;
182
+ this.nextNumberFormatId += 1;
183
+ this.numberFormatIdsByCode.set(formatCode, id);
184
+ this.addedFormatIdsByCode.set(formatCode, id);
185
+ return id;
186
+ }
187
+ }
188
+ function sheetCellFormats(sheet) {
189
+ const formats = new Map();
190
+ for (const cell of sheet.cells) {
191
+ const format = cell.format?.trim();
192
+ if (format && format !== 'General') {
193
+ formats.set(cell.address, format);
194
+ }
195
+ }
196
+ return formats;
197
+ }
198
+ function decodeExportRange(startAddress, endAddress) {
199
+ const decoded = XLSX.utils.decode_range(`${startAddress}:${endAddress}`);
200
+ return {
201
+ s: {
202
+ r: Math.min(decoded.s.r, decoded.e.r),
203
+ c: Math.min(decoded.s.c, decoded.e.c),
204
+ },
205
+ e: {
206
+ r: Math.max(decoded.s.r, decoded.e.r),
207
+ c: Math.max(decoded.s.c, decoded.e.c),
208
+ },
209
+ };
210
+ }
211
+ function addRangeNumberFormats(formats, sheet, formatCodesById) {
212
+ for (const formatRange of sheet.metadata?.formatRanges ?? []) {
213
+ if (formatRange.range.sheetName !== sheet.name) {
214
+ continue;
215
+ }
216
+ const format = formatCodesById.get(formatRange.formatId)?.trim();
217
+ if (!format || format === 'General') {
218
+ continue;
219
+ }
220
+ const range = decodeExportRange(formatRange.range.startAddress, formatRange.range.endAddress);
221
+ for (let row = range.s.r; row <= range.e.r; row += 1) {
222
+ for (let col = range.s.c; col <= range.e.c; col += 1) {
223
+ formats.set(XLSX.utils.encode_cell({ r: row, c: col }), format);
224
+ }
225
+ }
226
+ }
227
+ }
228
+ function buildSheetCellFormats(sheet, formatCodesById) {
229
+ const formats = new Map();
230
+ addRangeNumberFormats(formats, sheet, formatCodesById);
231
+ for (const [address, format] of sheetCellFormats(sheet)) {
232
+ formats.set(address, format);
233
+ }
234
+ return formats;
235
+ }
236
+ function applyNumberFormatsToSheetXml(sheetXml, formats, registry) {
237
+ if (formats.size === 0) {
238
+ return sheetXml;
239
+ }
240
+ const handledAddresses = new Set();
241
+ let output = sheetXml.replace(worksheetCellElementPattern, (cellXml) => {
242
+ const openingTag = worksheetCellOpeningTagPattern.exec(cellXml)?.[0];
243
+ const address = openingTag ? /\br="([^"]+)"/u.exec(openingTag)?.[1] : undefined;
244
+ const format = address ? formats.get(address) : undefined;
245
+ if (!openingTag || !address || !format) {
246
+ return cellXml;
247
+ }
248
+ handledAddresses.add(address);
249
+ const baseStyleIndex = readXmlNumberAttribute(openingTag, 's') ?? 0;
250
+ const styleIndex = registry.styleIndexFor(baseStyleIndex, format);
251
+ return cellXml.replace(openingTag, setXmlAttribute(openingTag, 's', String(styleIndex)));
252
+ });
253
+ const missingCells = [...formats.entries()]
254
+ .filter(([address]) => !handledAddresses.has(address))
255
+ .map(([address, format]) => ({
256
+ address,
257
+ styleIndex: registry.styleIndexFor(0, format),
258
+ }));
259
+ if (missingCells.length > 0) {
260
+ output = addMissingFormattedCells(output, missingCells);
261
+ }
262
+ return output;
263
+ }
264
+ function preserveSnapshotNumberFormats(bytes, sheetFormats) {
265
+ if (sheetFormats.every((formats) => formats.size === 0)) {
266
+ return repairLeadingZeroNumberFormatIds(bytes);
267
+ }
268
+ const zip = unzipSync(repairLeadingZeroNumberFormatIds(bytes));
269
+ const stylesXml = getZipText(zip, 'xl/styles.xml');
270
+ if (!stylesXml) {
271
+ return zipSync(zip);
272
+ }
273
+ const registry = new ExportNumberFormatRegistry(stylesXml);
274
+ sheetFormats.forEach((formats, sheetIndex) => {
275
+ if (formats.size === 0) {
276
+ return;
277
+ }
278
+ const sheetPath = `xl/worksheets/sheet${String(sheetIndex + 1)}.xml`;
279
+ const sheetXml = getZipText(zip, sheetPath);
280
+ if (!sheetXml) {
281
+ return;
282
+ }
283
+ setZipText(zip, sheetPath, applyNumberFormatsToSheetXml(sheetXml, formats, registry));
284
+ });
285
+ setZipText(zip, 'xl/styles.xml', registry.apply(stylesXml));
286
+ return zipSync(zip);
287
+ }
288
+ function normalizeRgbColor(value) {
289
+ if (!value) {
290
+ return null;
291
+ }
292
+ const normalized = value.trim().replace(/^#/, '');
293
+ if (/^[0-9a-fA-F]{6}$/u.test(normalized)) {
294
+ return `FF${normalized.toUpperCase()}`;
295
+ }
296
+ if (/^[0-9a-fA-F]{8}$/u.test(normalized)) {
297
+ return normalized.toUpperCase();
298
+ }
299
+ return null;
300
+ }
301
+ function fastStyleFontXml(style) {
302
+ const font = style.font;
303
+ if (!font) {
304
+ return null;
305
+ }
306
+ const children = [];
307
+ if (font.family) {
308
+ children.push(`<name val="${escapeXmlAttribute(font.family)}"/>`);
309
+ }
310
+ if (font.size && font.size > 0) {
311
+ children.push(`<sz val="${String(font.size)}"/>`);
312
+ }
313
+ const color = normalizeRgbColor(font.color);
314
+ if (color) {
315
+ children.push(`<color rgb="${color}"/>`);
316
+ }
317
+ if (font.bold === true) {
318
+ children.push('<b/>');
319
+ }
320
+ if (font.italic === true) {
321
+ children.push('<i/>');
322
+ }
323
+ if (font.underline === true) {
324
+ children.push('<u/>');
325
+ }
326
+ return children.length > 0 ? `<font>${children.join('')}</font>` : null;
327
+ }
328
+ function fastStyleFillXml(style) {
329
+ const color = normalizeRgbColor(style.fill?.backgroundColor);
330
+ return color ? `<fill><patternFill patternType="solid"><fgColor rgb="${color}"/><bgColor indexed="64"/></patternFill></fill>` : null;
331
+ }
332
+ function fastBorderStyle(value) {
333
+ if (!value) {
334
+ return null;
335
+ }
336
+ if (value.style === 'dashed') {
337
+ return value.weight === 'medium' ? 'mediumDashed' : 'dashed';
338
+ }
339
+ if (value.style === 'dotted') {
340
+ return 'dotted';
341
+ }
342
+ if (value.style === 'double') {
343
+ return 'thick';
344
+ }
345
+ return value.weight;
346
+ }
347
+ function fastBorderSideXml(name, value) {
348
+ const borderStyle = fastBorderStyle(value);
349
+ if (!borderStyle || !value) {
350
+ return `<${name}/>`;
351
+ }
352
+ const color = normalizeRgbColor(value.color) ?? 'FF000000';
353
+ return `<${name} style="${borderStyle}"><color rgb="${color}"/></${name}>`;
354
+ }
355
+ function fastStyleBorderXml(style) {
356
+ const borders = style.borders;
357
+ if (!borders) {
358
+ return null;
359
+ }
360
+ return `<border>${fastBorderSideXml('left', borders.left)}${fastBorderSideXml('right', borders.right)}${fastBorderSideXml('top', borders.top)}${fastBorderSideXml('bottom', borders.bottom)}<diagonal/></border>`;
361
+ }
362
+ function fastStyleAlignmentXml(style) {
363
+ const alignment = style.alignment;
364
+ if (!alignment) {
365
+ return '';
366
+ }
367
+ const attributes = [
368
+ alignment.horizontal ? `horizontal="${alignment.horizontal}"` : null,
369
+ alignment.vertical ? `vertical="${alignment.vertical === 'middle' ? 'center' : alignment.vertical}"` : null,
370
+ alignment.wrap === true ? 'wrapText="1"' : null,
371
+ alignment.indent !== undefined && alignment.indent >= 0 ? `indent="${String(alignment.indent)}"` : null,
372
+ alignment.shrinkToFit === true ? 'shrinkToFit="1"' : null,
373
+ alignment.readingOrder !== undefined ? `readingOrder="${String(alignment.readingOrder)}"` : null,
374
+ alignment.textRotation !== undefined ? `textRotation="${String(alignment.textRotation)}"` : null,
375
+ alignment.justifyLastLine === true ? 'justifyLastLine="1"' : null,
376
+ ].filter((entry) => Boolean(entry));
377
+ return attributes.length > 0 ? `<alignment ${attributes.join(' ')}/>` : '';
378
+ }
379
+ function fastStyleProtectionXml(style) {
380
+ if (style.protection === undefined) {
381
+ return '';
382
+ }
383
+ const attributes = [
384
+ style.protection.locked !== undefined ? `locked="${style.protection.locked ? '1' : '0'}"` : null,
385
+ style.protection.hidden !== undefined ? `hidden="${style.protection.hidden ? '1' : '0'}"` : null,
386
+ ].filter((entry) => Boolean(entry));
387
+ return attributes.length > 0 ? `<protection ${attributes.join(' ')}/>` : '<protection/>';
388
+ }
389
+ function appendXmlChildren(xml, elementName, children) {
390
+ if (children.length === 0) {
391
+ const current = new RegExp(`<${elementName}\\b[^>]*>([\\s\\S]*?)</${elementName}>`, 'u').exec(xml)?.[1] ?? '';
392
+ return { xml, startIndex: Array.from(current.matchAll(new RegExp(`<${elementName.slice(0, -1)}\\b`, 'gu'))).length };
393
+ }
394
+ const pattern = new RegExp(`<${elementName}\\b([^>]*)>([\\s\\S]*?)</${elementName}>`, 'u');
395
+ const match = pattern.exec(xml);
396
+ if (!match) {
397
+ return { xml, startIndex: 0 };
398
+ }
399
+ const body = match[2] ?? '';
400
+ const childName = elementName.slice(0, -1);
401
+ const startIndex = Array.from(body.matchAll(new RegExp(`<${childName}\\b`, 'gu'))).length;
402
+ const nextXml = xml.replace(pattern, (_tag, attributes, existingBody) => {
403
+ const count = startIndex + children.length;
404
+ return `<${elementName}${updateElementCount(attributes, count)}>${existingBody}${children.join('')}</${elementName}>`;
405
+ });
406
+ return { xml: nextXml, startIndex };
407
+ }
408
+ function appendFastStyleXfs(stylesXml, styles) {
409
+ let output = stylesXml;
410
+ const fonts = styles.map(fastStyleFontXml);
411
+ const fills = styles.map(fastStyleFillXml);
412
+ const borders = styles.map(fastStyleBorderXml);
413
+ const appendedFonts = appendXmlChildren(output, 'fonts', fonts.filter((entry) => Boolean(entry)));
414
+ output = appendedFonts.xml;
415
+ const appendedFills = appendXmlChildren(output, 'fills', fills.filter((entry) => Boolean(entry)));
416
+ output = appendedFills.xml;
417
+ const appendedBorders = appendXmlChildren(output, 'borders', borders.filter((entry) => Boolean(entry)));
418
+ output = appendedBorders.xml;
419
+ let nextFontIndex = appendedFonts.startIndex;
420
+ let nextFillIndex = appendedFills.startIndex;
421
+ let nextBorderIndex = appendedBorders.startIndex;
422
+ const styleXfs = [];
423
+ const styleIndexById = new Map();
424
+ const baseStyleCount = readCellXfs(output).length;
425
+ styles.forEach((style, index) => {
426
+ const fontXml = fonts[index];
427
+ const fillXml = fills[index];
428
+ const borderXml = borders[index];
429
+ const fontId = fontXml ? nextFontIndex++ : 0;
430
+ const fillId = fillXml ? nextFillIndex++ : 0;
431
+ const borderId = borderXml ? nextBorderIndex++ : 0;
432
+ const alignmentXml = fastStyleAlignmentXml(style);
433
+ const protectionXml = fastStyleProtectionXml(style);
434
+ const childXml = `${alignmentXml}${protectionXml}`;
435
+ const attributes = [
436
+ 'numFmtId="0"',
437
+ `fontId="${String(fontId)}"`,
438
+ `fillId="${String(fillId)}"`,
439
+ `borderId="${String(borderId)}"`,
440
+ 'xfId="0"',
441
+ fontXml ? 'applyFont="1"' : null,
442
+ fillXml ? 'applyFill="1"' : null,
443
+ borderXml ? 'applyBorder="1"' : null,
444
+ alignmentXml ? 'applyAlignment="1"' : null,
445
+ protectionXml ? 'applyProtection="1"' : null,
446
+ ].filter((entry) => Boolean(entry));
447
+ styleIndexById.set(style.id, baseStyleCount + styleXfs.length);
448
+ styleXfs.push(childXml ? `<xf ${attributes.join(' ')}>${childXml}</xf>` : `<xf ${attributes.join(' ')}/>`);
449
+ });
450
+ return {
451
+ stylesXml: appendCustomCellXfsToStylesXml(output, styleXfs),
452
+ styleIndexById,
453
+ };
454
+ }
455
+ function applyStyleIndexesToSheetXml(sheetXml, sheet, styleIndexById) {
456
+ const stylesByAddress = new Map();
457
+ const rawStyleArtifactAddresses = new Set([
458
+ ...(sheet.metadata?.styleArtifacts?.cellStyleIndexes ?? []).map((entry) => entry.address),
459
+ ...(sheet.metadata?.styleArtifacts?.blankCellAddresses ?? []),
460
+ ]);
461
+ for (const styleRange of sheet.metadata?.styleRanges ?? []) {
462
+ if (styleRange.range.sheetName !== sheet.name) {
463
+ continue;
464
+ }
465
+ const styleIndex = styleIndexById.get(styleRange.styleId);
466
+ if (styleIndex === undefined) {
467
+ continue;
468
+ }
469
+ const range = decodeExportRange(styleRange.range.startAddress, styleRange.range.endAddress);
470
+ for (let row = range.s.r; row <= range.e.r; row += 1) {
471
+ for (let col = range.s.c; col <= range.e.c; col += 1) {
472
+ const address = XLSX.utils.encode_cell({ r: row, c: col });
473
+ if (!rawStyleArtifactAddresses.has(address)) {
474
+ stylesByAddress.set(address, styleIndex);
475
+ }
476
+ }
477
+ }
478
+ }
479
+ if (stylesByAddress.size === 0) {
480
+ return sheetXml;
481
+ }
482
+ const handledAddresses = new Set();
483
+ let output = sheetXml.replace(worksheetCellElementPattern, (cellXml) => {
484
+ const openingTag = worksheetCellOpeningTagPattern.exec(cellXml)?.[0];
485
+ const address = openingTag ? /\br="([^"]+)"/u.exec(openingTag)?.[1] : undefined;
486
+ const styleIndex = address ? stylesByAddress.get(address) : undefined;
487
+ if (!openingTag || !address || styleIndex === undefined) {
488
+ return cellXml;
489
+ }
490
+ handledAddresses.add(address);
491
+ return cellXml.replace(openingTag, setXmlAttribute(openingTag, 's', String(styleIndex)));
492
+ });
493
+ const missingCells = [...stylesByAddress.entries()]
494
+ .filter(([address]) => !handledAddresses.has(address))
495
+ .map(([address, styleIndex]) => ({ address, styleIndex }));
496
+ return missingCells.length > 0 ? addMissingFormattedCells(output, missingCells) : output;
497
+ }
498
+ function applyStyleArtifactIndexesToSheetXml(sheetXml, styleArtifacts) {
499
+ const cellStyleIndexes = styleArtifacts?.cellStyleIndexes ?? [];
500
+ const blankCellAddresses = styleArtifacts?.blankCellAddresses ?? [];
501
+ if (cellStyleIndexes.length === 0 && blankCellAddresses.length === 0) {
502
+ return sheetXml;
503
+ }
504
+ const stylesByAddress = new Map(cellStyleIndexes.map((entry) => [entry.address, entry.styleIndex]));
505
+ const handledAddresses = new Set();
506
+ const presentAddresses = new Set();
507
+ let output = sheetXml.replace(worksheetCellElementPattern, (cellXml) => {
508
+ const openingTag = worksheetCellOpeningTagPattern.exec(cellXml)?.[0];
509
+ const address = openingTag ? /\br="([^"]+)"/u.exec(openingTag)?.[1] : undefined;
510
+ const styleIndex = address ? stylesByAddress.get(address) : undefined;
511
+ if (!openingTag || !address) {
512
+ return cellXml;
513
+ }
514
+ presentAddresses.add(address);
515
+ if (styleIndex === undefined) {
516
+ return cellXml;
517
+ }
518
+ handledAddresses.add(address);
519
+ return cellXml.replace(openingTag, setXmlAttribute(openingTag, 's', String(styleIndex)));
520
+ });
521
+ const missingCells = [...stylesByAddress.entries()]
522
+ .filter(([address]) => !handledAddresses.has(address))
523
+ .map(([address, styleIndex]) => ({ address, styleIndex }));
524
+ if (missingCells.length > 0) {
525
+ output = addMissingFormattedCells(output, missingCells);
526
+ }
527
+ const missingBlankCellAddresses = blankCellAddresses.filter((address) => !handledAddresses.has(address) && !presentAddresses.has(address));
528
+ return missingBlankCellAddresses.length > 0 ? addMissingBlankCells(output, missingBlankCellAddresses) : output;
529
+ }
530
+ function preserveSnapshotStyles(bytes, snapshot) {
531
+ const styles = snapshot.workbook.metadata?.styles ?? [];
532
+ const hasStyleRanges = snapshot.sheets.some((sheet) => (sheet.metadata?.styleRanges?.length ?? 0) > 0);
533
+ if (styles.length === 0 || !hasStyleRanges) {
534
+ return bytes;
535
+ }
536
+ const zip = unzipSync(bytes);
537
+ const stylesXml = getZipText(zip, 'xl/styles.xml');
538
+ if (!stylesXml) {
539
+ return bytes;
540
+ }
541
+ const { stylesXml: nextStylesXml, styleIndexById } = appendFastStyleXfs(stylesXml, styles);
542
+ snapshot.sheets
543
+ .toSorted((left, right) => left.order - right.order)
544
+ .forEach((sheet, sheetIndex) => {
545
+ const sheetPath = `xl/worksheets/sheet${String(sheetIndex + 1)}.xml`;
546
+ const sheetXml = getZipText(zip, sheetPath);
547
+ if (sheetXml) {
548
+ setZipText(zip, sheetPath, applyExportWorksheetDimensionsToWorksheetXml(applyStyleIndexesToSheetXml(sheetXml, sheet, styleIndexById), sheet.metadata));
549
+ }
550
+ });
551
+ setZipText(zip, 'xl/styles.xml', nextStylesXml);
552
+ return zipSync(zip);
553
+ }
554
+ function addExportStyleArtifactsToXlsxBytes(bytes, snapshot) {
555
+ const stylesXml = snapshot.workbook.metadata?.styleArtifacts?.stylesXml;
556
+ if (!stylesXml) {
557
+ return bytes;
558
+ }
559
+ const zip = unzipSync(bytes);
560
+ setZipText(zip, 'xl/styles.xml', stylesXml);
561
+ snapshot.sheets
562
+ .toSorted((left, right) => left.order - right.order)
563
+ .forEach((sheet, sheetIndex) => {
564
+ const styleArtifacts = sheet.metadata?.styleArtifacts;
565
+ if (!styleArtifacts || (styleArtifacts.cellStyleIndexes.length === 0 && (styleArtifacts.blankCellAddresses?.length ?? 0) === 0)) {
566
+ return;
567
+ }
568
+ const sheetPath = `xl/worksheets/sheet${String(sheetIndex + 1)}.xml`;
569
+ const sheetXml = getZipText(zip, sheetPath);
570
+ if (sheetXml) {
571
+ setZipText(zip, sheetPath, applyStyleArtifactIndexesToSheetXml(sheetXml, styleArtifacts));
572
+ }
573
+ });
574
+ return zipSync(zip);
575
+ }
576
+ function buildExportMerges(merges) {
577
+ if (!merges || merges.length === 0) {
578
+ return undefined;
579
+ }
580
+ return merges.map((merge) => XLSX.utils.decode_range(`${merge.startAddress}:${merge.endAddress}`));
581
+ }
582
+ function updateWorksheetBounds(bounds, address) {
583
+ const decoded = XLSX.utils.decode_cell(address);
584
+ if (!bounds) {
585
+ return {
586
+ s: { r: decoded.r, c: decoded.c },
587
+ e: { r: decoded.r, c: decoded.c },
588
+ };
589
+ }
590
+ return {
591
+ s: {
592
+ r: Math.min(bounds.s.r, decoded.r),
593
+ c: Math.min(bounds.s.c, decoded.c),
594
+ },
595
+ e: {
596
+ r: Math.max(bounds.e.r, decoded.r),
597
+ c: Math.max(bounds.e.c, decoded.c),
598
+ },
599
+ };
600
+ }
601
+ function inferExportWorksheetRange(sheet) {
602
+ let bounds = null;
603
+ for (const cell of sheet.cells) {
604
+ bounds = updateWorksheetBounds(bounds, cell.address);
605
+ }
606
+ for (const merge of sheet.metadata?.merges ?? []) {
607
+ bounds = updateWorksheetBounds(bounds, merge.startAddress);
608
+ bounds = updateWorksheetBounds(bounds, merge.endAddress);
609
+ }
610
+ for (const thread of sheet.metadata?.commentThreads ?? []) {
611
+ bounds = updateWorksheetBounds(bounds, thread.address);
612
+ }
613
+ for (const hyperlink of sheet.metadata?.hyperlinks ?? []) {
614
+ bounds = updateWorksheetBounds(bounds, hyperlink.address);
615
+ }
616
+ for (const styleRange of sheet.metadata?.styleRanges ?? []) {
617
+ bounds = updateWorksheetBounds(bounds, styleRange.range.startAddress);
618
+ bounds = updateWorksheetBounds(bounds, styleRange.range.endAddress);
619
+ }
620
+ for (const formatRange of sheet.metadata?.formatRanges ?? []) {
621
+ bounds = updateWorksheetBounds(bounds, formatRange.range.startAddress);
622
+ bounds = updateWorksheetBounds(bounds, formatRange.range.endAddress);
623
+ }
624
+ return bounds ? XLSX.utils.encode_range(bounds) : undefined;
625
+ }
626
+ function cellTypeForLiteral(value) {
627
+ if (typeof value === 'number') {
628
+ return 'n';
629
+ }
630
+ if (typeof value === 'boolean') {
631
+ return 'b';
632
+ }
633
+ if (typeof value === 'string') {
634
+ return 's';
635
+ }
636
+ return undefined;
637
+ }
638
+ function buildExportCell(cell) {
639
+ const output = { t: 'z' };
640
+ if (cell.value !== undefined && cell.value !== null) {
641
+ const type = cellTypeForLiteral(cell.value);
642
+ if (type) {
643
+ output.t = type;
644
+ output.v = cell.value;
645
+ }
646
+ }
647
+ if (typeof cell.formula === 'string' && cell.formula.trim().length > 0) {
648
+ output.f = cell.formula.replace(/^=/, '');
649
+ if (output.v === undefined) {
650
+ output.t = 'e';
651
+ }
652
+ else {
653
+ output.t = output.t ?? 'n';
654
+ }
655
+ }
656
+ return output.v !== undefined || output.f !== undefined ? output : null;
657
+ }
658
+ const invalidExportSheetNameCharacters = ['[', ']', ':', '*', '?', '/', '\\'];
659
+ function normalizeExportSheetName(name, order, usedNames) {
660
+ let sanitized = name;
661
+ for (const character of invalidExportSheetNameCharacters) {
662
+ sanitized = sanitized.split(character).join(' ');
663
+ }
664
+ const baseName = sanitized.length > 0 ? sanitized : `Sheet${order + 1}`;
665
+ let candidate = baseName.slice(0, 31);
666
+ candidate = candidate.length > 0 ? candidate : `Sheet${order + 1}`;
667
+ let suffix = 1;
668
+ while (usedNames.has(candidate)) {
669
+ const suffixText = ` ${String(suffix)}`;
670
+ candidate = `${baseName.slice(0, 31 - suffixText.length)}${suffixText}`;
671
+ suffix += 1;
672
+ }
673
+ usedNames.add(candidate);
674
+ return candidate;
675
+ }
676
+ function toUint8Array(value) {
677
+ if (value instanceof Uint8Array) {
678
+ return new Uint8Array(value);
679
+ }
680
+ if (value instanceof ArrayBuffer) {
681
+ return new Uint8Array(value);
682
+ }
683
+ throw new Error('XLSX writer returned unsupported output bytes');
684
+ }
685
+ function applyMacroCodeNamesToWorkbook(workbook, macroPayload, exportSheetNamesByOriginalName) {
686
+ if (!macroPayload?.workbookCodeName && (!macroPayload?.sheetCodeNames || macroPayload.sheetCodeNames.length === 0)) {
687
+ return;
688
+ }
689
+ const workbookMetadata = {
690
+ ...workbook.Workbook,
691
+ };
692
+ if (macroPayload.workbookCodeName) {
693
+ workbookMetadata.WBProps = {
694
+ ...workbookMetadata.WBProps,
695
+ CodeName: macroPayload.workbookCodeName,
696
+ };
697
+ }
698
+ if (macroPayload.sheetCodeNames && macroPayload.sheetCodeNames.length > 0) {
699
+ const codeNamesByExportSheetName = new Map();
700
+ for (const entry of macroPayload.sheetCodeNames) {
701
+ const exportSheetName = exportSheetNamesByOriginalName.get(entry.sheetName) ?? entry.sheetName;
702
+ codeNamesByExportSheetName.set(exportSheetName, entry.codeName);
703
+ }
704
+ const existingSheets = workbookMetadata.Sheets ?? [];
705
+ workbookMetadata.Sheets = workbook.SheetNames.map((sheetName, index) => {
706
+ const codeName = codeNamesByExportSheetName.get(sheetName) ?? existingSheets[index]?.CodeName;
707
+ return {
708
+ ...existingSheets[index],
709
+ name: sheetName,
710
+ ...(codeName ? { CodeName: codeName } : {}),
711
+ };
712
+ });
713
+ }
714
+ workbook.Workbook = workbookMetadata;
715
+ }
716
+ export function exportXlsx(snapshot) {
717
+ const workbook = XLSX.utils.book_new();
718
+ const usedNames = new Set();
719
+ const exportSheetNamesByOriginalName = new Map();
720
+ const exportSheetIndexesByOriginalName = new Map();
721
+ const formatCodesById = new Map((snapshot.workbook.metadata?.formats ?? []).map((format) => [format.id, format.code]));
722
+ const exportSheetFormats = snapshot.sheets
723
+ .toSorted((left, right) => left.order - right.order)
724
+ .map((sheet) => buildSheetCellFormats(sheet, formatCodesById));
725
+ for (const sheet of snapshot.sheets.toSorted((left, right) => left.order - right.order)) {
726
+ const worksheet = {};
727
+ for (const cell of sheet.cells) {
728
+ const exportCell = buildExportCell(cell);
729
+ if (exportCell) {
730
+ worksheet[cell.address] = exportCell;
731
+ }
732
+ }
733
+ const ref = inferExportWorksheetRange(sheet);
734
+ if (ref) {
735
+ worksheet['!ref'] = ref;
736
+ }
737
+ const columns = buildExportColumns(sheet.metadata?.columns);
738
+ if (columns) {
739
+ worksheet['!cols'] = columns;
740
+ }
741
+ const rows = buildExportRows(sheet.metadata?.rows);
742
+ if (rows) {
743
+ worksheet['!rows'] = rows;
744
+ }
745
+ const merges = buildExportMerges(sheet.metadata?.merges);
746
+ if (merges) {
747
+ worksheet['!merges'] = merges;
748
+ }
749
+ addExportCommentsToWorksheet(worksheet, sheet.metadata?.commentThreads);
750
+ if (hasExportHyperlinks(sheet.metadata)) {
751
+ addExportHyperlinksToWorksheet(worksheet, sheet);
752
+ }
753
+ const exportSheetName = normalizeExportSheetName(sheet.name, sheet.order, usedNames);
754
+ exportSheetNamesByOriginalName.set(sheet.name, exportSheetName);
755
+ exportSheetIndexesByOriginalName.set(sheet.name, exportSheetIndexesByOriginalName.size);
756
+ XLSX.utils.book_append_sheet(workbook, worksheet, exportSheetName);
757
+ }
758
+ const definedNames = buildExportDefinedNames(snapshot.workbook.metadata?.definedNames, exportSheetNamesByOriginalName, exportSheetIndexesByOriginalName);
759
+ if (definedNames) {
760
+ workbook.Workbook = {
761
+ ...workbook.Workbook,
762
+ Names: definedNames,
763
+ };
764
+ }
765
+ const macroPayload = snapshot.workbook.metadata?.macroPayloads?.[0];
766
+ const preservedVbaProject = decodePreservedVbaProjectPayload(macroPayload);
767
+ if (preservedVbaProject) {
768
+ const macroWorkbook = workbook;
769
+ macroWorkbook.vbaraw = preservedVbaProject;
770
+ applyMacroCodeNamesToWorkbook(workbook, macroPayload, exportSheetNamesByOriginalName);
771
+ }
772
+ applyExportSheetVisibilitiesToWorkbook(workbook, snapshot);
773
+ const bytes = toUint8Array(XLSX.write(workbook, {
774
+ bookType: preservedVbaProject ? 'xlsm' : 'xlsx',
775
+ type: 'buffer',
776
+ bookVBA: Boolean(preservedVbaProject),
777
+ }));
778
+ const pivotBytes = addExportPivotsToXlsxBytes(addExportTablesToXlsxBytes(addExportDataValidationsToXlsxBytes(addExportConditionalFormatsToXlsxBytes(addExportSortsToXlsxBytes(addExportFiltersToXlsxBytes(addExportProtectedRangesToXlsxBytes(addExportSheetProtectionsToXlsxBytes(addExportViewStateToXlsxBytes(addExportFreezePanesToXlsxBytes(addExportWorksheetPropertiesToXlsxBytes(addExportSheetTabColorsToXlsxBytes(addExportCalculationSettingsToXlsxBytes(addExportWorkbookProtectionToXlsxBytes(addExportWorkbookPropertiesToXlsxBytes(bytes, snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot), snapshot, exportSheetNamesByOriginalName), snapshot, exportSheetNamesByOriginalName), snapshot, exportSheetNamesByOriginalName);
779
+ const chartArtifactBytes = addExportChartArtifactsToXlsxBytes(pivotBytes, snapshot);
780
+ const enrichedBytes = addExportChartsToXlsxBytes(chartArtifactBytes, snapshot, exportSheetNamesByOriginalName);
781
+ const richTextArtifactBytes = addExportRichTextArtifactsToXlsxBytes(enrichedBytes, snapshot);
782
+ const artifactStyledBytes = addExportStyleArtifactsToXlsxBytes(richTextArtifactBytes, snapshot);
783
+ const styledBytes = preserveSnapshotStyles(artifactStyledBytes, snapshot);
784
+ const formattedBytes = preserveSnapshotNumberFormats(styledBytes, exportSheetFormats);
785
+ const themeArtifactBytes = addExportThemeArtifactToXlsxBytes(formattedBytes, snapshot);
786
+ const dimensionedBytes = addExportWorksheetDimensionsToXlsxBytes(themeArtifactBytes, snapshot);
787
+ const drawingArtifactBytes = addExportDrawingArtifactsToXlsxBytes(dimensionedBytes, snapshot);
788
+ const ignoredErrorsBytes = addExportIgnoredErrorsToXlsxBytes(drawingArtifactBytes, snapshot);
789
+ const sparklineBytes = addExportSparklinesToXlsxBytes(ignoredErrorsBytes, snapshot);
790
+ const controlArtifactBytes = addExportControlArtifactsToXlsxBytes(sparklineBytes, snapshot);
791
+ const dataTableFormulaBytes = addExportDataTableFormulasToXlsxBytes(controlArtifactBytes, snapshot);
792
+ const arrayFormulaBytes = addExportArrayFormulasToXlsxBytes(dataTableFormulaBytes, snapshot);
793
+ const dataModelArtifactBytes = addExportDataModelArtifactsToXlsxBytes(arrayFormulaBytes, snapshot);
794
+ const externalLinkArtifactBytes = addExportExternalLinkArtifactsToXlsxBytes(dataModelArtifactBytes, snapshot);
795
+ const slicerConnectionArtifactBytes = addExportSlicerConnectionArtifactsToXlsxBytes(externalLinkArtifactBytes, snapshot);
796
+ const threadedCommentArtifactBytes = addExportThreadedCommentArtifactsToXlsxBytes(slicerConnectionArtifactBytes, snapshot);
797
+ const printPageSetupBytes = addExportPrintPageSetupToXlsxBytes(addExportLegacyCommentVmlToXlsxBytes(threadedCommentArtifactBytes, snapshot), snapshot);
798
+ return addExportCellMetadataToXlsxBytes(addExportPrinterSettingsToXlsxBytes(printPageSetupBytes, snapshot), snapshot);
799
+ }
800
+ //# sourceMappingURL=xlsx-export.js.map