@js-ak/excel-toolbox 1.8.3 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/build/cjs/lib/template/template-fs.js +2 -1
  2. package/build/cjs/lib/template/template-memory.js +2 -1
  3. package/build/cjs/lib/template/utils/column-letter-to-index.js +15 -0
  4. package/build/cjs/lib/template/utils/index.js +1 -1
  5. package/build/cjs/lib/template/utils/prepare-row-to-cells.js +2 -2
  6. package/build/cjs/lib/template/utils/validate-worksheet-xml.js +19 -9
  7. package/build/cjs/lib/utils/index.js +2 -0
  8. package/build/cjs/lib/utils/trim-and-join-multiline.js +32 -0
  9. package/build/cjs/lib/workbook-builder/default/border.js +18 -0
  10. package/build/cjs/lib/workbook-builder/default/cell-xf.js +15 -0
  11. package/build/cjs/lib/workbook-builder/default/fill.js +18 -0
  12. package/build/cjs/lib/workbook-builder/default/font.js +19 -0
  13. package/build/cjs/lib/workbook-builder/default/index.js +21 -0
  14. package/build/cjs/lib/workbook-builder/default/sheet-name.js +10 -0
  15. package/build/cjs/lib/workbook-builder/index.js +18 -0
  16. package/build/cjs/lib/workbook-builder/merge-cells/add.js +72 -0
  17. package/build/cjs/lib/workbook-builder/merge-cells/helpers/index.js +18 -0
  18. package/build/cjs/lib/workbook-builder/merge-cells/helpers/ranges-equal.js +17 -0
  19. package/build/cjs/lib/workbook-builder/merge-cells/helpers/ranges-intersect.js +17 -0
  20. package/build/cjs/lib/workbook-builder/merge-cells/index.js +18 -0
  21. package/build/cjs/lib/workbook-builder/merge-cells/remove.js +60 -0
  22. package/build/cjs/lib/workbook-builder/shared-string-ref/add.js +24 -0
  23. package/build/cjs/lib/workbook-builder/shared-string-ref/index.js +19 -0
  24. package/build/cjs/lib/workbook-builder/shared-string-ref/remove-all-from-sheet.js +66 -0
  25. package/build/cjs/lib/workbook-builder/shared-string-ref/remove.js +66 -0
  26. package/build/cjs/lib/workbook-builder/style-ref/add-or-get.js +94 -0
  27. package/build/cjs/lib/workbook-builder/style-ref/helpers/add-num-fmt.js +25 -0
  28. package/build/cjs/lib/workbook-builder/style-ref/helpers/border-to-xml.js +49 -0
  29. package/build/cjs/lib/workbook-builder/style-ref/helpers/fill-to-xml.js +51 -0
  30. package/build/cjs/lib/workbook-builder/style-ref/helpers/font-to-xml.js +112 -0
  31. package/build/cjs/lib/workbook-builder/style-ref/helpers/index.js +21 -0
  32. package/build/cjs/lib/workbook-builder/style-ref/helpers/reindex-style-map-after-removal.js +30 -0
  33. package/build/cjs/lib/workbook-builder/style-ref/index.js +19 -0
  34. package/build/cjs/lib/workbook-builder/style-ref/remove-all-from-sheet.js +26 -0
  35. package/build/cjs/lib/workbook-builder/style-ref/remove.js +52 -0
  36. package/build/cjs/lib/workbook-builder/types/app-xml-options.js +2 -0
  37. package/build/cjs/lib/workbook-builder/types/border-style.js +2 -0
  38. package/build/cjs/lib/workbook-builder/types/cell-data.js +2 -0
  39. package/build/cjs/lib/workbook-builder/types/cell-style.js +2 -0
  40. package/build/cjs/lib/workbook-builder/types/cell-type.js +2 -0
  41. package/build/cjs/lib/workbook-builder/types/cell-value.js +2 -0
  42. package/build/cjs/lib/workbook-builder/types/cell-xf.js +2 -0
  43. package/build/cjs/lib/workbook-builder/types/index.js +27 -0
  44. package/build/cjs/lib/workbook-builder/types/merge-cell.js +2 -0
  45. package/build/cjs/lib/workbook-builder/types/row-data.js +2 -0
  46. package/build/cjs/lib/workbook-builder/types/sheet-data.js +2 -0
  47. package/build/cjs/lib/workbook-builder/types/xml-node.js +2 -0
  48. package/build/cjs/lib/workbook-builder/utils/build-app-xml.js +51 -0
  49. package/build/cjs/lib/workbook-builder/utils/build-cell-children.js +59 -0
  50. package/build/cjs/lib/workbook-builder/utils/build-content-types-xml.js +42 -0
  51. package/build/cjs/lib/workbook-builder/utils/build-core-xml.js +27 -0
  52. package/build/cjs/lib/workbook-builder/utils/build-rels-xml.js +19 -0
  53. package/build/cjs/lib/workbook-builder/utils/build-shared-strings-xml.js +39 -0
  54. package/build/cjs/lib/workbook-builder/utils/build-styles-xml.js +178 -0
  55. package/build/cjs/lib/workbook-builder/utils/build-theme-xml.js +609 -0
  56. package/build/cjs/lib/workbook-builder/utils/build-workbook-rels-xml.js +58 -0
  57. package/build/cjs/lib/workbook-builder/utils/build-workbook-xml.js +26 -0
  58. package/build/cjs/lib/workbook-builder/utils/build-worksheet-xml.js +66 -0
  59. package/build/cjs/lib/workbook-builder/utils/build-xml.js +72 -0
  60. package/build/cjs/lib/workbook-builder/utils/constants.js +55 -0
  61. package/build/cjs/lib/workbook-builder/utils/date-to-excel-serial.js +16 -0
  62. package/build/cjs/lib/workbook-builder/utils/index.js +34 -0
  63. package/build/cjs/lib/workbook-builder/utils/initialize-files.js +40 -0
  64. package/build/cjs/lib/workbook-builder/utils/sheet.js +144 -0
  65. package/build/cjs/lib/workbook-builder/utils/write-shared-strings-xml.js +49 -0
  66. package/build/cjs/lib/workbook-builder/utils/write-styles-xml.js +196 -0
  67. package/build/cjs/lib/workbook-builder/utils/write-worksheet-xml.js +209 -0
  68. package/build/cjs/lib/workbook-builder/utils/write-xml.js +37 -0
  69. package/build/cjs/lib/workbook-builder/workbook-builder.js +414 -0
  70. package/build/esm/lib/template/template-fs.js +2 -1
  71. package/build/esm/lib/template/template-memory.js +2 -1
  72. package/build/esm/lib/template/utils/column-letter-to-index.js +12 -0
  73. package/build/esm/lib/template/utils/index.js +1 -1
  74. package/build/esm/lib/template/utils/prepare-row-to-cells.js +1 -1
  75. package/build/esm/lib/template/utils/validate-worksheet-xml.js +19 -9
  76. package/build/esm/lib/utils/index.js +2 -0
  77. package/build/esm/lib/utils/trim-and-join-multiline.js +29 -0
  78. package/build/esm/lib/workbook-builder/default/border.js +14 -0
  79. package/build/esm/lib/workbook-builder/default/cell-xf.js +11 -0
  80. package/build/esm/lib/workbook-builder/default/fill.js +14 -0
  81. package/build/esm/lib/workbook-builder/default/font.js +15 -0
  82. package/build/esm/lib/workbook-builder/default/index.js +5 -0
  83. package/build/esm/lib/workbook-builder/default/sheet-name.js +6 -0
  84. package/build/esm/lib/workbook-builder/index.js +2 -0
  85. package/build/esm/lib/workbook-builder/merge-cells/add.js +36 -0
  86. package/build/esm/lib/workbook-builder/merge-cells/helpers/index.js +2 -0
  87. package/build/esm/lib/workbook-builder/merge-cells/helpers/ranges-equal.js +14 -0
  88. package/build/esm/lib/workbook-builder/merge-cells/helpers/ranges-intersect.js +14 -0
  89. package/build/esm/lib/workbook-builder/merge-cells/index.js +2 -0
  90. package/build/esm/lib/workbook-builder/merge-cells/remove.js +24 -0
  91. package/build/esm/lib/workbook-builder/shared-string-ref/add.js +21 -0
  92. package/build/esm/lib/workbook-builder/shared-string-ref/index.js +3 -0
  93. package/build/esm/lib/workbook-builder/shared-string-ref/remove-all-from-sheet.js +63 -0
  94. package/build/esm/lib/workbook-builder/shared-string-ref/remove.js +63 -0
  95. package/build/esm/lib/workbook-builder/style-ref/add-or-get.js +58 -0
  96. package/build/esm/lib/workbook-builder/style-ref/helpers/add-num-fmt.js +21 -0
  97. package/build/esm/lib/workbook-builder/style-ref/helpers/border-to-xml.js +45 -0
  98. package/build/esm/lib/workbook-builder/style-ref/helpers/fill-to-xml.js +47 -0
  99. package/build/esm/lib/workbook-builder/style-ref/helpers/font-to-xml.js +75 -0
  100. package/build/esm/lib/workbook-builder/style-ref/helpers/index.js +5 -0
  101. package/build/esm/lib/workbook-builder/style-ref/helpers/reindex-style-map-after-removal.js +26 -0
  102. package/build/esm/lib/workbook-builder/style-ref/index.js +3 -0
  103. package/build/esm/lib/workbook-builder/style-ref/remove-all-from-sheet.js +23 -0
  104. package/build/esm/lib/workbook-builder/style-ref/remove.js +49 -0
  105. package/build/esm/lib/workbook-builder/types/app-xml-options.js +1 -0
  106. package/build/esm/lib/workbook-builder/types/border-style.js +1 -0
  107. package/build/esm/lib/workbook-builder/types/cell-data.js +1 -0
  108. package/build/esm/lib/workbook-builder/types/cell-style.js +1 -0
  109. package/build/esm/lib/workbook-builder/types/cell-type.js +1 -0
  110. package/build/esm/lib/workbook-builder/types/cell-value.js +1 -0
  111. package/build/esm/lib/workbook-builder/types/cell-xf.js +1 -0
  112. package/build/esm/lib/workbook-builder/types/index.js +11 -0
  113. package/build/esm/lib/workbook-builder/types/merge-cell.js +1 -0
  114. package/build/esm/lib/workbook-builder/types/row-data.js +1 -0
  115. package/build/esm/lib/workbook-builder/types/sheet-data.js +1 -0
  116. package/build/esm/lib/workbook-builder/types/xml-node.js +1 -0
  117. package/build/esm/lib/workbook-builder/utils/build-app-xml.js +48 -0
  118. package/build/esm/lib/workbook-builder/utils/build-cell-children.js +56 -0
  119. package/build/esm/lib/workbook-builder/utils/build-content-types-xml.js +39 -0
  120. package/build/esm/lib/workbook-builder/utils/build-core-xml.js +24 -0
  121. package/build/esm/lib/workbook-builder/utils/build-rels-xml.js +16 -0
  122. package/build/esm/lib/workbook-builder/utils/build-shared-strings-xml.js +36 -0
  123. package/build/esm/lib/workbook-builder/utils/build-styles-xml.js +142 -0
  124. package/build/esm/lib/workbook-builder/utils/build-theme-xml.js +606 -0
  125. package/build/esm/lib/workbook-builder/utils/build-workbook-rels-xml.js +55 -0
  126. package/build/esm/lib/workbook-builder/utils/build-workbook-xml.js +23 -0
  127. package/build/esm/lib/workbook-builder/utils/build-worksheet-xml.js +63 -0
  128. package/build/esm/lib/workbook-builder/utils/build-xml.js +69 -0
  129. package/build/esm/lib/workbook-builder/utils/constants.js +52 -0
  130. package/build/esm/lib/workbook-builder/utils/date-to-excel-serial.js +13 -0
  131. package/build/esm/lib/workbook-builder/utils/index.js +18 -0
  132. package/build/esm/lib/workbook-builder/utils/initialize-files.js +36 -0
  133. package/build/esm/lib/workbook-builder/utils/sheet.js +141 -0
  134. package/build/esm/lib/workbook-builder/utils/write-shared-strings-xml.js +43 -0
  135. package/build/esm/lib/workbook-builder/utils/write-styles-xml.js +157 -0
  136. package/build/esm/lib/workbook-builder/utils/write-worksheet-xml.js +203 -0
  137. package/build/esm/lib/workbook-builder/utils/write-xml.js +34 -0
  138. package/build/esm/lib/workbook-builder/workbook-builder.js +374 -0
  139. package/build/types/lib/template/utils/column-letter-to-index.d.ts +1 -0
  140. package/build/types/lib/template/utils/index.d.ts +1 -1
  141. package/build/types/lib/utils/index.d.ts +2 -0
  142. package/build/types/lib/utils/trim-and-join-multiline.d.ts +23 -0
  143. package/build/types/lib/workbook-builder/default/border.d.ts +7 -0
  144. package/build/types/lib/workbook-builder/default/cell-xf.d.ts +7 -0
  145. package/build/types/lib/workbook-builder/default/fill.d.ts +7 -0
  146. package/build/types/lib/workbook-builder/default/font.d.ts +21 -0
  147. package/build/types/lib/workbook-builder/default/index.d.ts +5 -0
  148. package/build/types/lib/workbook-builder/default/sheet-name.d.ts +6 -0
  149. package/build/types/lib/workbook-builder/index.d.ts +2 -0
  150. package/build/types/lib/workbook-builder/merge-cells/add.d.ts +15 -0
  151. package/build/types/lib/workbook-builder/merge-cells/helpers/index.d.ts +2 -0
  152. package/build/types/lib/workbook-builder/merge-cells/helpers/ranges-equal.d.ts +10 -0
  153. package/build/types/lib/workbook-builder/merge-cells/helpers/ranges-intersect.d.ts +10 -0
  154. package/build/types/lib/workbook-builder/merge-cells/index.d.ts +2 -0
  155. package/build/types/lib/workbook-builder/merge-cells/remove.d.ts +15 -0
  156. package/build/types/lib/workbook-builder/shared-string-ref/add.d.ts +13 -0
  157. package/build/types/lib/workbook-builder/shared-string-ref/index.d.ts +3 -0
  158. package/build/types/lib/workbook-builder/shared-string-ref/remove-all-from-sheet.d.ts +10 -0
  159. package/build/types/lib/workbook-builder/shared-string-ref/remove.d.ts +13 -0
  160. package/build/types/lib/workbook-builder/style-ref/add-or-get.d.ts +16 -0
  161. package/build/types/lib/workbook-builder/style-ref/helpers/add-num-fmt.d.ts +17 -0
  162. package/build/types/lib/workbook-builder/style-ref/helpers/border-to-xml.d.ts +16 -0
  163. package/build/types/lib/workbook-builder/style-ref/helpers/fill-to-xml.d.ts +17 -0
  164. package/build/types/lib/workbook-builder/style-ref/helpers/font-to-xml.d.ts +18 -0
  165. package/build/types/lib/workbook-builder/style-ref/helpers/index.d.ts +5 -0
  166. package/build/types/lib/workbook-builder/style-ref/helpers/reindex-style-map-after-removal.d.ts +15 -0
  167. package/build/types/lib/workbook-builder/style-ref/index.d.ts +3 -0
  168. package/build/types/lib/workbook-builder/style-ref/remove-all-from-sheet.d.ts +4 -0
  169. package/build/types/lib/workbook-builder/style-ref/remove.d.ts +18 -0
  170. package/build/types/lib/workbook-builder/types/app-xml-options.d.ts +9 -0
  171. package/build/types/lib/workbook-builder/types/border-style.d.ts +5 -0
  172. package/build/types/lib/workbook-builder/types/cell-data.d.ts +10 -0
  173. package/build/types/lib/workbook-builder/types/cell-style.d.ts +32 -0
  174. package/build/types/lib/workbook-builder/types/cell-type.d.ts +11 -0
  175. package/build/types/lib/workbook-builder/types/cell-value.d.ts +2 -0
  176. package/build/types/lib/workbook-builder/types/cell-xf.d.ts +13 -0
  177. package/build/types/lib/workbook-builder/types/index.d.ts +11 -0
  178. package/build/types/lib/workbook-builder/types/merge-cell.d.ts +6 -0
  179. package/build/types/lib/workbook-builder/types/row-data.d.ts +5 -0
  180. package/build/types/lib/workbook-builder/types/sheet-data.d.ts +13 -0
  181. package/build/types/lib/workbook-builder/types/xml-node.d.ts +11 -0
  182. package/build/types/lib/workbook-builder/utils/build-app-xml.d.ts +2 -0
  183. package/build/types/lib/workbook-builder/utils/build-cell-children.d.ts +9 -0
  184. package/build/types/lib/workbook-builder/utils/build-content-types-xml.d.ts +1 -0
  185. package/build/types/lib/workbook-builder/utils/build-core-xml.d.ts +1 -0
  186. package/build/types/lib/workbook-builder/utils/build-rels-xml.d.ts +1 -0
  187. package/build/types/lib/workbook-builder/utils/build-shared-strings-xml.d.ts +10 -0
  188. package/build/types/lib/workbook-builder/utils/build-styles-xml.d.ts +23 -0
  189. package/build/types/lib/workbook-builder/utils/build-theme-xml.d.ts +1 -0
  190. package/build/types/lib/workbook-builder/utils/build-workbook-rels-xml.d.ts +9 -0
  191. package/build/types/lib/workbook-builder/utils/build-workbook-xml.d.ts +3 -0
  192. package/build/types/lib/workbook-builder/utils/build-worksheet-xml.d.ts +2 -0
  193. package/build/types/lib/workbook-builder/utils/build-xml.d.ts +50 -0
  194. package/build/types/lib/workbook-builder/utils/constants.d.ts +47 -0
  195. package/build/types/lib/workbook-builder/utils/date-to-excel-serial.d.ts +9 -0
  196. package/build/types/lib/workbook-builder/utils/index.d.ts +18 -0
  197. package/build/types/lib/workbook-builder/utils/initialize-files.d.ts +13 -0
  198. package/build/types/lib/workbook-builder/utils/sheet.d.ts +21 -0
  199. package/build/types/lib/workbook-builder/utils/write-shared-strings-xml.d.ts +11 -0
  200. package/build/types/lib/workbook-builder/utils/write-styles-xml.d.ts +24 -0
  201. package/build/types/lib/workbook-builder/utils/write-worksheet-xml.d.ts +14 -0
  202. package/build/types/lib/workbook-builder/utils/write-xml.d.ts +3 -0
  203. package/build/types/lib/workbook-builder/workbook-builder.d.ts +110 -0
  204. package/package.json +1 -1
  205. /package/build/cjs/lib/{template/utils → utils}/escape-xml.js +0 -0
  206. /package/build/esm/lib/{template/utils → utils}/escape-xml.js +0 -0
  207. /package/build/types/lib/{template/utils → utils}/escape-xml.d.ts +0 -0
