@js-ak/excel-toolbox 1.8.2 → 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.
- package/build/cjs/lib/template/template-fs.js +2 -1
- package/build/cjs/lib/template/template-memory.js +2 -1
- package/build/cjs/lib/template/utils/column-letter-to-index.js +15 -0
- package/build/cjs/lib/template/utils/index.js +1 -1
- package/build/cjs/lib/template/utils/prepare-row-to-cells.js +2 -2
- package/build/cjs/lib/template/utils/validate-worksheet-xml.js +19 -9
- package/build/cjs/lib/utils/index.js +2 -0
- package/build/cjs/lib/utils/trim-and-join-multiline.js +32 -0
- package/build/cjs/lib/workbook-builder/default/border.js +18 -0
- package/build/cjs/lib/workbook-builder/default/cell-xf.js +15 -0
- package/build/cjs/lib/workbook-builder/default/fill.js +18 -0
- package/build/cjs/lib/workbook-builder/default/font.js +19 -0
- package/build/cjs/lib/workbook-builder/default/index.js +21 -0
- package/build/cjs/lib/workbook-builder/default/sheet-name.js +10 -0
- package/build/cjs/lib/workbook-builder/index.js +18 -0
- package/build/cjs/lib/workbook-builder/merge-cells/add.js +72 -0
- package/build/cjs/lib/workbook-builder/merge-cells/helpers/index.js +18 -0
- package/build/cjs/lib/workbook-builder/merge-cells/helpers/ranges-equal.js +17 -0
- package/build/cjs/lib/workbook-builder/merge-cells/helpers/ranges-intersect.js +17 -0
- package/build/cjs/lib/workbook-builder/merge-cells/index.js +18 -0
- package/build/cjs/lib/workbook-builder/merge-cells/remove.js +60 -0
- package/build/cjs/lib/workbook-builder/shared-string-ref/add.js +24 -0
- package/build/cjs/lib/workbook-builder/shared-string-ref/index.js +19 -0
- package/build/cjs/lib/workbook-builder/shared-string-ref/remove-all-from-sheet.js +66 -0
- package/build/cjs/lib/workbook-builder/shared-string-ref/remove.js +66 -0
- package/build/cjs/lib/workbook-builder/style-ref/add-or-get.js +94 -0
- package/build/cjs/lib/workbook-builder/style-ref/helpers/add-num-fmt.js +25 -0
- package/build/cjs/lib/workbook-builder/style-ref/helpers/border-to-xml.js +49 -0
- package/build/cjs/lib/workbook-builder/style-ref/helpers/fill-to-xml.js +51 -0
- package/build/cjs/lib/workbook-builder/style-ref/helpers/font-to-xml.js +112 -0
- package/build/cjs/lib/workbook-builder/style-ref/helpers/index.js +21 -0
- package/build/cjs/lib/workbook-builder/style-ref/helpers/reindex-style-map-after-removal.js +30 -0
- package/build/cjs/lib/workbook-builder/style-ref/index.js +19 -0
- package/build/cjs/lib/workbook-builder/style-ref/remove-all-from-sheet.js +26 -0
- package/build/cjs/lib/workbook-builder/style-ref/remove.js +52 -0
- package/build/cjs/lib/workbook-builder/types/app-xml-options.js +2 -0
- package/build/cjs/lib/workbook-builder/types/border-style.js +2 -0
- package/build/cjs/lib/workbook-builder/types/cell-data.js +2 -0
- package/build/cjs/lib/workbook-builder/types/cell-style.js +2 -0
- package/build/cjs/lib/workbook-builder/types/cell-type.js +2 -0
- package/build/cjs/lib/workbook-builder/types/cell-value.js +2 -0
- package/build/cjs/lib/workbook-builder/types/cell-xf.js +2 -0
- package/build/cjs/lib/workbook-builder/types/index.js +27 -0
- package/build/cjs/lib/workbook-builder/types/merge-cell.js +2 -0
- package/build/cjs/lib/workbook-builder/types/row-data.js +2 -0
- package/build/cjs/lib/workbook-builder/types/sheet-data.js +2 -0
- package/build/cjs/lib/workbook-builder/types/xml-node.js +2 -0
- package/build/cjs/lib/workbook-builder/utils/build-app-xml.js +51 -0
- package/build/cjs/lib/workbook-builder/utils/build-cell-children.js +59 -0
- package/build/cjs/lib/workbook-builder/utils/build-content-types-xml.js +42 -0
- package/build/cjs/lib/workbook-builder/utils/build-core-xml.js +27 -0
- package/build/cjs/lib/workbook-builder/utils/build-rels-xml.js +19 -0
- package/build/cjs/lib/workbook-builder/utils/build-shared-strings-xml.js +39 -0
- package/build/cjs/lib/workbook-builder/utils/build-styles-xml.js +178 -0
- package/build/cjs/lib/workbook-builder/utils/build-theme-xml.js +609 -0
- package/build/cjs/lib/workbook-builder/utils/build-workbook-rels-xml.js +58 -0
- package/build/cjs/lib/workbook-builder/utils/build-workbook-xml.js +26 -0
- package/build/cjs/lib/workbook-builder/utils/build-worksheet-xml.js +66 -0
- package/build/cjs/lib/workbook-builder/utils/build-xml.js +72 -0
- package/build/cjs/lib/workbook-builder/utils/constants.js +55 -0
- package/build/cjs/lib/workbook-builder/utils/date-to-excel-serial.js +16 -0
- package/build/cjs/lib/workbook-builder/utils/index.js +34 -0
- package/build/cjs/lib/workbook-builder/utils/initialize-files.js +40 -0
- package/build/cjs/lib/workbook-builder/utils/sheet.js +144 -0
- package/build/cjs/lib/workbook-builder/utils/write-shared-strings-xml.js +49 -0
- package/build/cjs/lib/workbook-builder/utils/write-styles-xml.js +196 -0
- package/build/cjs/lib/workbook-builder/utils/write-worksheet-xml.js +209 -0
- package/build/cjs/lib/workbook-builder/utils/write-xml.js +37 -0
- package/build/cjs/lib/workbook-builder/workbook-builder.js +414 -0
- package/build/cjs/lib/zip/utils/to-bytes.js +19 -11
- package/build/esm/lib/template/template-fs.js +2 -1
- package/build/esm/lib/template/template-memory.js +2 -1
- package/build/esm/lib/template/utils/column-letter-to-index.js +12 -0
- package/build/esm/lib/template/utils/index.js +1 -1
- package/build/esm/lib/template/utils/prepare-row-to-cells.js +1 -1
- package/build/esm/lib/template/utils/validate-worksheet-xml.js +19 -9
- package/build/esm/lib/utils/index.js +2 -0
- package/build/esm/lib/utils/trim-and-join-multiline.js +29 -0
- package/build/esm/lib/workbook-builder/default/border.js +14 -0
- package/build/esm/lib/workbook-builder/default/cell-xf.js +11 -0
- package/build/esm/lib/workbook-builder/default/fill.js +14 -0
- package/build/esm/lib/workbook-builder/default/font.js +15 -0
- package/build/esm/lib/workbook-builder/default/index.js +5 -0
- package/build/esm/lib/workbook-builder/default/sheet-name.js +6 -0
- package/build/esm/lib/workbook-builder/index.js +2 -0
- package/build/esm/lib/workbook-builder/merge-cells/add.js +36 -0
- package/build/esm/lib/workbook-builder/merge-cells/helpers/index.js +2 -0
- package/build/esm/lib/workbook-builder/merge-cells/helpers/ranges-equal.js +14 -0
- package/build/esm/lib/workbook-builder/merge-cells/helpers/ranges-intersect.js +14 -0
- package/build/esm/lib/workbook-builder/merge-cells/index.js +2 -0
- package/build/esm/lib/workbook-builder/merge-cells/remove.js +24 -0
- package/build/esm/lib/workbook-builder/shared-string-ref/add.js +21 -0
- package/build/esm/lib/workbook-builder/shared-string-ref/index.js +3 -0
- package/build/esm/lib/workbook-builder/shared-string-ref/remove-all-from-sheet.js +63 -0
- package/build/esm/lib/workbook-builder/shared-string-ref/remove.js +63 -0
- package/build/esm/lib/workbook-builder/style-ref/add-or-get.js +58 -0
- package/build/esm/lib/workbook-builder/style-ref/helpers/add-num-fmt.js +21 -0
- package/build/esm/lib/workbook-builder/style-ref/helpers/border-to-xml.js +45 -0
- package/build/esm/lib/workbook-builder/style-ref/helpers/fill-to-xml.js +47 -0
- package/build/esm/lib/workbook-builder/style-ref/helpers/font-to-xml.js +75 -0
- package/build/esm/lib/workbook-builder/style-ref/helpers/index.js +5 -0
- package/build/esm/lib/workbook-builder/style-ref/helpers/reindex-style-map-after-removal.js +26 -0
- package/build/esm/lib/workbook-builder/style-ref/index.js +3 -0
- package/build/esm/lib/workbook-builder/style-ref/remove-all-from-sheet.js +23 -0
- package/build/esm/lib/workbook-builder/style-ref/remove.js +49 -0
- package/build/esm/lib/workbook-builder/types/app-xml-options.js +1 -0
- package/build/esm/lib/workbook-builder/types/border-style.js +1 -0
- package/build/esm/lib/workbook-builder/types/cell-data.js +1 -0
- package/build/esm/lib/workbook-builder/types/cell-style.js +1 -0
- package/build/esm/lib/workbook-builder/types/cell-type.js +1 -0
- package/build/esm/lib/workbook-builder/types/cell-value.js +1 -0
- package/build/esm/lib/workbook-builder/types/cell-xf.js +1 -0
- package/build/esm/lib/workbook-builder/types/index.js +11 -0
- package/build/esm/lib/workbook-builder/types/merge-cell.js +1 -0
- package/build/esm/lib/workbook-builder/types/row-data.js +1 -0
- package/build/esm/lib/workbook-builder/types/sheet-data.js +1 -0
- package/build/esm/lib/workbook-builder/types/xml-node.js +1 -0
- package/build/esm/lib/workbook-builder/utils/build-app-xml.js +48 -0
- package/build/esm/lib/workbook-builder/utils/build-cell-children.js +56 -0
- package/build/esm/lib/workbook-builder/utils/build-content-types-xml.js +39 -0
- package/build/esm/lib/workbook-builder/utils/build-core-xml.js +24 -0
- package/build/esm/lib/workbook-builder/utils/build-rels-xml.js +16 -0
- package/build/esm/lib/workbook-builder/utils/build-shared-strings-xml.js +36 -0
- package/build/esm/lib/workbook-builder/utils/build-styles-xml.js +142 -0
- package/build/esm/lib/workbook-builder/utils/build-theme-xml.js +606 -0
- package/build/esm/lib/workbook-builder/utils/build-workbook-rels-xml.js +55 -0
- package/build/esm/lib/workbook-builder/utils/build-workbook-xml.js +23 -0
- package/build/esm/lib/workbook-builder/utils/build-worksheet-xml.js +63 -0
- package/build/esm/lib/workbook-builder/utils/build-xml.js +69 -0
- package/build/esm/lib/workbook-builder/utils/constants.js +52 -0
- package/build/esm/lib/workbook-builder/utils/date-to-excel-serial.js +13 -0
- package/build/esm/lib/workbook-builder/utils/index.js +18 -0
- package/build/esm/lib/workbook-builder/utils/initialize-files.js +36 -0
- package/build/esm/lib/workbook-builder/utils/sheet.js +141 -0
- package/build/esm/lib/workbook-builder/utils/write-shared-strings-xml.js +43 -0
- package/build/esm/lib/workbook-builder/utils/write-styles-xml.js +157 -0
- package/build/esm/lib/workbook-builder/utils/write-worksheet-xml.js +203 -0
- package/build/esm/lib/workbook-builder/utils/write-xml.js +34 -0
- package/build/esm/lib/workbook-builder/workbook-builder.js +374 -0
- package/build/esm/lib/zip/utils/to-bytes.js +19 -11
- package/build/types/lib/template/utils/column-letter-to-index.d.ts +1 -0
- package/build/types/lib/template/utils/index.d.ts +1 -1
- package/build/types/lib/utils/index.d.ts +2 -0
- package/build/types/lib/utils/trim-and-join-multiline.d.ts +23 -0
- package/build/types/lib/workbook-builder/default/border.d.ts +7 -0
- package/build/types/lib/workbook-builder/default/cell-xf.d.ts +7 -0
- package/build/types/lib/workbook-builder/default/fill.d.ts +7 -0
- package/build/types/lib/workbook-builder/default/font.d.ts +21 -0
- package/build/types/lib/workbook-builder/default/index.d.ts +5 -0
- package/build/types/lib/workbook-builder/default/sheet-name.d.ts +6 -0
- package/build/types/lib/workbook-builder/index.d.ts +2 -0
- package/build/types/lib/workbook-builder/merge-cells/add.d.ts +15 -0
- package/build/types/lib/workbook-builder/merge-cells/helpers/index.d.ts +2 -0
- package/build/types/lib/workbook-builder/merge-cells/helpers/ranges-equal.d.ts +10 -0
- package/build/types/lib/workbook-builder/merge-cells/helpers/ranges-intersect.d.ts +10 -0
- package/build/types/lib/workbook-builder/merge-cells/index.d.ts +2 -0
- package/build/types/lib/workbook-builder/merge-cells/remove.d.ts +15 -0
- package/build/types/lib/workbook-builder/shared-string-ref/add.d.ts +13 -0
- package/build/types/lib/workbook-builder/shared-string-ref/index.d.ts +3 -0
- package/build/types/lib/workbook-builder/shared-string-ref/remove-all-from-sheet.d.ts +10 -0
- package/build/types/lib/workbook-builder/shared-string-ref/remove.d.ts +13 -0
- package/build/types/lib/workbook-builder/style-ref/add-or-get.d.ts +16 -0
- package/build/types/lib/workbook-builder/style-ref/helpers/add-num-fmt.d.ts +17 -0
- package/build/types/lib/workbook-builder/style-ref/helpers/border-to-xml.d.ts +16 -0
- package/build/types/lib/workbook-builder/style-ref/helpers/fill-to-xml.d.ts +17 -0
- package/build/types/lib/workbook-builder/style-ref/helpers/font-to-xml.d.ts +18 -0
- package/build/types/lib/workbook-builder/style-ref/helpers/index.d.ts +5 -0
- package/build/types/lib/workbook-builder/style-ref/helpers/reindex-style-map-after-removal.d.ts +15 -0
- package/build/types/lib/workbook-builder/style-ref/index.d.ts +3 -0
- package/build/types/lib/workbook-builder/style-ref/remove-all-from-sheet.d.ts +4 -0
- package/build/types/lib/workbook-builder/style-ref/remove.d.ts +18 -0
- package/build/types/lib/workbook-builder/types/app-xml-options.d.ts +9 -0
- package/build/types/lib/workbook-builder/types/border-style.d.ts +5 -0
- package/build/types/lib/workbook-builder/types/cell-data.d.ts +10 -0
- package/build/types/lib/workbook-builder/types/cell-style.d.ts +32 -0
- package/build/types/lib/workbook-builder/types/cell-type.d.ts +11 -0
- package/build/types/lib/workbook-builder/types/cell-value.d.ts +2 -0
- package/build/types/lib/workbook-builder/types/cell-xf.d.ts +13 -0
- package/build/types/lib/workbook-builder/types/index.d.ts +11 -0
- package/build/types/lib/workbook-builder/types/merge-cell.d.ts +6 -0
- package/build/types/lib/workbook-builder/types/row-data.d.ts +5 -0
- package/build/types/lib/workbook-builder/types/sheet-data.d.ts +13 -0
- package/build/types/lib/workbook-builder/types/xml-node.d.ts +11 -0
- package/build/types/lib/workbook-builder/utils/build-app-xml.d.ts +2 -0
- package/build/types/lib/workbook-builder/utils/build-cell-children.d.ts +9 -0
- package/build/types/lib/workbook-builder/utils/build-content-types-xml.d.ts +1 -0
- package/build/types/lib/workbook-builder/utils/build-core-xml.d.ts +1 -0
- package/build/types/lib/workbook-builder/utils/build-rels-xml.d.ts +1 -0
- package/build/types/lib/workbook-builder/utils/build-shared-strings-xml.d.ts +10 -0
- package/build/types/lib/workbook-builder/utils/build-styles-xml.d.ts +23 -0
- package/build/types/lib/workbook-builder/utils/build-theme-xml.d.ts +1 -0
- package/build/types/lib/workbook-builder/utils/build-workbook-rels-xml.d.ts +9 -0
- package/build/types/lib/workbook-builder/utils/build-workbook-xml.d.ts +3 -0
- package/build/types/lib/workbook-builder/utils/build-worksheet-xml.d.ts +2 -0
- package/build/types/lib/workbook-builder/utils/build-xml.d.ts +50 -0
- package/build/types/lib/workbook-builder/utils/constants.d.ts +47 -0
- package/build/types/lib/workbook-builder/utils/date-to-excel-serial.d.ts +9 -0
- package/build/types/lib/workbook-builder/utils/index.d.ts +18 -0
- package/build/types/lib/workbook-builder/utils/initialize-files.d.ts +13 -0
- package/build/types/lib/workbook-builder/utils/sheet.d.ts +21 -0
- package/build/types/lib/workbook-builder/utils/write-shared-strings-xml.d.ts +11 -0
- package/build/types/lib/workbook-builder/utils/write-styles-xml.d.ts +24 -0
- package/build/types/lib/workbook-builder/utils/write-worksheet-xml.d.ts +14 -0
- package/build/types/lib/workbook-builder/utils/write-xml.d.ts +3 -0
- package/build/types/lib/workbook-builder/workbook-builder.d.ts +110 -0
- package/build/types/lib/zip/utils/to-bytes.d.ts +2 -2
- package/package.json +4 -2
- /package/build/cjs/lib/{template/utils → utils}/escape-xml.js +0 -0
- /package/build/esm/lib/{template/utils → utils}/escape-xml.js +0 -0
- /package/build/types/lib/{template/utils → utils}/escape-xml.d.ts +0 -0
@@ -0,0 +1,36 @@
|
|
1
|
+
import * as Helpers from "./helpers/index.js";
|
2
|
+
/**
|
3
|
+
* Adds a merge cell range to the specified sheet.
|
4
|
+
*
|
5
|
+
* @param this - WorkbookBuilder instance
|
6
|
+
* @param payload - Merge cell data with sheet name
|
7
|
+
*
|
8
|
+
* @returns The added merge cell object
|
9
|
+
*
|
10
|
+
* @throws Error if sheet is not found or merge intersects with existing merged cells
|
11
|
+
*/
|
12
|
+
export function add(payload) {
|
13
|
+
const { endCol, endRow, sheetName, startCol, startRow } = payload;
|
14
|
+
if (!this.getSheet(sheetName)) {
|
15
|
+
throw new Error("Sheet not found");
|
16
|
+
}
|
17
|
+
const merges = this.mergeCells.get(sheetName) ?? [];
|
18
|
+
// Check for intersection with existing merge cells
|
19
|
+
for (const m of merges) {
|
20
|
+
if (Helpers.rangesEqual(m, payload)) {
|
21
|
+
return m; // Already exists
|
22
|
+
}
|
23
|
+
if (Helpers.rangesIntersect(m, payload)) {
|
24
|
+
throw new Error("Merge intersects existing merged cell");
|
25
|
+
}
|
26
|
+
}
|
27
|
+
const merge = {
|
28
|
+
endCol,
|
29
|
+
endRow,
|
30
|
+
startCol,
|
31
|
+
startRow,
|
32
|
+
};
|
33
|
+
merges.push(merge);
|
34
|
+
this.mergeCells.set(sheetName, merges);
|
35
|
+
return merge;
|
36
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* Compares two merge cell ranges for equality.
|
3
|
+
*
|
4
|
+
* @param a - First merge cell range to compare
|
5
|
+
* @param b - Second merge cell range to compare
|
6
|
+
*
|
7
|
+
* @returns True if both ranges have identical start and end coordinates
|
8
|
+
*/
|
9
|
+
export function rangesEqual(a, b) {
|
10
|
+
return a.startRow === b.startRow &&
|
11
|
+
a.endRow === b.endRow &&
|
12
|
+
a.startCol === b.startCol &&
|
13
|
+
a.endCol === b.endCol;
|
14
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
/**
|
2
|
+
* Checks if two merge cell ranges intersect with each other.
|
3
|
+
*
|
4
|
+
* @param a - First merge cell range to check
|
5
|
+
* @param b - Second merge cell range to check
|
6
|
+
*
|
7
|
+
* @returns True if the ranges intersect (overlap), false otherwise
|
8
|
+
*/
|
9
|
+
export function rangesIntersect(a, b) {
|
10
|
+
return !(a.endRow < b.startRow ||
|
11
|
+
a.startRow > b.endRow ||
|
12
|
+
a.endCol < b.startCol ||
|
13
|
+
a.startCol > b.endCol);
|
14
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import * as Helpers from "./helpers/index.js";
|
2
|
+
/**
|
3
|
+
* Removes a merge cell range from the specified sheet.
|
4
|
+
*
|
5
|
+
* @param this - WorkbookBuilder instance
|
6
|
+
* @param payload - Merge cell data with sheet name
|
7
|
+
*
|
8
|
+
* @returns True if the merge cell was successfully removed
|
9
|
+
*
|
10
|
+
* @throws Error if sheet is not found or merge cell does not exist
|
11
|
+
*/
|
12
|
+
export function remove(payload) {
|
13
|
+
const { endCol, endRow, sheetName, startCol, startRow } = payload;
|
14
|
+
if (!this.getSheet(sheetName)) {
|
15
|
+
throw new Error("Sheet not found: " + sheetName);
|
16
|
+
}
|
17
|
+
const merges = this.mergeCells.get(sheetName) ?? [];
|
18
|
+
const i = merges.findIndex(m => Helpers.rangesEqual(m, { endCol, endRow, startCol, startRow }));
|
19
|
+
if (i === -1) {
|
20
|
+
throw new Error("Sheet: " + sheetName + " Invalid merge cell: " + JSON.stringify(payload));
|
21
|
+
}
|
22
|
+
merges.splice(i, 1);
|
23
|
+
return true;
|
24
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/**
|
2
|
+
* Adds a shared string to the workbook and returns its index.
|
3
|
+
*
|
4
|
+
* @param this - WorkbookBuilder instance
|
5
|
+
* @param payload - Object containing sheet name and string value
|
6
|
+
*
|
7
|
+
* @returns The index of the shared string in the shared strings array
|
8
|
+
*/
|
9
|
+
export function add(payload) {
|
10
|
+
const { sheetName, str } = payload;
|
11
|
+
if (!this.getSheet(sheetName)) {
|
12
|
+
throw new Error("SheetName was not found");
|
13
|
+
}
|
14
|
+
let idx = this.sharedStringMap.get(str);
|
15
|
+
if (idx === undefined) {
|
16
|
+
idx = this.sharedStrings.length;
|
17
|
+
this.sharedStrings.push(str);
|
18
|
+
this.sharedStringMap.set(str, idx);
|
19
|
+
}
|
20
|
+
return idx;
|
21
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
/**
|
2
|
+
* Removes all shared string references for a specific sheet and cleans up unused strings.
|
3
|
+
*
|
4
|
+
* @param this - WorkbookBuilder instance
|
5
|
+
* @param payload - Object containing the sheet name to remove references from
|
6
|
+
*/
|
7
|
+
export function removeAllFromSheet(payload) {
|
8
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
9
|
+
const { sheetName } = payload;
|
10
|
+
return;
|
11
|
+
// // 1. Collect strings that need to be removed
|
12
|
+
// const stringsToRemove: string[] = [];
|
13
|
+
// for (const [str, sheetsSet] of this.sharedStringRefs) {
|
14
|
+
// sheetsSet.delete(sheetName);
|
15
|
+
// if (sheetsSet.size === 0) {
|
16
|
+
// stringsToRemove.push(str);
|
17
|
+
// }
|
18
|
+
// }
|
19
|
+
// if (stringsToRemove.length === 0) {
|
20
|
+
// return;
|
21
|
+
// }
|
22
|
+
// // 2. Build map of old indices → new indices
|
23
|
+
// const oldToNew = new Map<number, number>();
|
24
|
+
// let newIdx = 0;
|
25
|
+
// for (let oldIdx = 0; oldIdx < this.sharedStrings.length; oldIdx++) {
|
26
|
+
// const str = this.sharedStrings[oldIdx];
|
27
|
+
// if (!str) {
|
28
|
+
// continue; // Skip if undefined
|
29
|
+
// }
|
30
|
+
// if (stringsToRemove.includes(str)) {
|
31
|
+
// // Remove string from refs
|
32
|
+
// this.sharedStringRefs.delete(str);
|
33
|
+
// continue; // Index is not accounted for
|
34
|
+
// }
|
35
|
+
// oldToNew.set(oldIdx, newIdx++);
|
36
|
+
// }
|
37
|
+
// // 3. Update sharedStrings array
|
38
|
+
// this.sharedStrings = this.sharedStrings.filter(s => !stringsToRemove.includes(s));
|
39
|
+
// // 4. Update sharedStringMap with new indices
|
40
|
+
// this.sharedStringMap.clear();
|
41
|
+
// for (let i = 0; i < this.sharedStrings.length; i++) {
|
42
|
+
// const str = this.sharedStrings[i];
|
43
|
+
// if (str) {
|
44
|
+
// this.sharedStringMap.set(str, i);
|
45
|
+
// }
|
46
|
+
// }
|
47
|
+
// // 5. Update indices in cells across all sheets
|
48
|
+
// for (const sheet of this.sheets.values()) {
|
49
|
+
// for (const row of sheet.rows.values()) {
|
50
|
+
// for (const cell of row.cells.values()) {
|
51
|
+
// if (cell.type === "s" && typeof cell.value === "number") {
|
52
|
+
// const newIdx = oldToNew.get(cell.value);
|
53
|
+
// if (newIdx !== undefined) {
|
54
|
+
// cell.value = newIdx;
|
55
|
+
// } else {
|
56
|
+
// // If cell.value was a removed string, set to 0 or null
|
57
|
+
// cell.value = 0;
|
58
|
+
// }
|
59
|
+
// }
|
60
|
+
// }
|
61
|
+
// }
|
62
|
+
// }
|
63
|
+
}
|
@@ -0,0 +1,63 @@
|
|
1
|
+
/**
|
2
|
+
* Removes a shared string reference for a specific sheet and cleans up if unused.
|
3
|
+
*
|
4
|
+
* @param this - WorkbookBuilder instance
|
5
|
+
* @param payload - Object containing sheet name and string index to remove
|
6
|
+
*
|
7
|
+
* @returns True if the reference was successfully removed, false if string or reference not found
|
8
|
+
*/
|
9
|
+
export function remove(payload) {
|
10
|
+
const { sheetName, strIdx } = payload;
|
11
|
+
if (!this.getSheet(sheetName)) {
|
12
|
+
throw new Error(`Sheet not found: ${sheetName}`);
|
13
|
+
}
|
14
|
+
const str = this.sharedStrings[strIdx];
|
15
|
+
if (!str) {
|
16
|
+
throw new Error(`String not found: ${strIdx}`);
|
17
|
+
}
|
18
|
+
return true;
|
19
|
+
// const refs = this.sharedStringRefs.get(str);
|
20
|
+
// if (!refs || !refs.has(sheetName)) {
|
21
|
+
// return false;
|
22
|
+
// }
|
23
|
+
// refs.delete(sheetName);
|
24
|
+
// if (refs.size === 0) {
|
25
|
+
// // Build map of old indices → new indices before removal
|
26
|
+
// const oldToNew = new Map<number, number>();
|
27
|
+
// for (let i = 0; i < this.sharedStrings.length; i++) {
|
28
|
+
// if (i < strIdx) {
|
29
|
+
// oldToNew.set(i, i);
|
30
|
+
// } else if (i > strIdx) {
|
31
|
+
// oldToNew.set(i, i - 1);
|
32
|
+
// }
|
33
|
+
// // i === strIdx — this string will be removed, no index
|
34
|
+
// }
|
35
|
+
// // Remove string from array and refs
|
36
|
+
// this.sharedStrings.splice(strIdx, 1);
|
37
|
+
// this.sharedStringMap.delete(str);
|
38
|
+
// this.sharedStringRefs.delete(str);
|
39
|
+
// // Update sharedStringMap with new indices
|
40
|
+
// for (let i = 0; i < this.sharedStrings.length; i++) {
|
41
|
+
// const str = this.sharedStrings[i];
|
42
|
+
// if (str) {
|
43
|
+
// this.sharedStringMap.set(str, i);
|
44
|
+
// }
|
45
|
+
// }
|
46
|
+
// // Update indices across all sheets
|
47
|
+
// for (const sheet of this.sheets.values()) {
|
48
|
+
// for (const row of sheet.rows.values()) {
|
49
|
+
// for (const cell of row.cells.values()) {
|
50
|
+
// if (cell.type === "s" && typeof cell.value === "number") {
|
51
|
+
// const newIdx = oldToNew.get(cell.value);
|
52
|
+
// if (newIdx !== undefined) {
|
53
|
+
// cell.value = newIdx;
|
54
|
+
// } else {
|
55
|
+
// // Just in case, if cell.value was a removed string
|
56
|
+
// cell.value = 0; // or null, according to your application logic
|
57
|
+
// }
|
58
|
+
// }
|
59
|
+
// }
|
60
|
+
// }
|
61
|
+
// }
|
62
|
+
// }
|
63
|
+
}
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import * as Helpers from "./helpers/index.js";
|
2
|
+
/**
|
3
|
+
* Adds a new cell style to the workbook or returns the index of an existing identical style.
|
4
|
+
* This function manages style deduplication by checking if an identical style already exists
|
5
|
+
* before creating a new one.
|
6
|
+
*
|
7
|
+
* @param this - The WorkbookBuilder instance
|
8
|
+
* @param payload - Object containing the style to add or get
|
9
|
+
* @param payload.style - The cell style configuration
|
10
|
+
*
|
11
|
+
* @returns The index of the style in the cellXfs array
|
12
|
+
*/
|
13
|
+
export function addOrGet(payload) {
|
14
|
+
const { style } = payload;
|
15
|
+
// Convert each style component to XML and get their IDs using Map-backed de-duplication
|
16
|
+
const fontXml = Helpers.fontToXml({ existingFonts: this.fonts, font: style.font });
|
17
|
+
const fontKey = JSON.stringify(fontXml);
|
18
|
+
let fontId = this.fontsMap.get(fontKey);
|
19
|
+
if (fontId === undefined) {
|
20
|
+
fontId = this.fonts.length;
|
21
|
+
this.fonts.push(fontXml);
|
22
|
+
this.fontsMap.set(fontKey, fontId);
|
23
|
+
}
|
24
|
+
const fillXml = Helpers.fillToXml({ existingFills: this.fills, fill: style.fill });
|
25
|
+
const fillKey = JSON.stringify(fillXml);
|
26
|
+
let fillId = this.fillsMap.get(fillKey);
|
27
|
+
if (fillId === undefined) {
|
28
|
+
fillId = this.fills.length;
|
29
|
+
this.fills.push(fillXml);
|
30
|
+
this.fillsMap.set(fillKey, fillId);
|
31
|
+
}
|
32
|
+
const borderXml = Helpers.borderToXml({ border: style.border, existingBorders: this.borders });
|
33
|
+
const borderKey = JSON.stringify(borderXml);
|
34
|
+
let borderId = this.bordersMap.get(borderKey);
|
35
|
+
if (borderId === undefined) {
|
36
|
+
borderId = this.borders.length;
|
37
|
+
this.borders.push(borderXml);
|
38
|
+
this.bordersMap.set(borderKey, borderId);
|
39
|
+
}
|
40
|
+
const numFmtId = style.numberFormat
|
41
|
+
? Helpers.addNumFmt({ formatCode: style.numberFormat, numFmts: this.numFmts })
|
42
|
+
: 0;
|
43
|
+
const xf = {
|
44
|
+
alignment: style.alignment,
|
45
|
+
borderId,
|
46
|
+
fillId,
|
47
|
+
fontId,
|
48
|
+
numFmtId,
|
49
|
+
};
|
50
|
+
const xfKey = JSON.stringify(xf);
|
51
|
+
if (this.styleMap.has(xfKey)) {
|
52
|
+
return this.styleMap.get(xfKey);
|
53
|
+
}
|
54
|
+
const index = this.cellXfs.length;
|
55
|
+
this.cellXfs.push(xf);
|
56
|
+
this.styleMap.set(xfKey, index);
|
57
|
+
return index;
|
58
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
/**
|
2
|
+
* Adds a custom number format to the collection or returns the existing id.
|
3
|
+
*
|
4
|
+
* Excel reserves built-in ids below 164; custom formats start from 164.
|
5
|
+
*
|
6
|
+
* @param payload - Input arguments
|
7
|
+
* @param payload.formatCode - Format code, e.g., "0.00" or "dd/mm/yyyy"
|
8
|
+
* @param payload.numFmts - Mutable list of custom formats to search/extend
|
9
|
+
* @returns Numeric id of the number format
|
10
|
+
*/
|
11
|
+
export const addNumFmt = (payload) => {
|
12
|
+
const { formatCode, numFmts } = payload;
|
13
|
+
// 164+ is reserved for custom formats
|
14
|
+
const existing = numFmts.find(nf => nf.formatCode === formatCode);
|
15
|
+
if (existing) {
|
16
|
+
return existing.id;
|
17
|
+
}
|
18
|
+
const id = 164 + numFmts.length;
|
19
|
+
numFmts.push({ formatCode, id });
|
20
|
+
return id;
|
21
|
+
};
|
@@ -0,0 +1,45 @@
|
|
1
|
+
/**
|
2
|
+
* Builds an XmlNode representing a <border> element based on the provided CellStyle.
|
3
|
+
*
|
4
|
+
* If no border is provided, the first existing border is returned (assumed default).
|
5
|
+
* Color values beginning with # are converted to RGB without the leading hash, as expected by Excel.
|
6
|
+
*
|
7
|
+
* @param payload - Input arguments
|
8
|
+
* @param payload.border - Optional border style from the cell style
|
9
|
+
* @param payload.existingBorders - Existing borders collection to fall back to
|
10
|
+
* @returns XmlNode representing a <border> element
|
11
|
+
*/
|
12
|
+
export const borderToXml = (payload) => {
|
13
|
+
const { border, existingBorders } = payload;
|
14
|
+
if (!existingBorders?.length) {
|
15
|
+
throw new Error("existingBorders is empty");
|
16
|
+
}
|
17
|
+
if (!border) {
|
18
|
+
return existingBorders[0];
|
19
|
+
}
|
20
|
+
const children = [];
|
21
|
+
for (const side of ["left", "right", "top", "bottom"]) {
|
22
|
+
const b = border?.[side];
|
23
|
+
if (b) {
|
24
|
+
const attrs = { style: b.style };
|
25
|
+
const sideChildren = b.color
|
26
|
+
? [{
|
27
|
+
attrs: { rgb: b.color.replace(/^#/, "") },
|
28
|
+
tag: "color",
|
29
|
+
}]
|
30
|
+
: [];
|
31
|
+
children.push({
|
32
|
+
attrs,
|
33
|
+
children: sideChildren,
|
34
|
+
tag: side,
|
35
|
+
});
|
36
|
+
}
|
37
|
+
else {
|
38
|
+
children.push({ tag: side });
|
39
|
+
}
|
40
|
+
}
|
41
|
+
return {
|
42
|
+
children,
|
43
|
+
tag: "border",
|
44
|
+
};
|
45
|
+
};
|
@@ -0,0 +1,47 @@
|
|
1
|
+
/**
|
2
|
+
* Builds an XmlNode representing a <fill> element based on the provided CellStyle.
|
3
|
+
*
|
4
|
+
* If no fill is provided, the first existing fill is returned (assumed default).
|
5
|
+
* Foreground/background colors may include a leading '#', which is removed to
|
6
|
+
* match Excel's expected RGB format.
|
7
|
+
*
|
8
|
+
* @param payload - Input arguments
|
9
|
+
* @param payload.existingFills - Existing fills collection to fall back to
|
10
|
+
* @param payload.fill - Optional fill from the cell style
|
11
|
+
* @returns XmlNode representing a <fill> element
|
12
|
+
*/
|
13
|
+
export const fillToXml = (payload) => {
|
14
|
+
const { existingFills, fill } = payload;
|
15
|
+
if (!existingFills?.length) {
|
16
|
+
throw new Error("existingFills is empty");
|
17
|
+
}
|
18
|
+
if (!fill)
|
19
|
+
return existingFills[0];
|
20
|
+
const patternType = fill.patternType ?? "solid";
|
21
|
+
const children = [];
|
22
|
+
const attrs = { patternType };
|
23
|
+
const fillChildren = [];
|
24
|
+
if (fill.fgColor) {
|
25
|
+
const colorVal = fill.fgColor.startsWith("#") ? fill.fgColor.slice(1) : fill.fgColor;
|
26
|
+
fillChildren.push({
|
27
|
+
attrs: { rgb: colorVal },
|
28
|
+
tag: "fgColor",
|
29
|
+
});
|
30
|
+
}
|
31
|
+
if (fill.bgColor) {
|
32
|
+
const colorVal = fill.bgColor.startsWith("#") ? fill.bgColor.slice(1) : fill.bgColor;
|
33
|
+
fillChildren.push({
|
34
|
+
attrs: { rgb: colorVal },
|
35
|
+
tag: "bgColor",
|
36
|
+
});
|
37
|
+
}
|
38
|
+
children.push({
|
39
|
+
attrs,
|
40
|
+
children: fillChildren,
|
41
|
+
tag: "patternFill",
|
42
|
+
});
|
43
|
+
return {
|
44
|
+
children,
|
45
|
+
tag: "fill",
|
46
|
+
};
|
47
|
+
};
|
@@ -0,0 +1,75 @@
|
|
1
|
+
import * as Default from "../../default/index.js";
|
2
|
+
/**
|
3
|
+
* Builds an XmlNode representing a <font> element based on the provided CellStyle.
|
4
|
+
*
|
5
|
+
* If no font is provided, returns the default font from the template. Color
|
6
|
+
* values may include a leading '#'. Six-digit RGB values are prefixed with
|
7
|
+
* 'FF' (alpha) to form ARGB; eight-digit values are used as-is. Throws for
|
8
|
+
* invalid color lengths.
|
9
|
+
*
|
10
|
+
* @param payload - Input arguments
|
11
|
+
* @param payload.existingFonts - Existing fonts collection (not used directly; kept for parity)
|
12
|
+
* @param payload.font - Optional font from the cell style
|
13
|
+
* @returns XmlNode representing a <font> element
|
14
|
+
*/
|
15
|
+
export const fontToXml = (payload) => {
|
16
|
+
const { existingFonts, font } = payload;
|
17
|
+
if (!existingFonts?.length) {
|
18
|
+
throw new Error("existingFonts is empty");
|
19
|
+
}
|
20
|
+
// Default values
|
21
|
+
const defaultFont = Default.font();
|
22
|
+
if (!font) {
|
23
|
+
// If no font style provided — return default font (as in Excel template)
|
24
|
+
return defaultFont;
|
25
|
+
}
|
26
|
+
const children = [];
|
27
|
+
// Size is always present
|
28
|
+
children.push({
|
29
|
+
attrs: { val: String(font.size ?? defaultFont.children.at(0)?.attrs.val) },
|
30
|
+
tag: "sz",
|
31
|
+
});
|
32
|
+
// Color (if provided) otherwise default
|
33
|
+
if (font.color) {
|
34
|
+
const colorVal = font.color.startsWith("#") ? font.color.slice(1) : font.color;
|
35
|
+
if (colorVal.length === 6) {
|
36
|
+
children.push({
|
37
|
+
attrs: { rgb: "FF" + colorVal.toUpperCase() },
|
38
|
+
tag: "color",
|
39
|
+
});
|
40
|
+
}
|
41
|
+
else if (colorVal.length === 8) {
|
42
|
+
children.push({
|
43
|
+
attrs: { rgb: colorVal.toUpperCase() },
|
44
|
+
tag: "color",
|
45
|
+
});
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
throw new Error(`Invalid font color: ${font.color}`);
|
49
|
+
}
|
50
|
+
}
|
51
|
+
else {
|
52
|
+
children.push(defaultFont.children.at(1));
|
53
|
+
}
|
54
|
+
// Font name (required)
|
55
|
+
children.push({
|
56
|
+
attrs: { val: font.name ?? defaultFont.children.at(2)?.attrs.val },
|
57
|
+
tag: "name",
|
58
|
+
});
|
59
|
+
// Additional attributes
|
60
|
+
if (font.bold)
|
61
|
+
children.push({ tag: "b" });
|
62
|
+
if (font.italic)
|
63
|
+
children.push({ tag: "i" });
|
64
|
+
if (font.underline) {
|
65
|
+
const val = font.underline === true ? "single" : font.underline;
|
66
|
+
children.push({
|
67
|
+
attrs: { val },
|
68
|
+
tag: "u",
|
69
|
+
});
|
70
|
+
}
|
71
|
+
return {
|
72
|
+
children,
|
73
|
+
tag: "font",
|
74
|
+
};
|
75
|
+
};
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/**
|
2
|
+
* Reindexes a style map in-place after removing a style at a given index.
|
3
|
+
*
|
4
|
+
* - Deletes entries that point to the removed index
|
5
|
+
* - Decrements by 1 all indices greater than the removed index
|
6
|
+
*
|
7
|
+
* @param payload - Input arguments
|
8
|
+
* @param payload.removedIndex - The style index that was removed
|
9
|
+
* @param payload.styleMap - Map of serialized style key to style index
|
10
|
+
* @returns void
|
11
|
+
*/
|
12
|
+
export const reindexStyleMapAfterRemoval = (payload) => {
|
13
|
+
const { removedIndex, styleMap } = payload;
|
14
|
+
const updates = [];
|
15
|
+
for (const [key, idx] of styleMap.entries()) {
|
16
|
+
if (idx === removedIndex) {
|
17
|
+
styleMap.delete(key);
|
18
|
+
}
|
19
|
+
else if (idx > removedIndex) {
|
20
|
+
updates.push([key, idx - 1]);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
for (const [key, newIdx] of updates) {
|
24
|
+
styleMap.set(key, newIdx);
|
25
|
+
}
|
26
|
+
};
|
@@ -0,0 +1,23 @@
|
|
1
|
+
import { remove } from "./remove.js";
|
2
|
+
export function removeAllFromSheet(payload) {
|
3
|
+
const { sheetName } = payload;
|
4
|
+
const sheet = this.sheets.get(sheetName);
|
5
|
+
if (!sheet)
|
6
|
+
return false;
|
7
|
+
const stylesToRemove = [];
|
8
|
+
let removedSomething = false;
|
9
|
+
for (const row of sheet.rows.values()) {
|
10
|
+
for (const cell of row.cells.values()) {
|
11
|
+
if (cell.style?.index !== undefined) {
|
12
|
+
stylesToRemove.push(cell.style);
|
13
|
+
}
|
14
|
+
}
|
15
|
+
}
|
16
|
+
for (const style of stylesToRemove) {
|
17
|
+
const removed = remove.bind(this)({ style });
|
18
|
+
if (removed) {
|
19
|
+
removedSomething = true;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
return removedSomething;
|
23
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
// import * as Helpers from "./helpers/index.js";
|
2
|
+
/**
|
3
|
+
* Validates a cell style index and checks if the style exists in the workbook.
|
4
|
+
* This function performs validation checks on the provided style index and
|
5
|
+
* verifies that the style exists at the given index in the cellXfs array.
|
6
|
+
*
|
7
|
+
* @param this - The WorkbookBuilder instance
|
8
|
+
* @param payload - Object containing the style to validate
|
9
|
+
* @param payload.style - The cell style configuration with index
|
10
|
+
*
|
11
|
+
* @returns True if the style index is valid and the style exists
|
12
|
+
*
|
13
|
+
* @throws {Error} When styleIndex is invalid (not a number) or when style doesn't exist at the given index
|
14
|
+
*/
|
15
|
+
export function remove(payload) {
|
16
|
+
const { style } = payload;
|
17
|
+
const styleIndex = style.index;
|
18
|
+
if (typeof styleIndex !== "number") {
|
19
|
+
throw new Error("Invalid styleIndex: not a number");
|
20
|
+
}
|
21
|
+
if (styleIndex === 0) {
|
22
|
+
throw new Error("Invalid styleIndex: 0 is the default style and cannot be removed");
|
23
|
+
}
|
24
|
+
const xf = this.cellXfs[styleIndex];
|
25
|
+
if (!xf) {
|
26
|
+
throw new Error(`Invalid styleIndex: style not found at index ${styleIndex}`);
|
27
|
+
}
|
28
|
+
return true;
|
29
|
+
// let removedSomething = false;
|
30
|
+
// // Get style parts before splice - indices are still valid
|
31
|
+
// const xf = this.cellXfs[styleIndex];
|
32
|
+
// if (xf) {
|
33
|
+
// this.cellXfs.splice(styleIndex, 1);
|
34
|
+
// // Fix: reindex styleMap after splice
|
35
|
+
// Helpers.reindexStyleMapAfterRemoval({ removedIndex: styleIndex, styleMap: this.styleMap });
|
36
|
+
// // Reindex style references in cells across all sheets
|
37
|
+
// for (const sheet of this.sheets.values()) {
|
38
|
+
// for (const row of sheet.rows.values()) {
|
39
|
+
// for (const cell of row.cells.values()) {
|
40
|
+
// if (cell.style?.index !== undefined && cell.style.index > styleIndex) {
|
41
|
+
// cell.style.index -= 1;
|
42
|
+
// }
|
43
|
+
// }
|
44
|
+
// }
|
45
|
+
// }
|
46
|
+
// removedSomething = true;
|
47
|
+
// }
|
48
|
+
// return removedSomething;
|
49
|
+
}
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|