@js-ak/excel-toolbox 1.6.0 → 1.8.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/merge-sheets-to-base-file-process-sync.js +105 -0
- package/build/cjs/lib/merge-sheets-to-base-file-process.js +3 -3
- package/build/cjs/lib/merge-sheets-to-base-file-sync.js +2 -2
- package/build/cjs/lib/merge-sheets-to-base-file.js +1 -1
- package/build/cjs/lib/template/template-fs.js +97 -18
- package/build/cjs/lib/template/template-memory.js +110 -43
- package/build/cjs/lib/template/utils/compare-columns.js +16 -0
- package/build/cjs/lib/template/utils/index.js +1 -0
- package/build/cjs/lib/xml/extract-rows-from-sheet-sync.js +67 -0
- package/build/cjs/lib/xml/extract-rows-from-sheet.js +4 -2
- package/build/cjs/lib/xml/extract-xml-from-sheet-sync.js +43 -0
- package/build/cjs/lib/xml/extract-xml-from-sheet.js +15 -15
- package/build/cjs/lib/xml/index.js +2 -1
- package/build/esm/lib/merge-sheets-to-base-file-process-sync.js +69 -0
- package/build/esm/lib/merge-sheets-to-base-file-process.js +3 -3
- package/build/esm/lib/merge-sheets-to-base-file-sync.js +2 -2
- package/build/esm/lib/merge-sheets-to-base-file.js +1 -1
- package/build/esm/lib/template/template-fs.js +97 -18
- package/build/esm/lib/template/template-memory.js +110 -43
- package/build/esm/lib/template/utils/compare-columns.js +13 -0
- package/build/esm/lib/template/utils/index.js +1 -0
- package/build/esm/lib/xml/extract-rows-from-sheet-sync.js +64 -0
- package/build/esm/lib/xml/extract-rows-from-sheet.js +4 -2
- package/build/esm/lib/xml/extract-xml-from-sheet-sync.js +40 -0
- package/build/esm/lib/xml/extract-xml-from-sheet.js +12 -15
- package/build/esm/lib/xml/index.js +2 -1
- package/build/types/lib/merge-sheets-to-base-file-process-sync.d.ts +27 -0
- package/build/types/lib/merge-sheets-to-base-file-process.d.ts +1 -1
- package/build/types/lib/template/template-fs.d.ts +14 -0
- package/build/types/lib/template/template-memory.d.ts +4 -2
- package/build/types/lib/template/utils/compare-columns.d.ts +8 -0
- package/build/types/lib/template/utils/index.d.ts +1 -0
- package/build/types/lib/xml/extract-rows-from-sheet-sync.d.ts +28 -0
- package/build/types/lib/xml/extract-rows-from-sheet.d.ts +2 -2
- package/build/types/lib/xml/extract-xml-from-sheet-sync.d.ts +14 -0
- package/build/types/lib/xml/extract-xml-from-sheet.d.ts +2 -2
- package/build/types/lib/xml/index.d.ts +2 -1
- package/package.json +1 -5
- package/build/cjs/lib/xml/extract-xml-from-system-content.js +0 -53
- package/build/esm/lib/xml/extract-xml-from-system-content.js +0 -49
- package/build/types/lib/xml/extract-xml-from-system-content.d.ts +0 -15
@@ -0,0 +1,105 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
19
|
+
var ownKeys = function(o) {
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
21
|
+
var ar = [];
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
23
|
+
return ar;
|
24
|
+
};
|
25
|
+
return ownKeys(o);
|
26
|
+
};
|
27
|
+
return function (mod) {
|
28
|
+
if (mod && mod.__esModule) return mod;
|
29
|
+
var result = {};
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
31
|
+
__setModuleDefault(result, mod);
|
32
|
+
return result;
|
33
|
+
};
|
34
|
+
})();
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
36
|
+
exports.mergeSheetsToBaseFileProcessSync = mergeSheetsToBaseFileProcessSync;
|
37
|
+
const Utils = __importStar(require("./utils/index.js"));
|
38
|
+
const Xml = __importStar(require("./xml/index.js"));
|
39
|
+
/**
|
40
|
+
* Merges rows from other Excel files into a base Excel file.
|
41
|
+
*
|
42
|
+
* This function is a process-friendly version of mergeSheetsToBaseFile.
|
43
|
+
* It takes a single object with the following properties:
|
44
|
+
* - additions: An array of objects with two properties:
|
45
|
+
* - files: A dictionary of file paths to their corresponding XML content
|
46
|
+
* - sheetIndexes: The 1-based indexes of the sheet to extract rows from
|
47
|
+
* - baseFiles: A dictionary of file paths to their corresponding XML content
|
48
|
+
* - baseSheetIndex: The 1-based index of the sheet in the base file to add rows to
|
49
|
+
* - gap: The number of empty rows to insert between each added section
|
50
|
+
* - sheetNamesToRemove: The names of sheets to remove from the output file
|
51
|
+
* - sheetsToRemove: The 1-based indices of sheets to remove from the output file
|
52
|
+
*
|
53
|
+
* The function returns a dictionary of file paths to their corresponding XML content.
|
54
|
+
*/
|
55
|
+
function mergeSheetsToBaseFileProcessSync(data) {
|
56
|
+
const { additions, baseFiles, baseSheetIndex, gap, sheetNamesToRemove, sheetsToRemove, } = data;
|
57
|
+
const basePath = `xl/worksheets/sheet${baseSheetIndex}.xml`;
|
58
|
+
if (!baseFiles[basePath]) {
|
59
|
+
throw new Error(`Base file does not contain ${basePath}`);
|
60
|
+
}
|
61
|
+
const { lastRowNumber, mergeCells: baseMergeCells, rows: baseRows, xml, } = Xml.extractRowsFromSheetSync(baseFiles[basePath]);
|
62
|
+
const allRows = [...baseRows];
|
63
|
+
const allMergeCells = [...baseMergeCells];
|
64
|
+
let currentRowOffset = lastRowNumber + gap;
|
65
|
+
for (const { files, sheetIndexes } of additions) {
|
66
|
+
for (const sheetIndex of sheetIndexes) {
|
67
|
+
const sheetPath = `xl/worksheets/sheet${sheetIndex}.xml`;
|
68
|
+
if (!files[sheetPath]) {
|
69
|
+
throw new Error(`File does not contain ${sheetPath}`);
|
70
|
+
}
|
71
|
+
const { mergeCells, rows } = Xml.extractRowsFromSheetSync(files[sheetPath]);
|
72
|
+
const shiftedRows = Xml.shiftRowIndices(rows, currentRowOffset);
|
73
|
+
const shiftedMergeCells = mergeCells.map(cell => {
|
74
|
+
const [start, end] = cell.ref.split(":");
|
75
|
+
if (!start || !end) {
|
76
|
+
return cell;
|
77
|
+
}
|
78
|
+
const shiftedStart = Utils.shiftCellRef(start, currentRowOffset);
|
79
|
+
const shiftedEnd = Utils.shiftCellRef(end, currentRowOffset);
|
80
|
+
return { ...cell, ref: `${shiftedStart}:${shiftedEnd}` };
|
81
|
+
});
|
82
|
+
allRows.push(...shiftedRows);
|
83
|
+
allMergeCells.push(...shiftedMergeCells);
|
84
|
+
currentRowOffset += Utils.getMaxRowNumber(rows) + gap;
|
85
|
+
}
|
86
|
+
}
|
87
|
+
const mergedXml = Xml.buildMergedSheet(xml, allRows, allMergeCells);
|
88
|
+
baseFiles[basePath] = mergedXml;
|
89
|
+
for (const sheetIndex of sheetsToRemove) {
|
90
|
+
const sheetPath = `xl/worksheets/sheet${sheetIndex}.xml`;
|
91
|
+
delete baseFiles[sheetPath];
|
92
|
+
if (baseFiles["xl/workbook.xml"]) {
|
93
|
+
baseFiles["xl/workbook.xml"] = Buffer.from(Utils.removeSheetFromWorkbook(baseFiles["xl/workbook.xml"].toString(), sheetIndex));
|
94
|
+
}
|
95
|
+
if (baseFiles["xl/_rels/workbook.xml.rels"]) {
|
96
|
+
baseFiles["xl/_rels/workbook.xml.rels"] = Buffer.from(Utils.removeSheetFromRels(baseFiles["xl/_rels/workbook.xml.rels"].toString(), sheetIndex));
|
97
|
+
}
|
98
|
+
if (baseFiles["[Content_Types].xml"]) {
|
99
|
+
baseFiles["[Content_Types].xml"] = Buffer.from(Utils.removeSheetFromContentTypes(baseFiles["[Content_Types].xml"].toString(), sheetIndex));
|
100
|
+
}
|
101
|
+
}
|
102
|
+
for (const sheetName of sheetNamesToRemove) {
|
103
|
+
Utils.removeSheetByName(baseFiles, sheetName);
|
104
|
+
}
|
105
|
+
}
|
@@ -52,13 +52,13 @@ const Xml = __importStar(require("./xml/index.js"));
|
|
52
52
|
*
|
53
53
|
* The function returns a dictionary of file paths to their corresponding XML content.
|
54
54
|
*/
|
55
|
-
function mergeSheetsToBaseFileProcess(data) {
|
55
|
+
async function mergeSheetsToBaseFileProcess(data) {
|
56
56
|
const { additions, baseFiles, baseSheetIndex, gap, sheetNamesToRemove, sheetsToRemove, } = data;
|
57
57
|
const basePath = `xl/worksheets/sheet${baseSheetIndex}.xml`;
|
58
58
|
if (!baseFiles[basePath]) {
|
59
59
|
throw new Error(`Base file does not contain ${basePath}`);
|
60
60
|
}
|
61
|
-
const { lastRowNumber, mergeCells: baseMergeCells, rows: baseRows, xml, } = Xml.extractRowsFromSheet(baseFiles[basePath]);
|
61
|
+
const { lastRowNumber, mergeCells: baseMergeCells, rows: baseRows, xml, } = await Xml.extractRowsFromSheet(baseFiles[basePath]);
|
62
62
|
const allRows = [...baseRows];
|
63
63
|
const allMergeCells = [...baseMergeCells];
|
64
64
|
let currentRowOffset = lastRowNumber + gap;
|
@@ -68,7 +68,7 @@ function mergeSheetsToBaseFileProcess(data) {
|
|
68
68
|
if (!files[sheetPath]) {
|
69
69
|
throw new Error(`File does not contain ${sheetPath}`);
|
70
70
|
}
|
71
|
-
const { mergeCells, rows } = Xml.extractRowsFromSheet(files[sheetPath]);
|
71
|
+
const { mergeCells, rows } = await Xml.extractRowsFromSheet(files[sheetPath]);
|
72
72
|
const shiftedRows = Xml.shiftRowIndices(rows, currentRowOffset);
|
73
73
|
const shiftedMergeCells = mergeCells.map(cell => {
|
74
74
|
const [start, end] = cell.ref.split(":");
|
@@ -36,7 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.mergeSheetsToBaseFileSync = mergeSheetsToBaseFileSync;
|
37
37
|
const Utils = __importStar(require("./utils/index.js"));
|
38
38
|
const Zip = __importStar(require("./zip/index.js"));
|
39
|
-
const
|
39
|
+
const merge_sheets_to_base_file_process_sync_js_1 = require("./merge-sheets-to-base-file-process-sync.js");
|
40
40
|
/**
|
41
41
|
* Merge rows from other Excel files into a base Excel file.
|
42
42
|
* The output is a new Excel file with the merged content.
|
@@ -65,7 +65,7 @@ function mergeSheetsToBaseFileSync(data) {
|
|
65
65
|
sheetIndexes,
|
66
66
|
});
|
67
67
|
}
|
68
|
-
(0,
|
68
|
+
(0, merge_sheets_to_base_file_process_sync_js_1.mergeSheetsToBaseFileProcessSync)({
|
69
69
|
additions: additionsUpdated,
|
70
70
|
baseFiles,
|
71
71
|
baseSheetIndex,
|
@@ -65,7 +65,7 @@ async function mergeSheetsToBaseFile(data) {
|
|
65
65
|
sheetIndexes,
|
66
66
|
});
|
67
67
|
}
|
68
|
-
(0, merge_sheets_to_base_file_process_js_1.mergeSheetsToBaseFileProcess)({
|
68
|
+
await (0, merge_sheets_to_base_file_process_js_1.mergeSheetsToBaseFileProcess)({
|
69
69
|
additions: additionsUpdated,
|
70
70
|
baseFiles,
|
71
71
|
baseSheetIndex,
|
@@ -92,6 +92,7 @@ class TemplateFs {
|
|
92
92
|
this.fileKeys = fileKeys;
|
93
93
|
this.destination = destination;
|
94
94
|
}
|
95
|
+
/** Private methods */
|
95
96
|
/**
|
96
97
|
* Removes the temporary directory created by this Template instance.
|
97
98
|
* @private
|
@@ -165,13 +166,13 @@ class TemplateFs {
|
|
165
166
|
*/
|
166
167
|
async #getSheetPathByName(sheetName) {
|
167
168
|
// Read XML workbook to find sheet name and path
|
168
|
-
const workbookXml = Xml.extractXmlFromSheet(await this.#readFile(this.#excelKeys.workbook));
|
169
|
+
const workbookXml = await Xml.extractXmlFromSheet(await this.#readFile(this.#excelKeys.workbook));
|
169
170
|
const sheetMatch = workbookXml.match(Utils.sheetMatch(sheetName));
|
170
171
|
if (!sheetMatch || !sheetMatch[1]) {
|
171
172
|
throw new Error(`Sheet "${sheetName}" not found`);
|
172
173
|
}
|
173
174
|
const rId = sheetMatch[1];
|
174
|
-
const relsXml = Xml.extractXmlFromSheet(await this.#readFile(this.#excelKeys.workbookRels));
|
175
|
+
const relsXml = await Xml.extractXmlFromSheet(await this.#readFile(this.#excelKeys.workbookRels));
|
175
176
|
const relMatch = relsXml.match(Utils.relationshipMatch(rId));
|
176
177
|
if (!relMatch || !relMatch[1]) {
|
177
178
|
throw new Error(`Relationship "${rId}" not found`);
|
@@ -224,16 +225,30 @@ class TemplateFs {
|
|
224
225
|
const fullPath = path.join(this.destination, ...key.split("/"));
|
225
226
|
await fs.writeFile(fullPath, Buffer.isBuffer(content) ? content : Buffer.from(content));
|
226
227
|
}
|
228
|
+
/**
|
229
|
+
* Replaces placeholders in the given sheet with values from the replacements map.
|
230
|
+
*
|
231
|
+
* The function searches for placeholders in the format `${key}` within the sheet
|
232
|
+
* content, where `key` corresponds to a path in the replacements object.
|
233
|
+
* If a value is found for the key, it replaces the placeholder with the value.
|
234
|
+
* If no value is found, the original placeholder remains unchanged.
|
235
|
+
*
|
236
|
+
* @param sheetName - The name of the sheet to be replaced.
|
237
|
+
* @param replacements - An object where keys represent placeholder paths and values are the replacements.
|
238
|
+
* @returns A promise that resolves when the substitution is complete.
|
239
|
+
* @throws {Error} If the template instance has been destroyed.
|
240
|
+
* @experimental This API is experimental and might change in future versions.
|
241
|
+
*/
|
227
242
|
async #substitute(sheetName, replacements) {
|
228
243
|
const sharedStringsPath = this.#excelKeys.sharedStrings;
|
229
244
|
const sheetPath = await this.#getSheetPathByName(sheetName);
|
230
245
|
let sharedStringsContent = "";
|
231
246
|
let sheetContent = "";
|
232
247
|
if (this.fileKeys.has(sharedStringsPath)) {
|
233
|
-
sharedStringsContent = Xml.extractXmlFromSheet(await this.#readFile(sharedStringsPath));
|
248
|
+
sharedStringsContent = await Xml.extractXmlFromSheet(await this.#readFile(sharedStringsPath));
|
234
249
|
}
|
235
250
|
if (this.fileKeys.has(sheetPath)) {
|
236
|
-
sheetContent = Xml.extractXmlFromSheet(await this.#readFile(sheetPath));
|
251
|
+
sheetContent = await Xml.extractXmlFromSheet(await this.#readFile(sheetPath));
|
237
252
|
const TABLE_REGEX = /\$\{table:([a-zA-Z0-9_]+)\.([a-zA-Z0-9_]+)\}/g;
|
238
253
|
const hasTablePlaceholders = TABLE_REGEX.test(sharedStringsContent) || TABLE_REGEX.test(sheetContent);
|
239
254
|
if (hasTablePlaceholders) {
|
@@ -251,6 +266,54 @@ class TemplateFs {
|
|
251
266
|
await this.#set(sheetPath, sheetContent);
|
252
267
|
}
|
253
268
|
}
|
269
|
+
/**
|
270
|
+
* Removes sheets from the workbook.
|
271
|
+
*
|
272
|
+
* @param {Object} data - The data for sheet removal.
|
273
|
+
* @param {number[]} [data.sheetIndexes] - The 1-based indexes of the sheets to remove.
|
274
|
+
* @param {string[]} [data.sheetNames] - The names of the sheets to remove.
|
275
|
+
* @returns {void}
|
276
|
+
*
|
277
|
+
* @throws {Error} If the template instance has been destroyed.
|
278
|
+
* @throws {Error} If the sheet does not exist.
|
279
|
+
* @experimental This API is experimental and might change in future versions.
|
280
|
+
*/
|
281
|
+
async #removeSheets(data) {
|
282
|
+
const { sheetIndexes = [], sheetNames = [] } = data;
|
283
|
+
// first get index of sheets to remove
|
284
|
+
const sheetIndexesToRemove = new Set(sheetIndexes);
|
285
|
+
for (const sheetName of sheetNames) {
|
286
|
+
const sheetPath = await this.#getSheetPathByName(sheetName);
|
287
|
+
const sheetIndexMatch = sheetPath.match(/sheet(\d+)\.xml$/);
|
288
|
+
if (!sheetIndexMatch || !sheetIndexMatch[1]) {
|
289
|
+
throw new Error(`Sheet "${sheetName}" not found`);
|
290
|
+
}
|
291
|
+
const sheetIndex = parseInt(sheetIndexMatch[1], 10);
|
292
|
+
sheetIndexesToRemove.add(sheetIndex);
|
293
|
+
}
|
294
|
+
// Remove sheets by index
|
295
|
+
for (const sheetIndex of sheetIndexesToRemove.values()) {
|
296
|
+
const sheetPath = `xl/worksheets/sheet${sheetIndex}.xml`;
|
297
|
+
if (!this.fileKeys.has(sheetPath)) {
|
298
|
+
continue;
|
299
|
+
}
|
300
|
+
// remove sheet file
|
301
|
+
await fs.unlink(path.join(this.destination, ...sheetPath.split("/")));
|
302
|
+
this.fileKeys.delete(sheetPath);
|
303
|
+
// remove sheet from workbook
|
304
|
+
if (this.fileKeys.has(this.#excelKeys.workbook)) {
|
305
|
+
this.#set(this.#excelKeys.workbook, Buffer.from(Utils.Common.removeSheetFromWorkbook(this.#readFile(this.#excelKeys.workbook).toString(), sheetIndex)));
|
306
|
+
}
|
307
|
+
// remove sheet from workbook relations
|
308
|
+
if (this.fileKeys.has(this.#excelKeys.workbookRels)) {
|
309
|
+
this.#set(this.#excelKeys.workbookRels, Buffer.from(Utils.Common.removeSheetFromRels(this.#readFile(this.#excelKeys.workbookRels).toString(), sheetIndex)));
|
310
|
+
}
|
311
|
+
// remove sheet from content types
|
312
|
+
if (this.fileKeys.has(this.#excelKeys.contentTypes)) {
|
313
|
+
this.#set(this.#excelKeys.contentTypes, Buffer.from(Utils.Common.removeSheetFromContentTypes(this.#readFile(this.#excelKeys.contentTypes).toString(), sheetIndex)));
|
314
|
+
}
|
315
|
+
}
|
316
|
+
}
|
254
317
|
/**
|
255
318
|
* Validates the template by checking all required files exist.
|
256
319
|
*
|
@@ -270,6 +333,7 @@ class TemplateFs {
|
|
270
333
|
}
|
271
334
|
}
|
272
335
|
}
|
336
|
+
/** Public methods */
|
273
337
|
/**
|
274
338
|
* Copies a sheet from the template to a new name.
|
275
339
|
*
|
@@ -290,7 +354,7 @@ class TemplateFs {
|
|
290
354
|
}
|
291
355
|
// Read workbook.xml and find the source sheet
|
292
356
|
const workbookXmlPath = this.#excelKeys.workbook;
|
293
|
-
const workbookXml = Xml.extractXmlFromSheet(await this.#readFile(workbookXmlPath));
|
357
|
+
const workbookXml = await Xml.extractXmlFromSheet(await this.#readFile(workbookXmlPath));
|
294
358
|
// Find the source sheet
|
295
359
|
const sheetMatch = workbookXml.match(Utils.sheetMatch(sourceName));
|
296
360
|
if (!sheetMatch || !sheetMatch[1]) {
|
@@ -304,7 +368,7 @@ class TemplateFs {
|
|
304
368
|
// Find the source sheet path by rId
|
305
369
|
const rId = sheetMatch[1];
|
306
370
|
const relsXmlPath = this.#excelKeys.workbookRels;
|
307
|
-
const relsXml = Xml.extractXmlFromSheet(await this.#readFile(relsXmlPath));
|
371
|
+
const relsXml = await Xml.extractXmlFromSheet(await this.#readFile(relsXmlPath));
|
308
372
|
const relMatch = relsXml.match(Utils.relationshipMatch(rId));
|
309
373
|
if (!relMatch || !relMatch[1]) {
|
310
374
|
throw new Error(`Relationship "${rId}" not found`);
|
@@ -339,7 +403,7 @@ class TemplateFs {
|
|
339
403
|
// Read [Content_Types].xml
|
340
404
|
// Update [Content_Types].xml
|
341
405
|
const contentTypesPath = this.#excelKeys.contentTypes;
|
342
|
-
const contentTypesXml = Xml.extractXmlFromSheet(await this.#readFile(contentTypesPath));
|
406
|
+
const contentTypesXml = await Xml.extractXmlFromSheet(await this.#readFile(contentTypesPath));
|
343
407
|
const overrideTag = `<Override PartName="/xl/worksheets/${newSheetFilename}" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>`;
|
344
408
|
const updatedContentTypesXml = contentTypesXml.replace("</Types>", overrideTag + "</Types>");
|
345
409
|
await this.#set(contentTypesPath, updatedContentTypesXml);
|
@@ -360,12 +424,12 @@ class TemplateFs {
|
|
360
424
|
* @param replacements - An object where keys represent placeholder paths and values are the replacements.
|
361
425
|
* @returns A promise that resolves when the substitution is complete.
|
362
426
|
*/
|
363
|
-
substitute(sheetName, replacements) {
|
427
|
+
async substitute(sheetName, replacements) {
|
364
428
|
this.#ensureNotProcessing();
|
365
429
|
this.#ensureNotDestroyed();
|
366
430
|
this.#isProcessing = true;
|
367
431
|
try {
|
368
|
-
|
432
|
+
await this.#substitute(sheetName, replacements);
|
369
433
|
}
|
370
434
|
finally {
|
371
435
|
this.#isProcessing = false;
|
@@ -398,7 +462,7 @@ class TemplateFs {
|
|
398
462
|
// Find the sheet
|
399
463
|
const sheetPath = await this.#getSheetPathByName(sheetName);
|
400
464
|
const sheetXmlRaw = await this.#readFile(sheetPath);
|
401
|
-
const sheetXml = Xml.extractXmlFromSheet(sheetXmlRaw);
|
465
|
+
const sheetXml = await Xml.extractXmlFromSheet(sheetXmlRaw);
|
402
466
|
let nextRow = 0;
|
403
467
|
if (!startRowNumber) {
|
404
468
|
// Find the last row
|
@@ -527,7 +591,7 @@ class TemplateFs {
|
|
527
591
|
}
|
528
592
|
}
|
529
593
|
const { dimension: newDimension, rowNumber: actualRowNumber } = await Utils.writeRowsToStream(output, rows, maxRowNumber);
|
530
|
-
if (compareColumns(newDimension.maxColumn, dimension.maxColumn) > 0) {
|
594
|
+
if (Utils.compareColumns(newDimension.maxColumn, dimension.maxColumn) > 0) {
|
531
595
|
dimension.maxColumn = newDimension.maxColumn;
|
532
596
|
}
|
533
597
|
if (newDimension.maxRow > dimension.maxRow) {
|
@@ -574,7 +638,7 @@ class TemplateFs {
|
|
574
638
|
}
|
575
639
|
// new <row>
|
576
640
|
const { dimension: newDimension, rowNumber: actualRowNumber } = await Utils.writeRowsToStream(output, rows, maxRowNumber);
|
577
|
-
if (compareColumns(newDimension.maxColumn, dimension.maxColumn) > 0) {
|
641
|
+
if (Utils.compareColumns(newDimension.maxColumn, dimension.maxColumn) > 0) {
|
578
642
|
dimension.maxColumn = newDimension.maxColumn;
|
579
643
|
}
|
580
644
|
if (newDimension.maxRow > dimension.maxRow) {
|
@@ -607,7 +671,7 @@ class TemplateFs {
|
|
607
671
|
output.write("<sheetData>");
|
608
672
|
// Prepare the rows
|
609
673
|
const { dimension: newDimension } = await Utils.writeRowsToStream(output, rows, maxRowNumber);
|
610
|
-
if (compareColumns(newDimension.maxColumn, dimension.maxColumn) > 0) {
|
674
|
+
if (Utils.compareColumns(newDimension.maxColumn, dimension.maxColumn) > 0) {
|
611
675
|
dimension.maxColumn = newDimension.maxColumn;
|
612
676
|
}
|
613
677
|
if (newDimension.maxRow > dimension.maxRow) {
|
@@ -674,6 +738,25 @@ class TemplateFs {
|
|
674
738
|
this.#isProcessing = false;
|
675
739
|
}
|
676
740
|
}
|
741
|
+
/**
|
742
|
+
* Removes sheets from the workbook.
|
743
|
+
*
|
744
|
+
* @param {Object} data
|
745
|
+
* @param {number[]} [data.sheetIndexes] - The 1-based indexes of the sheets to remove.
|
746
|
+
* @param {string[]} [data.sheetNames] - The names of the sheets to remove.
|
747
|
+
* @returns {void}
|
748
|
+
*/
|
749
|
+
async removeSheets(data) {
|
750
|
+
this.#ensureNotProcessing();
|
751
|
+
this.#ensureNotDestroyed();
|
752
|
+
this.#isProcessing = true;
|
753
|
+
try {
|
754
|
+
await this.#removeSheets(data);
|
755
|
+
}
|
756
|
+
finally {
|
757
|
+
this.#isProcessing = false;
|
758
|
+
}
|
759
|
+
}
|
677
760
|
/**
|
678
761
|
* Saves the modified Excel template to a buffer.
|
679
762
|
*
|
@@ -762,6 +845,7 @@ class TemplateFs {
|
|
762
845
|
this.#isProcessing = false;
|
763
846
|
}
|
764
847
|
}
|
848
|
+
/** Static methods */
|
765
849
|
/**
|
766
850
|
* Creates a Template instance from an Excel file source.
|
767
851
|
* Removes any existing files in the destination directory.
|
@@ -800,8 +884,3 @@ class TemplateFs {
|
|
800
884
|
}
|
801
885
|
}
|
802
886
|
exports.TemplateFs = TemplateFs;
|
803
|
-
const compareColumns = (a, b) => {
|
804
|
-
if (a === b)
|
805
|
-
return 0;
|
806
|
-
return a.length === b.length ? (a < b ? -1 : 1) : (a.length < b.length ? -1 : 1);
|
807
|
-
};
|