@@ -0,0 +1,203 @@
1
+ import fs from "node:fs";
2
+ import fsPromises from "node:fs/promises";
3
+ import path from "node:path";
4
+ import readline from "node:readline";
5
+ import { XML_DECLARATION, XML_NAMESPACES } from "./constants.js";
6
+ import { columnIndexToLetter } from "../../template/utils/column-index-to-letter.js";
7
+ import { columnLetterToIndex } from "../../template/utils/column-letter-to-index.js";
8
+ /**
9
+ * Writes a worksheet XML file to the given destination using a streaming approach.
10
+ *
11
+ * - Streams rows and cells to minimize memory usage
12
+ * - Tracks the worksheet dimension (min/max rows/cols) while streaming
13
+ * - Updates the <dimension> ref at the end by rewriting the file in a buffered pass
14
+ *
15
+ * @param destination - Absolute or relative file path for the worksheet XML
16
+ * @param rows - Map of rowIndex -> RowData with cells
17
+ * @param merges - Merge ranges to append after <sheetData>
18
+ * @returns Promise that resolves when the file is fully written and dimension updated
19
+ */
20
+ export async function writeWorksheetXml(destination, rows = new Map(), merges = []) {
21
+ // ensure folder exists
22
+ await fsPromises.mkdir(path.dirname(destination), { recursive: true });
23
+ const stream = fs.createWriteStream(destination, { encoding: "utf-8" });
24
+ // Track dimension incrementally while streaming
25
+ let minRow = Number.POSITIVE_INFINITY;
26
+ let maxRow = 0;
27
+ let minCol = Number.POSITIVE_INFINITY;
28
+ let maxCol = 0;
29
+ try {
30
+ // header
31
+ stream.write(XML_DECLARATION + "\n");
32
+ stream.write(`<worksheet xmlns="${XML_NAMESPACES.SPREADSHEET_ML}" xmlns:r="${XML_NAMESPACES.OFFICE_DOCUMENT}">\n`);
33
+ // dimension
34
+ stream.write(" <dimension ref=\"A1:A1\"/>\n");
35
+ // sheetViews
36
+ stream.write(" <sheetViews>\n");
37
+ stream.write(" <sheetView workbookViewId=\"0\"/>\n");
38
+ stream.write(" </sheetViews>\n");
39
+ // sheetFormatPr
40
+ stream.write(" <sheetFormatPr defaultRowHeight=\"15\"/>\n");
41
+ // sheetData start
42
+ stream.write(" <sheetData>\n");
43
+ // rows (stream, without accumulation)
44
+ const typeSetSkipping = new Set(["n"]);
45
+ let processedRows = 0;
46
+ for (const [rowNumber, row] of rows) {
47
+ if (row.cells.size > 0) {
48
+ if (rowNumber < minRow)
49
+ minRow = rowNumber;
50
+ if (rowNumber > maxRow)
51
+ maxRow = rowNumber;
52
+ }
53
+ // Build the row string
54
+ const rowStart = ` <row r="${rowNumber}">\n`;
55
+ const rowEnd = " </row>\n";
56
+ // write to stream with backpressure control
57
+ if (!stream.write(rowStart)) {
58
+ await new Promise(resolve => stream.once("drain", () => resolve()));
59
+ }
60
+ // if you need to stream cells, you can do so as well:
61
+ for (const [colNumber, cellData] of row.cells) {
62
+ const colIndex = columnLetterToIndex(colNumber) - 1;
63
+ if (colIndex < minCol)
64
+ minCol = colIndex;
65
+ if (colIndex > maxCol)
66
+ maxCol = colIndex;
67
+ const attrT = cellData.type && typeSetSkipping.has(cellData.type)
68
+ ? ""
69
+ : ` t="${cellData.type}"`;
70
+ const attrS = cellData.style?.index
71
+ ? ` s="${cellData.style?.index}"`
72
+ : "";
73
+ let cellXml = "";
74
+ if (cellData.isFormula) {
75
+ cellXml = ` <c r="${colNumber}${rowNumber}"${attrS}${attrT}><f>${cellData.value}</f></c>\n`;
76
+ }
77
+ else {
78
+ switch (cellData.type) {
79
+ case "b": {
80
+ cellXml = ` <c r="${colNumber}${rowNumber}"${attrS}${attrT}><v>${cellData.value ? "1" : "0"}</v></c>\n`;
81
+ break;
82
+ }
83
+ case "inlineStr": {
84
+ cellXml = ` <c r="${colNumber}${rowNumber}"${attrS}${attrT}><is><t>${cellData.value}</t></is></c>\n`;
85
+ break;
86
+ }
87
+ default: {
88
+ cellXml = ` <c r="${colNumber}${rowNumber}"${attrS}${attrT}><v>${cellData.value}</v></c>\n`;
89
+ break;
90
+ }
91
+ }
92
+ }
93
+ stream.write(cellXml);
94
+ // if (!stream.write(cellXml)) {
95
+ // await new Promise<void>(resolve => stream.once("drain", () => resolve()));
96
+ // }
97
+ }
98
+ if (!stream.write(rowEnd)) {
99
+ await new Promise(resolve => stream.once("drain", () => resolve()));
100
+ }
101
+ // Unload the event loop every 100 rows
102
+ processedRows++;
103
+ if (processedRows % 100 === 0) {
104
+ await new Promise(resolve => setImmediate(resolve));
105
+ }
106
+ // Unload the event loop every 100 rows
107
+ // rows.delete(rowNumber);
108
+ }
109
+ // sheetData end
110
+ stream.write(" </sheetData>\n");
111
+ // mergeCells
112
+ if (merges.length > 0) {
113
+ stream.write(` <mergeCells count="${merges.length}">\n`);
114
+ for (const merge of merges) {
115
+ if (merge.startCol < minCol)
116
+ minCol = merge.startCol;
117
+ if (merge.endCol > maxCol)
118
+ maxCol = merge.endCol;
119
+ if (merge.startRow < minRow)
120
+ minRow = merge.startRow;
121
+ if (merge.endRow > maxRow)
122
+ maxRow = merge.endRow;
123
+ const ref = `${columnIndexToLetter(merge.startCol)}${merge.startRow}:${columnIndexToLetter(merge.endCol)}${merge.endRow}`;
124
+ stream.write(` <mergeCell ref="${ref}"/>\n`);
125
+ }
126
+ stream.write(" </mergeCells>\n");
127
+ }
128
+ // close worksheet
129
+ stream.write("</worksheet>\n");
130
+ }
131
+ finally {
132
+ stream.end();
133
+ }
134
+ let finalDimensionRef = "A1:A1";
135
+ if (Number.isFinite(minCol) && Number.isFinite(minRow) && maxCol >= 0 && maxRow > 0) {
136
+ finalDimensionRef = `${columnIndexToLetter(minCol)}${minRow}:${columnIndexToLetter(maxCol)}${maxRow}`;
137
+ }
138
+ await new Promise((resolve, reject) => {
139
+ stream.on("error", reject);
140
+ stream.on("finish", resolve);
141
+ });
142
+ await updateWorksheetDimensionInFile(destination, finalDimensionRef);
143
+ return;
144
+ }
145
+ // async function updateWorksheetDimensionInFile(destination: string, dimensionRef: string): Promise<void> {
146
+ // const tempPath = `${destination}.tmp`;
147
+ // const readStream = fs.createReadStream(destination, { encoding: "utf-8" });
148
+ // const rl = readline.createInterface({ crlfDelay: Infinity, input: readStream });
149
+ // const writeStream = fs.createWriteStream(tempPath, { encoding: "utf-8" });
150
+ // let updated = false;
151
+ // const rlClosed = new Promise<void>(resolve => rl.once("close", resolve));
152
+ // for await (const line of rl) {
153
+ // let outLine = line;
154
+ // if (!updated && line.includes("<dimension")) {
155
+ // outLine = line.replace(/(<dimension[^>]*ref=")[^"]*("[^>]*\/>)/, `$1${dimensionRef}$2`);
156
+ // updated = true;
157
+ // }
158
+ // if (!writeStream.write(outLine + "\n")) {
159
+ // await new Promise<void>(resolve => writeStream.once("drain", resolve));
160
+ // }
161
+ // }
162
+ // await rlClosed;
163
+ // writeStream.end();
164
+ // await new Promise<void>(resolve => writeStream.once("finish", resolve));
165
+ // await fsPromises.rename(tempPath, destination);
166
+ // }
167
+ /**
168
+ * Updates the <dimension> ref attribute in an existing worksheet XML file.
169
+ * Performs a buffered line-by-line rewrite to a temporary file, then renames it in place.
170
+ *
171
+ * @param destination - Path to the worksheet XML file to update
172
+ * @param dimensionRef - Final dimension reference, e.g., "A1:C25"
173
+ */
174
+ async function updateWorksheetDimensionInFile(destination, dimensionRef) {
175
+ const tempPath = `${destination}.tmp`;
176
+ const readStream = fs.createReadStream(destination, { encoding: "utf-8" });
177
+ const rl = readline.createInterface({ crlfDelay: Infinity, input: readStream });
178
+ const writeStream = fs.createWriteStream(tempPath, { encoding: "utf-8" });
179
+ let updated = false;
180
+ let buffer = "";
181
+ const BUFFER_SIZE = 64 * 1024; // 64 KB
182
+ for await (const line of rl) {
183
+ let outLine = line;
184
+ if (!updated && line.includes("<dimension")) {
185
+ outLine = line.replace(/(<dimension[^>]*ref=")[^"]*("[^>]*\/>)/, `$1${dimensionRef}$2`);
186
+ updated = true;
187
+ }
188
+ buffer += outLine + "\n";
189
+ if (buffer.length >= BUFFER_SIZE) {
190
+ if (!writeStream.write(buffer)) {
191
+ await new Promise(resolve => writeStream.once("drain", resolve));
192
+ }
193
+ buffer = "";
194
+ }
195
+ }
196
+ // Write remaining buffer
197
+ if (buffer)
198
+ writeStream.write(buffer);
199
+ // Close streams
200
+ await new Promise(resolve => writeStream.end(resolve));
201
+ // Replace original file
202
+ await fsPromises.rename(tempPath, destination);
203
+ }
@@ -0,0 +1,34 @@
1
+ export async function writeXml(node, stream, level = 0, chunkSize = 100) {
2
+ const { attrs = {}, children = [], tag } = node;
3
+ const attrStr = Object.entries(attrs)
4
+ .filter(([, v]) => v !== undefined && v !== null)
5
+ .map(([k, v]) => ` ${k}="${v}"`)
6
+ .join("");
7
+ const gap = " ".repeat(level);
8
+ // No children → self-closing tag
9
+ if (!children.length) {
10
+ stream.write(`${gap}<${tag}${attrStr}/>\n`);
11
+ return;
12
+ }
13
+ // Single text child → inline formatting
14
+ if (children.length === 1 && typeof children[0] === "string" && !children[0].includes("<")) {
15
+ stream.write(`${gap}<${tag}${attrStr}>${children[0]}</${tag}>\n`);
16
+ return;
17
+ }
18
+ // Has children → recursive streaming
19
+ stream.write(`${gap}<${tag}${attrStr}>\n`);
20
+ let processed = 0;
21
+ for (const c of children) {
22
+ if (typeof c === "string") {
23
+ stream.write(`${" ".repeat(level + 1)}${c}\n`);
24
+ }
25
+ else {
26
+ await writeXml(c, stream, level + 1, chunkSize);
27
+ }
28
+ processed++;
29
+ if (processed % chunkSize === 0) {
30
+ await new Promise(resolve => setImmediate(resolve));
31
+ }
32
+ }
33
+ stream.write(`${gap}</${tag}>\n`);
34
+ }
@@ -0,0 +1,374 @@
1
+ import crypto from "node:crypto";
2
+ import fs from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import * as Zip from "../zip/index.js";
6
+ import { columnIndexToLetter, updateDimension } from "../template/utils/index.js";
7
+ import * as Utils from "./utils/index.js";
8
+ import * as Default from "./default/index.js";
9
+ import * as MergeCells from "./merge-cells/index.js";
10
+ import * as SharedStringRef from "./shared-string-ref/index.js";
11
+ import * as StyleRef from "./style-ref/index.js";
12
+ /**
13
+ * Builds Excel workbooks by composing sheets, styles, shared strings and merges,
14
+ * and provides methods to save to file or stream.
15
+ *
16
+ * @experimental This API is experimental and might change in future versions.
17
+ */
18
+ export class WorkbookBuilder {
19
+ /** In-memory representation of workbook files to be zipped. */
20
+ #files;
21
+ /** Collection of sheets keyed by sheet name. */
22
+ #sheets = new Map();
23
+ /** Shared strings storage used by cells of type "s". */
24
+ #sharedStrings = [];
25
+ /** Map for lookup of shared string indices (key = string, value = index). */
26
+ #sharedStringMap = new Map();
27
+ /** Workbook style collections. */
28
+ #borders;
29
+ #cellXfs;
30
+ #fills;
31
+ #fonts;
32
+ #numFmts;
33
+ /** Map of serialized style JSON to style index (xf). */
34
+ #styleMap = new Map();
35
+ /** Map caches for fast de-duplication of style components. */
36
+ #fontMap = new Map();
37
+ #fillMap = new Map();
38
+ #borderMap = new Map();
39
+ /** Merge cell ranges grouped by sheet name. */
40
+ #mergeCells = new Map();
41
+ /**
42
+ * Creates a new workbook with a default sheet and initial style collections.
43
+ *
44
+ * @param options.defaultSheetName - The name for the initial sheet
45
+ */
46
+ constructor({ defaultSheetName = Default.sheetName(), } = {}) {
47
+ this.#files = Utils.initializeFiles(defaultSheetName);
48
+ // Initialize base style collections
49
+ this.#borders = [Default.border()];
50
+ this.#fills = [Default.fill()];
51
+ this.#fonts = [Default.font()];
52
+ this.#numFmts = [];
53
+ this.#cellXfs = [Default.cellXf()];
54
+ // Seed component maps with defaults at index 0
55
+ this.#fontMap.set(JSON.stringify(this.#fonts[0]), 0);
56
+ this.#fillMap.set(JSON.stringify(this.#fills[0]), 0);
57
+ this.#borderMap.set(JSON.stringify(this.#borders[0]), 0);
58
+ const sheet = Utils.createSheet(defaultSheetName, {
59
+ addMerge: this.#addMerge.bind(this),
60
+ addOrGetStyle: this.#addOrGetStyle.bind(this),
61
+ addSharedString: this.#addSharedString.bind(this),
62
+ removeMerge: this.#removeMerge.bind(this),
63
+ });
64
+ this.#sheets.set(Default.sheetName(), sheet);
65
+ }
66
+ /** Returns the internal sheets map. */
67
+ get sheets() {
68
+ return this.#sheets;
69
+ }
70
+ /** Returns the shared strings array. */
71
+ get sharedStrings() {
72
+ return this.#sharedStrings;
73
+ }
74
+ /** Replaces the shared strings array. */
75
+ set sharedStrings(sharedStrings) {
76
+ this.#sharedStrings = sharedStrings;
77
+ }
78
+ /** Returns the shared string index map. */
79
+ get sharedStringMap() {
80
+ return this.#sharedStringMap;
81
+ }
82
+ /** Returns the borders collection. */
83
+ get borders() {
84
+ return this.#borders;
85
+ }
86
+ /** Returns the border cache map (serialized xml -> index). */
87
+ get bordersMap() {
88
+ return this.#borderMap;
89
+ }
90
+ /** Returns the cellXfs (style records). */
91
+ get cellXfs() {
92
+ return this.#cellXfs;
93
+ }
94
+ /** Returns the fills collection. */
95
+ get fills() {
96
+ return this.#fills;
97
+ }
98
+ /** Returns the fill cache map (serialized xml -> index). */
99
+ get fillsMap() {
100
+ return this.#fillMap;
101
+ }
102
+ /** Returns the fonts collection. */
103
+ get fonts() {
104
+ return this.#fonts;
105
+ }
106
+ /** Returns the font cache map (serialized xml -> index). */
107
+ get fontsMap() {
108
+ return this.#fontMap;
109
+ }
110
+ /** Returns the number formats collection. */
111
+ get numFmts() {
112
+ return this.#numFmts;
113
+ }
114
+ /** Returns the mapping from serialized style JSON to style index. */
115
+ get styleMap() {
116
+ return this.#styleMap;
117
+ }
118
+ /** Returns the merge ranges, grouped by sheet name. */
119
+ get mergeCells() {
120
+ return this.#mergeCells;
121
+ }
122
+ /** Shared strings */
123
+ /** Adds a shared string (or returns existing index) and tracks its usage by sheet. */
124
+ #addSharedString(str, sheetName) {
125
+ return SharedStringRef.add.bind(this)({ sheetName, str });
126
+ }
127
+ /** -------------- */
128
+ /** Style refs */
129
+ /** Adds a style or returns an existing style index. */
130
+ #addOrGetStyle(style) {
131
+ return StyleRef.addOrGet.bind(this)({ style });
132
+ }
133
+ ;
134
+ /** ---------- */
135
+ /** Merge cells */
136
+ /** Adds a merge range to a sheet. */
137
+ #addMerge(payload) {
138
+ return MergeCells.add.bind(this)(payload);
139
+ }
140
+ /** Removes a merge range from a sheet. */
141
+ #removeMerge(payload) {
142
+ return MergeCells.remove.bind(this)(payload);
143
+ }
144
+ /** Removes all merge ranges for a sheet. */
145
+ #removeSheetMerges(sheetName) {
146
+ this.mergeCells.delete(sheetName);
147
+ }
148
+ /** ----------- */
149
+ /** Adds or replaces a logical file content in the in-memory file map. */
150
+ #addFile(key, value) {
151
+ this.#files[key] = value;
152
+ }
153
+ /** Updates the docProps/app.xml content based on current sheet names. */
154
+ #updateAppXml() {
155
+ this.#addFile(Utils.FILE_PATHS.APP, Utils.buildAppXml({ sheetNames: Array.from(this.#sheets.keys()) }));
156
+ }
157
+ /** Updates the xl/workbook.xml content based on current sheets. */
158
+ #updateWorkbookXml() {
159
+ this.#addFile(Utils.FILE_PATHS.WORKBOOK, Utils.buildWorkbookXml(Array.from(this.#sheets.values())));
160
+ }
161
+ /** Updates the xl/_rels/workbook.xml.rels relationships for sheets. */
162
+ #updateWorkbookRels() {
163
+ this.#addFile(Utils.FILE_PATHS.WORKBOOK_RELS, Utils.buildWorkbookRels(this.#sheets.size));
164
+ }
165
+ /** Updates [Content_Types].xml with sheet overrides. */
166
+ #updateContentTypes() {
167
+ this.#addFile(Utils.FILE_PATHS.CONTENT_TYPES, Utils.buildContentTypesXml(this.#sheets.size));
168
+ }
169
+ /** Public methods */
170
+ /**
171
+ * Adds a new sheet to the workbook.
172
+ *
173
+ * @throws Error if a sheet with the same name already exists
174
+ * @param sheetName - Sheet name to add
175
+ * @returns The created sheet data
176
+ */
177
+ addSheet(sheetName) {
178
+ if (this.getSheet(sheetName)) {
179
+ throw new Error("Sheet with this name already exists");
180
+ }
181
+ const sheet = Utils.createSheet(sheetName, {
182
+ addMerge: this.#addMerge.bind(this),
183
+ addOrGetStyle: this.#addOrGetStyle.bind(this),
184
+ addSharedString: this.#addSharedString.bind(this),
185
+ removeMerge: this.#removeMerge.bind(this),
186
+ });
187
+ this.#sheets.set(sheetName, sheet);
188
+ // Add entry to app.xml
189
+ this.#updateAppXml();
190
+ // Add entry to workbook.xml
191
+ this.#updateWorkbookXml();
192
+ // Add relationship in workbook.xml.rels
193
+ this.#updateWorkbookRels();
194
+ // Add Override in [Content_Types].xml
195
+ this.#updateContentTypes();
196
+ return sheet;
197
+ }
198
+ /** Returns a sheet by name if it exists. */
199
+ getSheet(sheetName) {
200
+ return this.#sheets.get(sheetName);
201
+ }
202
+ /**
203
+ * Removes a sheet by name.
204
+ * If cleanup is enabled, also removes associated shared strings and styles.
205
+ *
206
+ * @param sheetName - Sheet name to remove
207
+ * @returns True if the sheet existed and was removed
208
+ */
209
+ removeSheet(sheetName) {
210
+ const sheet = this.#sheets.get(sheetName);
211
+ if (!sheet) {
212
+ throw new Error("Sheet not found: " + sheetName);
213
+ }
214
+ // Remove its merges
215
+ this.#removeSheetMerges(sheetName);
216
+ // Remove from collection
217
+ this.#sheets.delete(sheetName);
218
+ this.#updateAppXml();
219
+ this.#updateWorkbookXml();
220
+ this.#updateWorkbookRels();
221
+ this.#updateContentTypes();
222
+ return true;
223
+ }
224
+ /**
225
+ * Returns a snapshot of the workbook internals for inspection and tests.
226
+ * The returned structure is deeply frozen to avoid accidental mutations.
227
+ */
228
+ getInfo() {
229
+ function deepFreeze(obj) {
230
+ if (obj === null || obj === undefined) {
231
+ return obj;
232
+ }
233
+ if (typeof obj !== "object") {
234
+ // string | number | boolean | symbol
235
+ return obj;
236
+ }
237
+ if (Array.isArray(obj)) {
238
+ return Object.freeze(obj.map(item => deepFreeze(item)));
239
+ }
240
+ if (obj instanceof Map) {
241
+ const frozenMap = new Map(Array.from(obj.entries()).map(([k, v]) => [k, deepFreeze(v)]));
242
+ return Object.freeze(frozenMap);
243
+ }
244
+ if (obj instanceof Set) {
245
+ const frozenSet = new Set(Array.from(obj.values()).map(v => deepFreeze(v)));
246
+ return Object.freeze(frozenSet);
247
+ }
248
+ // XmlNode or generic object
249
+ const frozenObj = {};
250
+ for (const [k, v] of Object.entries(obj)) {
251
+ frozenObj[k] = deepFreeze(v);
252
+ }
253
+ return Object.freeze(frozenObj);
254
+ }
255
+ return deepFreeze({
256
+ mergeCells: new Map(this.#mergeCells),
257
+ sheetsNames: Array.from(this.#sheets.values()).map((sheet) => sheet.name),
258
+ sharedStringMap: new Map(this.#sharedStringMap),
259
+ sharedStrings: [...this.#sharedStrings],
260
+ styles: {
261
+ borders: [...this.#borders],
262
+ cellXfs: [...this.#cellXfs],
263
+ fills: [...this.#fills],
264
+ fonts: [...this.#fonts],
265
+ numFmts: [...this.#numFmts],
266
+ styleMap: new Map(this.#styleMap),
267
+ },
268
+ });
269
+ }
270
+ /**
271
+ * Generates workbook XML parts in-memory and writes a .xlsx zip to disk.
272
+ *
273
+ * @param path - Absolute or relative file path to write
274
+ */
275
+ async saveToFile(path) {
276
+ let index = 0;
277
+ for (const sheet of this.#sheets.values()) {
278
+ const merges = this.#mergeCells.get(sheet.name) || [];
279
+ const preparedMerges = merges.map(merge => `${columnIndexToLetter(merge.startCol)}${merge.startRow}:${columnIndexToLetter(merge.endCol)}${merge.endRow}`);
280
+ const xml = Utils.buildWorksheetXml(sheet.rows, preparedMerges);
281
+ const filePath = `xl/worksheets/sheet${++index}.xml`;
282
+ this.#addFile(filePath, updateDimension(xml));
283
+ }
284
+ if (this.#sharedStrings.length) {
285
+ const xml = Utils.buildSharedStringsXml(this.#sharedStrings);
286
+ this.#addFile(Utils.FILE_PATHS.SHARED_STRINGS, xml);
287
+ }
288
+ // Styles
289
+ this.#addFile(Utils.FILE_PATHS.STYLES, Utils.buildStylesXml({
290
+ borders: this.#borders,
291
+ cellXfs: this.#cellXfs,
292
+ fills: this.#fills,
293
+ fonts: this.#fonts,
294
+ numFmts: this.#numFmts,
295
+ }));
296
+ const zipBuffer = await Zip.create(this.#files);
297
+ await fs.writeFile(path, zipBuffer);
298
+ }
299
+ /**
300
+ * Saves the workbook to a writable stream using temporary files.
301
+ * This method creates temporary files from the in-memory data and streams them
302
+ * to the output stream, avoiding loading the entire file into memory.
303
+ *
304
+ * @param output - Writable stream to receive the Excel file
305
+ * @param options.destination - Optional existing directory to use instead of a system temp directory
306
+ * @param options.cleanup - Optional flag to cleanup the temporary directory after saving (default: true)
307
+ * @returns Promise that resolves when the file has been fully written
308
+ */
309
+ async saveToStream(output, options) {
310
+ const { cleanup = true, destination } = options ?? {};
311
+ // Determine a temp directory to assemble ZIP contents
312
+ let tempDir = "";
313
+ if (destination) {
314
+ // Create a random subdirectory inside provided destination
315
+ tempDir = path.join(destination, crypto.randomUUID());
316
+ await fs.mkdir(tempDir, { recursive: true });
317
+ }
318
+ else {
319
+ // Create a temp directory in OS temp
320
+ tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "excel-toolbox-", crypto.randomUUID()));
321
+ }
322
+ let index = 0;
323
+ const usedFileKeys = [];
324
+ // Write "xl/worksheets/sheet*.xml"
325
+ for (const sheet of this.#sheets.values()) {
326
+ const merges = this.#mergeCells.get(sheet.name) || [];
327
+ const filePath = `xl/worksheets/sheet${++index}.xml`;
328
+ usedFileKeys.push(filePath);
329
+ const fullPath = path.join(tempDir, ...filePath.split("/"));
330
+ await Utils.writeWorksheetXml(fullPath, sheet.rows, merges);
331
+ this.#addFile(filePath, "");
332
+ }
333
+ // Write "xl/sharedStrings.xml"
334
+ if (this.#sharedStrings.length) {
335
+ usedFileKeys.push(Utils.FILE_PATHS.SHARED_STRINGS);
336
+ const fullPath = path.join(tempDir, ...Utils.FILE_PATHS.SHARED_STRINGS.split("/"));
337
+ await Utils.writeSharedStringsXml(fullPath, this.#sharedStrings);
338
+ }
339
+ // Write "xl/styles.xml"
340
+ {
341
+ usedFileKeys.push(Utils.FILE_PATHS.STYLES);
342
+ const fullPath = path.join(tempDir, ...Utils.FILE_PATHS.STYLES.split("/"));
343
+ await Utils.writeStylesXml(fullPath, {
344
+ borders: this.#borders,
345
+ cellXfs: this.#cellXfs,
346
+ fills: this.#fills,
347
+ fonts: this.#fonts,
348
+ numFmts: this.#numFmts,
349
+ });
350
+ }
351
+ try {
352
+ // Write all files from memory to temporary files
353
+ const fileKeys = [];
354
+ for (const [key, value] of Object.entries(this.#files)) {
355
+ if (usedFileKeys.includes(key)) {
356
+ fileKeys.push(key);
357
+ continue;
358
+ }
359
+ const fullPath = path.join(tempDir, ...key.split("/"));
360
+ await fs.mkdir(path.dirname(fullPath), { recursive: true });
361
+ await fs.writeFile(fullPath, value);
362
+ fileKeys.push(key);
363
+ }
364
+ // Create ZIP archive and stream to output
365
+ await Zip.createWithStream(fileKeys, tempDir, output);
366
+ }
367
+ finally {
368
+ // Clean up temporary files
369
+ if (cleanup) {
370
+ await fs.rm(tempDir, { force: true, recursive: true });
371
+ }
372
+ }
373
+ }
374
+ }
@@ -0,0 +1 @@
1
+ export declare function columnLetterToIndex(col: string): number;
@@ -4,8 +4,8 @@ export * from "./check-row.js";
4
4
  export * from "./check-rows.js";
5
5
  export * from "./check-start-row.js";
6
6
  export * from "./column-index-to-letter.js";
7
+ export * from "./column-letter-to-index.js";
7
8
  export * from "./compare-columns.js";
8
- export * from "./escape-xml.js";
9
9
  export * from "./extract-xml-declaration.js";
10
10
  export * from "./found-arrays-in-replacements.js";
11
11
  export * from "./get-by-path.js";
@@ -1,3 +1,4 @@
1
+ export * from "./escape-xml.js";
1
2
  export * from "./get-max-row-number.js";
2
3
  export * from "./is-same-buffer.js";
3
4
  export * from "./remove-sheet-by-name.js";
@@ -5,3 +6,4 @@ export * from "./remove-sheet-from-content-types.js";
5
6
  export * from "./remove-sheet-from-rels.js";
6
7
  export * from "./remove-sheet-from-workbook.js";
7
8
  export * from "./shift-cell-ref.js";
9
+ export * from "./trim-and-join-multiline.js";
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Trims whitespace from multiline strings and joins them with a specified separator.
3
+ *
4
+ * This function processes multiline text by:
5
+ * - Splitting the input string by line breaks (handles both \n and \r\n)
6
+ * - Trimming whitespace from each line
7
+ * - Optionally normalizing multiple spaces to single spaces
8
+ * - Optionally filtering out empty lines
9
+ * - Joining the processed lines with a custom separator
10
+ *
11
+ * @param options - Configuration object for processing the multiline string
12
+ * @param options.inputString - The multiline string to process
13
+ * @param options.keepEmptyLines - Whether to preserve empty lines in the output (default: false)
14
+ * @param options.normalizeSpaces - Whether to normalize multiple consecutive spaces to single spaces (default: true)
15
+ * @param options.separator - The string to use when joining lines (default: " ")
16
+ * @returns The processed string with lines joined by the separator
17
+ */
18
+ export declare function trimAndJoinMultiline(options: {
19
+ inputString: string;
20
+ keepEmptyLines?: boolean;
21
+ normalizeSpaces?: boolean;
22
+ separator?: string;
23
+ }): string;
@@ -0,0 +1,7 @@
1
+ import { XmlNode } from "../types/index.js";
2
+ /**
3
+ * Creates a basic empty border XML node.
4
+ *
5
+ * @returns XML node representing an empty border with left, right, top, and bottom elements
6
+ */
7
+ export declare const border: () => XmlNode;
@@ -0,0 +1,7 @@
1
+ import { CellXf } from "../types/index.js";
2
+ /**
3
+ * Creates a default cell formatting object.
4
+ *
5
+ * @returns Cell formatting object with default IDs
6
+ */
7
+ export declare const cellXf: () => CellXf;