@simplysm/excel 13.0.75 → 13.0.77

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 (54) hide show
  1. package/README.md +539 -17
  2. package/dist/excel-cell.d.ts +4 -4
  3. package/dist/excel-cell.d.ts.map +1 -1
  4. package/dist/excel-cell.js +9 -10
  5. package/dist/excel-cell.js.map +1 -1
  6. package/dist/excel-workbook.d.ts +3 -3
  7. package/dist/excel-workbook.d.ts.map +1 -1
  8. package/dist/excel-workbook.js +3 -3
  9. package/dist/excel-workbook.js.map +1 -1
  10. package/dist/excel-worksheet.d.ts +1 -1
  11. package/dist/excel-worksheet.d.ts.map +1 -1
  12. package/dist/excel-worksheet.js +13 -17
  13. package/dist/excel-worksheet.js.map +1 -1
  14. package/dist/excel-wrapper.d.ts +1 -1
  15. package/dist/excel-wrapper.js +7 -7
  16. package/dist/excel-wrapper.js.map +1 -1
  17. package/dist/types.d.ts +1 -1
  18. package/dist/types.d.ts.map +1 -1
  19. package/dist/utils/excel-utils.d.ts +5 -5
  20. package/dist/utils/excel-utils.d.ts.map +1 -1
  21. package/dist/utils/excel-utils.js +15 -15
  22. package/dist/utils/excel-utils.js.map +1 -1
  23. package/dist/utils/zip-cache.js +3 -3
  24. package/dist/utils/zip-cache.js.map +1 -1
  25. package/dist/xml/excel-xml-relationship.js +2 -2
  26. package/dist/xml/excel-xml-relationship.js.map +1 -1
  27. package/dist/xml/excel-xml-style.js +16 -16
  28. package/dist/xml/excel-xml-style.js.map +1 -1
  29. package/dist/xml/excel-xml-workbook.js +6 -6
  30. package/dist/xml/excel-xml-workbook.js.map +1 -1
  31. package/dist/xml/excel-xml-worksheet.d.ts +5 -2
  32. package/dist/xml/excel-xml-worksheet.d.ts.map +1 -1
  33. package/dist/xml/excel-xml-worksheet.js +38 -20
  34. package/dist/xml/excel-xml-worksheet.js.map +1 -1
  35. package/package.json +2 -2
  36. package/src/excel-cell.ts +10 -11
  37. package/src/excel-workbook.ts +3 -3
  38. package/src/excel-worksheet.ts +17 -18
  39. package/src/excel-wrapper.ts +7 -7
  40. package/src/types.ts +1 -1
  41. package/src/utils/excel-utils.ts +15 -15
  42. package/src/utils/zip-cache.ts +3 -3
  43. package/src/xml/excel-xml-relationship.ts +2 -2
  44. package/src/xml/excel-xml-style.ts +16 -16
  45. package/src/xml/excel-xml-workbook.ts +6 -6
  46. package/src/xml/excel-xml-worksheet.ts +47 -22
  47. package/tests/excel-cell.spec.ts +85 -140
  48. package/tests/excel-col.spec.ts +17 -48
  49. package/tests/excel-row.spec.ts +13 -23
  50. package/tests/excel-workbook.spec.ts +26 -40
  51. package/tests/excel-worksheet.spec.ts +217 -137
  52. package/tests/excel-wrapper.spec.ts +24 -47
  53. package/tests/image-insert.spec.ts +5 -5
  54. package/tests/utils/excel-utils.spec.ts +14 -58
@@ -3,17 +3,9 @@ import { ExcelWorkbook } from "../src/excel-workbook";
3
3
 
4
4
  describe("ExcelWorksheet", () => {
5
5
  describe("Sheet name", () => {
6
- it("should get sheet name", async () => {
7
- const wb = new ExcelWorkbook();
8
- const ws = await wb.createWorksheet("MySheet");
9
-
10
- const name = await ws.getName();
11
- expect(name).toBe("MySheet");
12
- });
13
-
14
6
  it("should change sheet name", async () => {
15
7
  const wb = new ExcelWorkbook();
16
- const ws = await wb.createWorksheet("OldName");
8
+ const ws = await wb.addWorksheet("OldName");
17
9
 
18
10
  await ws.setName("NewName");
19
11
  const name = await ws.getName();
@@ -22,10 +14,10 @@ describe("ExcelWorksheet", () => {
22
14
 
23
15
  it("should preserve changed sheet name after roundtrip", async () => {
24
16
  const wb = new ExcelWorkbook();
25
- const ws = await wb.createWorksheet("OldName");
17
+ const ws = await wb.addWorksheet("OldName");
26
18
  await ws.setName("NewName");
27
19
 
28
- const bytes = await wb.getBytes();
20
+ const bytes = await wb.toBytes();
29
21
 
30
22
  const wb2 = new ExcelWorkbook(bytes);
31
23
  const names = await wb2.getWorksheetNames();
@@ -41,47 +33,47 @@ describe("ExcelWorksheet", () => {
41
33
  describe("Row/Column copy", () => {
42
34
  it("should copy row", async () => {
43
35
  const wb = new ExcelWorkbook();
44
- const ws = await wb.createWorksheet("Test");
36
+ const ws = await wb.addWorksheet("Test");
45
37
 
46
38
  // Set source row
47
- await ws.cell(0, 0).setVal("A");
48
- await ws.cell(0, 1).setVal("B");
49
- await ws.cell(0, 2).setVal("C");
39
+ await ws.cell(0, 0).setValue("A");
40
+ await ws.cell(0, 1).setValue("B");
41
+ await ws.cell(0, 2).setValue("C");
50
42
 
51
43
  // Copy row
52
44
  await ws.copyRow(0, 2);
53
45
 
54
- expect(await ws.cell(2, 0).getVal()).toBe("A");
55
- expect(await ws.cell(2, 1).getVal()).toBe("B");
56
- expect(await ws.cell(2, 2).getVal()).toBe("C");
46
+ expect(await ws.cell(2, 0).getValue()).toBe("A");
47
+ expect(await ws.cell(2, 1).getValue()).toBe("B");
48
+ expect(await ws.cell(2, 2).getValue()).toBe("C");
57
49
  });
58
50
 
59
51
  it("should copy cell", async () => {
60
52
  const wb = new ExcelWorkbook();
61
- const ws = await wb.createWorksheet("Test");
53
+ const ws = await wb.addWorksheet("Test");
62
54
 
63
- await ws.cell(0, 0).setVal("Original");
55
+ await ws.cell(0, 0).setValue("Original");
64
56
  await ws.copyCell({ r: 0, c: 0 }, { r: 1, c: 1 });
65
57
 
66
- expect(await ws.cell(1, 1).getVal()).toBe("Original");
58
+ expect(await ws.cell(1, 1).getValue()).toBe("Original");
67
59
  });
68
60
 
69
61
  it("should copy only row style", async () => {
70
62
  const wb = new ExcelWorkbook();
71
- const ws = await wb.createWorksheet("Test");
63
+ const ws = await wb.addWorksheet("Test");
72
64
 
73
65
  // Set styles
74
- await ws.cell(0, 0).setVal("Styled");
66
+ await ws.cell(0, 0).setValue("Styled");
75
67
  await ws.cell(0, 0).setStyle({ background: "00FF0000" });
76
- await ws.cell(0, 1).setVal("Also Styled");
68
+ await ws.cell(0, 1).setValue("Also Styled");
77
69
  await ws.cell(0, 1).setStyle({ background: "0000FF00" });
78
70
 
79
71
  // Copy only styles
80
72
  await ws.copyRowStyle(0, 2);
81
73
 
82
74
  // Values should not be copied
83
- expect(await ws.cell(2, 0).getVal()).toBeUndefined();
84
- expect(await ws.cell(2, 1).getVal()).toBeUndefined();
75
+ expect(await ws.cell(2, 0).getValue()).toBeUndefined();
76
+ expect(await ws.cell(2, 1).getValue()).toBeUndefined();
85
77
 
86
78
  // Styles should be copied
87
79
  const styleId0 = await ws.cell(0, 0).getStyleId();
@@ -91,65 +83,85 @@ describe("ExcelWorksheet", () => {
91
83
 
92
84
  it("should insert copy row when srcR < targetR", async () => {
93
85
  const wb = new ExcelWorkbook();
94
- const ws = await wb.createWorksheet("Test");
86
+ const ws = await wb.addWorksheet("Test");
95
87
 
96
- await ws.cell(0, 0).setVal("Row0");
97
- await ws.cell(1, 0).setVal("Row1");
98
- await ws.cell(2, 0).setVal("Row2");
88
+ await ws.cell(0, 0).setValue("Row0");
89
+ await ws.cell(1, 0).setValue("Row1");
90
+ await ws.cell(2, 0).setValue("Row2");
99
91
 
100
92
  // Insert copy row 0 at position 1 (existing rows are shifted)
101
93
  await ws.insertCopyRow(0, 1);
102
94
 
103
- expect(await ws.cell(0, 0).getVal()).toBe("Row0");
104
- expect(await ws.cell(1, 0).getVal()).toBe("Row0"); // copied
105
- expect(await ws.cell(2, 0).getVal()).toBe("Row1"); // shifted
106
- expect(await ws.cell(3, 0).getVal()).toBe("Row2"); // shifted
95
+ expect(await ws.cell(0, 0).getValue()).toBe("Row0");
96
+ expect(await ws.cell(1, 0).getValue()).toBe("Row0"); // copied
97
+ expect(await ws.cell(2, 0).getValue()).toBe("Row1"); // shifted
98
+ expect(await ws.cell(3, 0).getValue()).toBe("Row2"); // shifted
107
99
  });
108
100
 
109
101
  it("should insert copy row when srcR > targetR", async () => {
110
102
  const wb = new ExcelWorkbook();
111
- const ws = await wb.createWorksheet("Test");
103
+ const ws = await wb.addWorksheet("Test");
112
104
 
113
- await ws.cell(0, 0).setVal("Row0");
114
- await ws.cell(1, 0).setVal("Row1");
115
- await ws.cell(2, 0).setVal("Row2");
116
- await ws.cell(3, 0).setVal("Row3");
105
+ await ws.cell(0, 0).setValue("Row0");
106
+ await ws.cell(1, 0).setValue("Row1");
107
+ await ws.cell(2, 0).setValue("Row2");
108
+ await ws.cell(3, 0).setValue("Row3");
117
109
 
118
110
  // Insert copy row 2 at position 1 (existing rows are shifted)
119
111
  await ws.insertCopyRow(2, 1);
120
112
 
121
- expect(await ws.cell(0, 0).getVal()).toBe("Row0");
122
- expect(await ws.cell(1, 0).getVal()).toBe("Row2"); // copied
123
- expect(await ws.cell(2, 0).getVal()).toBe("Row1"); // shifted
124
- expect(await ws.cell(3, 0).getVal()).toBe("Row2"); // shifted (original Row2)
125
- expect(await ws.cell(4, 0).getVal()).toBe("Row3"); // shifted
113
+ expect(await ws.cell(0, 0).getValue()).toBe("Row0");
114
+ expect(await ws.cell(1, 0).getValue()).toBe("Row2"); // copied
115
+ expect(await ws.cell(2, 0).getValue()).toBe("Row1"); // shifted
116
+ expect(await ws.cell(3, 0).getValue()).toBe("Row2"); // shifted (original Row2)
117
+ expect(await ws.cell(4, 0).getValue()).toBe("Row3"); // shifted
126
118
  });
127
119
 
128
120
  it("should insert copy row when srcR == targetR", async () => {
129
121
  const wb = new ExcelWorkbook();
130
- const ws = await wb.createWorksheet("Test");
122
+ const ws = await wb.addWorksheet("Test");
131
123
 
132
- await ws.cell(0, 0).setVal("Row0");
133
- await ws.cell(1, 0).setVal("Row1");
134
- await ws.cell(2, 0).setVal("Row2");
124
+ await ws.cell(0, 0).setValue("Row0");
125
+ await ws.cell(1, 0).setValue("Row1");
126
+ await ws.cell(2, 0).setValue("Row2");
135
127
 
136
128
  // Insert copy row 1 at position 1 (copy itself)
137
129
  await ws.insertCopyRow(1, 1);
138
130
 
139
- expect(await ws.cell(0, 0).getVal()).toBe("Row0");
140
- expect(await ws.cell(1, 0).getVal()).toBe("Row1"); // copied
141
- expect(await ws.cell(2, 0).getVal()).toBe("Row1"); // shifted (original Row1)
142
- expect(await ws.cell(3, 0).getVal()).toBe("Row2"); // shifted
131
+ expect(await ws.cell(0, 0).getValue()).toBe("Row0");
132
+ expect(await ws.cell(1, 0).getValue()).toBe("Row1"); // copied
133
+ expect(await ws.cell(2, 0).getValue()).toBe("Row1"); // shifted (original Row1)
134
+ expect(await ws.cell(3, 0).getValue()).toBe("Row2"); // shifted
135
+ });
136
+
137
+ it("should skip merge handling when skipMerge is true", async () => {
138
+ const wb = new ExcelWorkbook();
139
+ const ws = await wb.addWorksheet("Test");
140
+
141
+ await ws.cell(0, 0).setValue("Row0");
142
+ await ws.cell(1, 0).setValue("Row1");
143
+ await ws.cell(0, 0).merge(0, 1); // Merge A1:B1
144
+
145
+ const wsData = await ws["_getWsData"]();
146
+
147
+ // Copy row 0 to row 1, but skip merge handling
148
+ wsData.copyRow(0, 1, { skipMerge: true });
149
+
150
+ // Row 1 should have the data but merge should not be copied
151
+ const merges = wsData.getMergeCells();
152
+ expect(merges).toEqual([
153
+ { s: { r: 0, c: 0 }, e: { r: 0, c: 1 } }, // original merge, unchanged
154
+ ]);
143
155
  });
144
156
  });
145
157
 
146
158
  describe("Range and cell access", () => {
147
159
  it("should get data range", async () => {
148
160
  const wb = new ExcelWorkbook();
149
- const ws = await wb.createWorksheet("Test");
161
+ const ws = await wb.addWorksheet("Test");
150
162
 
151
- await ws.cell(0, 0).setVal("A");
152
- await ws.cell(2, 3).setVal("D");
163
+ await ws.cell(0, 0).setValue("A");
164
+ await ws.cell(2, 3).setValue("D");
153
165
 
154
166
  const range = await ws.getRange();
155
167
  expect(range.s.r).toBe(0);
@@ -160,12 +172,12 @@ describe("ExcelWorksheet", () => {
160
172
 
161
173
  it("should get all cells", async () => {
162
174
  const wb = new ExcelWorkbook();
163
- const ws = await wb.createWorksheet("Test");
175
+ const ws = await wb.addWorksheet("Test");
164
176
 
165
- await ws.cell(0, 0).setVal("A");
166
- await ws.cell(0, 1).setVal("B");
167
- await ws.cell(1, 0).setVal("C");
168
- await ws.cell(1, 1).setVal("D");
177
+ await ws.cell(0, 0).setValue("A");
178
+ await ws.cell(0, 1).setValue("B");
179
+ await ws.cell(1, 0).setValue("C");
180
+ await ws.cell(1, 1).setValue("D");
169
181
 
170
182
  const cells = await ws.getCells();
171
183
  expect(cells.length).toBe(2);
@@ -176,16 +188,16 @@ describe("ExcelWorksheet", () => {
176
188
  describe("Data table", () => {
177
189
  it("should get data table", async () => {
178
190
  const wb = new ExcelWorkbook();
179
- const ws = await wb.createWorksheet("Test");
191
+ const ws = await wb.addWorksheet("Test");
180
192
 
181
193
  // Headers
182
- await ws.cell(0, 0).setVal("Name");
183
- await ws.cell(0, 1).setVal("Age");
194
+ await ws.cell(0, 0).setValue("Name");
195
+ await ws.cell(0, 1).setValue("Age");
184
196
  // Data
185
- await ws.cell(1, 0).setVal("Alice");
186
- await ws.cell(1, 1).setVal(30);
187
- await ws.cell(2, 0).setVal("Bob");
188
- await ws.cell(2, 1).setVal(25);
197
+ await ws.cell(1, 0).setValue("Alice");
198
+ await ws.cell(1, 1).setValue(30);
199
+ await ws.cell(2, 0).setValue("Bob");
200
+ await ws.cell(2, 1).setValue(25);
189
201
 
190
202
  const data = await ws.getDataTable();
191
203
  expect(data.length).toBe(2);
@@ -197,14 +209,14 @@ describe("ExcelWorksheet", () => {
197
209
 
198
210
  it("should filter specific headers only", async () => {
199
211
  const wb = new ExcelWorkbook();
200
- const ws = await wb.createWorksheet("Test");
212
+ const ws = await wb.addWorksheet("Test");
201
213
 
202
- await ws.cell(0, 0).setVal("Name");
203
- await ws.cell(0, 1).setVal("Age");
204
- await ws.cell(0, 2).setVal("Ignore");
205
- await ws.cell(1, 0).setVal("Alice");
206
- await ws.cell(1, 1).setVal(30);
207
- await ws.cell(1, 2).setVal("X");
214
+ await ws.cell(0, 0).setValue("Name");
215
+ await ws.cell(0, 1).setValue("Age");
216
+ await ws.cell(0, 2).setValue("Ignore");
217
+ await ws.cell(1, 0).setValue("Alice");
218
+ await ws.cell(1, 1).setValue(30);
219
+ await ws.cell(1, 2).setValue("X");
208
220
 
209
221
  const data = await ws.getDataTable({
210
222
  usableHeaderNameFn: (name) => name !== "Ignore",
@@ -217,7 +229,7 @@ describe("ExcelWorksheet", () => {
217
229
 
218
230
  it("should set data matrix", async () => {
219
231
  const wb = new ExcelWorkbook();
220
- const ws = await wb.createWorksheet("Test");
232
+ const ws = await wb.addWorksheet("Test");
221
233
 
222
234
  const matrix = [
223
235
  ["A", "B", "C"],
@@ -227,14 +239,14 @@ describe("ExcelWorksheet", () => {
227
239
 
228
240
  await ws.setDataMatrix(matrix);
229
241
 
230
- expect(await ws.cell(0, 0).getVal()).toBe("A");
231
- expect(await ws.cell(0, 2).getVal()).toBe("C");
232
- expect(await ws.cell(2, 2).getVal()).toBe(6);
242
+ expect(await ws.cell(0, 0).getValue()).toBe("A");
243
+ expect(await ws.cell(0, 2).getValue()).toBe("C");
244
+ expect(await ws.cell(2, 2).getValue()).toBe(6);
233
245
  });
234
246
 
235
247
  it("should set records array", async () => {
236
248
  const wb = new ExcelWorkbook();
237
- const ws = await wb.createWorksheet("Test");
249
+ const ws = await wb.addWorksheet("Test");
238
250
 
239
251
  const records = [
240
252
  { Name: "Alice", Age: 30 },
@@ -244,7 +256,7 @@ describe("ExcelWorksheet", () => {
244
256
  await ws.setRecords(records);
245
257
 
246
258
  // Check headers
247
- const headers = [await ws.cell(0, 0).getVal(), await ws.cell(0, 1).getVal()];
259
+ const headers = [await ws.cell(0, 0).getValue(), await ws.cell(0, 1).getValue()];
248
260
  expect(headers).toContain("Name");
249
261
  expect(headers).toContain("Age");
250
262
 
@@ -254,44 +266,16 @@ describe("ExcelWorksheet", () => {
254
266
  });
255
267
  });
256
268
 
257
- describe("View settings", () => {
258
- it("should set zoom level", async () => {
259
- const wb = new ExcelWorkbook();
260
- const ws = await wb.createWorksheet("Test");
261
-
262
- await ws.setZoom(85);
263
- // Success if set without error
264
- });
265
-
266
- it("should set pane freeze", async () => {
267
- const wb = new ExcelWorkbook();
268
- const ws = await wb.createWorksheet("Test");
269
-
270
- await ws.setFix({ r: 1 }); // Freeze 1 row
271
- await ws.setFix({ c: 2 }); // Freeze 2 columns
272
- await ws.setFix({ r: 1, c: 1 }); // Freeze 1 row and 1 column
273
- // Success if set without error
274
- });
275
- });
276
-
277
269
  describe("Column width", () => {
278
- it("should set column width", async () => {
279
- const wb = new ExcelWorkbook();
280
- const ws = await wb.createWorksheet("Test");
281
-
282
- await ws.col(0).setWidth(20);
283
- // Success if set without error
284
- });
285
-
286
270
  it("should preserve column width after roundtrip", async () => {
287
271
  const wb = new ExcelWorkbook();
288
- const ws = await wb.createWorksheet("Test");
272
+ const ws = await wb.addWorksheet("Test");
289
273
 
290
- await ws.cell(0, 0).setVal("A1");
274
+ await ws.cell(0, 0).setValue("A1");
291
275
  await ws.col(0).setWidth(25);
292
276
  await ws.col(2).setWidth(30);
293
277
 
294
- const bytes = await wb.getBytes();
278
+ const bytes = await wb.toBytes();
295
279
 
296
280
  const wb2 = new ExcelWorkbook(bytes);
297
281
  await wb2.getWorksheet("Test");
@@ -315,33 +299,33 @@ describe("ExcelWorksheet", () => {
315
299
  describe("Column access", () => {
316
300
  it("should get all cells in column", async () => {
317
301
  const wb = new ExcelWorkbook();
318
- const ws = await wb.createWorksheet("Test");
302
+ const ws = await wb.addWorksheet("Test");
319
303
 
320
- await ws.cell(0, 0).setVal("A1");
321
- await ws.cell(1, 0).setVal("A2");
322
- await ws.cell(2, 0).setVal("A3");
304
+ await ws.cell(0, 0).setValue("A1");
305
+ await ws.cell(1, 0).setValue("A2");
306
+ await ws.cell(2, 0).setValue("A3");
323
307
 
324
308
  const cells = await ws.col(0).getCells();
325
309
  expect(cells.length).toBe(3);
326
- expect(await cells[0].getVal()).toBe("A1");
327
- expect(await cells[1].getVal()).toBe("A2");
328
- expect(await cells[2].getVal()).toBe("A3");
310
+ expect(await cells[0].getValue()).toBe("A1");
311
+ expect(await cells[1].getValue()).toBe("A2");
312
+ expect(await cells[2].getValue()).toBe("A3");
329
313
  });
330
314
  });
331
315
 
332
316
  describe("Data table edge cases", () => {
333
317
  it("should return empty array when calling getDataTable on empty sheet", async () => {
334
318
  const wb = new ExcelWorkbook();
335
- const ws = await wb.createWorksheet("Empty");
319
+ const ws = await wb.addWorksheet("Empty");
336
320
  const data = await ws.getDataTable();
337
321
  expect(data).toEqual([]);
338
322
  });
339
323
 
340
324
  it("should return empty array when only headers exist without data", async () => {
341
325
  const wb = new ExcelWorkbook();
342
- const ws = await wb.createWorksheet("Test");
343
- await ws.cell(0, 0).setVal("Header1");
344
- await ws.cell(0, 1).setVal("Header2");
326
+ const ws = await wb.addWorksheet("Test");
327
+ await ws.cell(0, 0).setValue("Header1");
328
+ await ws.cell(0, 1).setValue("Header2");
345
329
  const data = await ws.getDataTable();
346
330
  expect(data).toEqual([]);
347
331
  });
@@ -350,16 +334,16 @@ describe("ExcelWorksheet", () => {
350
334
  describe("Data table options", () => {
351
335
  it("should specify header row with headerRowIndex", async () => {
352
336
  const wb = new ExcelWorkbook();
353
- const ws = await wb.createWorksheet("Test");
337
+ const ws = await wb.addWorksheet("Test");
354
338
 
355
339
  // Row 0 is title
356
- await ws.cell(0, 0).setVal("Title");
340
+ await ws.cell(0, 0).setValue("Title");
357
341
  // Row 1 is header
358
- await ws.cell(1, 0).setVal("Name");
359
- await ws.cell(1, 1).setVal("Age");
342
+ await ws.cell(1, 0).setValue("Name");
343
+ await ws.cell(1, 1).setValue("Age");
360
344
  // Data starts from row 2
361
- await ws.cell(2, 0).setVal("Alice");
362
- await ws.cell(2, 1).setVal(30);
345
+ await ws.cell(2, 0).setValue("Alice");
346
+ await ws.cell(2, 1).setValue(30);
363
347
 
364
348
  const data = await ws.getDataTable({ headerRowIndex: 1 });
365
349
  expect(data.length).toBe(1);
@@ -369,16 +353,16 @@ describe("ExcelWorksheet", () => {
369
353
 
370
354
  it("should detect data end with checkEndColIndex", async () => {
371
355
  const wb = new ExcelWorkbook();
372
- const ws = await wb.createWorksheet("Test");
373
-
374
- await ws.cell(0, 0).setVal("Name");
375
- await ws.cell(0, 1).setVal("Age");
376
- await ws.cell(1, 0).setVal("Alice");
377
- await ws.cell(1, 1).setVal(30);
378
- await ws.cell(2, 0).setVal("Bob");
379
- await ws.cell(2, 1).setVal(25);
356
+ const ws = await wb.addWorksheet("Test");
357
+
358
+ await ws.cell(0, 0).setValue("Name");
359
+ await ws.cell(0, 1).setValue("Age");
360
+ await ws.cell(1, 0).setValue("Alice");
361
+ await ws.cell(1, 1).setValue(30);
362
+ await ws.cell(2, 0).setValue("Bob");
363
+ await ws.cell(2, 1).setValue(25);
380
364
  // Row 3 has empty Name column -> data end
381
- await ws.cell(3, 1).setVal(999);
365
+ await ws.cell(3, 1).setValue(999);
382
366
 
383
367
  const data = await ws.getDataTable({ checkEndColIndex: 0 });
384
368
  expect(data.length).toBe(2);
@@ -386,4 +370,100 @@ describe("ExcelWorksheet", () => {
386
370
  expect(data[1]["Name"]).toBe("Bob");
387
371
  });
388
372
  });
373
+
374
+ describe("Merge cells", () => {
375
+ it("should shift merge cells when inserting row", async () => {
376
+ const wb = new ExcelWorkbook();
377
+ const ws = await wb.addWorksheet("Test");
378
+
379
+ // Create merged cells: A1:B2 and C3:D4
380
+ await ws.cell(0, 0).merge(1, 1); // A1:B2
381
+ await ws.cell(2, 2).merge(3, 3); // C3:D4
382
+
383
+ const wsData = await ws["_getWsData"](); // Access private method for testing
384
+ wsData.shiftMergeCells(2, 1); // Shift rows >= 2 by +1
385
+
386
+ const merges = wsData.getMergeCells();
387
+ expect(merges).toEqual([
388
+ { s: { r: 0, c: 0 }, e: { r: 1, c: 1 } }, // unchanged
389
+ { s: { r: 3, c: 2 }, e: { r: 4, c: 3 } }, // shifted down by 1
390
+ ]);
391
+ });
392
+
393
+ it("should shift merge cells when inserting row with merges", async () => {
394
+ const wb = new ExcelWorkbook();
395
+ const ws = await wb.addWorksheet("Test");
396
+
397
+ await ws.cell(0, 0).setValue("Row0");
398
+ await ws.cell(1, 0).setValue("Row1");
399
+ await ws.cell(2, 0).setValue("Row2");
400
+
401
+ // Create merge A3:B4 (rows 2-3, well below insertion point)
402
+ await ws.cell(2, 0).merge(3, 1);
403
+
404
+ // Insert copy of row 0 at position 1
405
+ await ws.insertCopyRow(0, 1);
406
+
407
+ // Check that merge was shifted correctly
408
+ const wsData = await ws["_getWsData"]();
409
+ const merges = wsData.getMergeCells();
410
+
411
+ // Merge at rows 2-3 should shift to rows 3-4
412
+ expect(merges).toEqual([
413
+ { s: { r: 3, c: 0 }, e: { r: 4, c: 1 } },
414
+ ]);
415
+
416
+ expect(await ws.cell(0, 0).getValue()).toBe("Row0");
417
+ expect(await ws.cell(1, 0).getValue()).toBe("Row0"); // copied
418
+ expect(await ws.cell(2, 0).getValue()).toBe("Row1"); // shifted
419
+ expect(await ws.cell(3, 0).getValue()).toBe("Row2"); // shifted
420
+ });
421
+
422
+ it("should handle multi-row merge when inserting row", async () => {
423
+ const wb = new ExcelWorkbook();
424
+ const ws = await wb.addWorksheet("Test");
425
+
426
+ await ws.cell(0, 0).setValue("Row0");
427
+ await ws.cell(1, 0).setValue("Row1");
428
+ await ws.cell(2, 0).setValue("Row2");
429
+ await ws.cell(3, 0).setValue("Row3");
430
+
431
+ // Create merge A3:B4 (rows 2-3, below insertion point)
432
+ await ws.cell(2, 0).merge(3, 1);
433
+
434
+ // Insert copy of row 0 at position 1
435
+ await ws.insertCopyRow(0, 1);
436
+
437
+ const wsData = await ws["_getWsData"]();
438
+ const merges = wsData.getMergeCells();
439
+
440
+ // Merge at rows 2-3 should shift to rows 3-4 (rows >= 1 shift by 1)
441
+ expect(merges).toHaveLength(1);
442
+ expect(merges[0].s).toEqual({ r: 3, c: 0 });
443
+ expect(merges[0].e).toEqual({ r: 4, c: 1 }); // shifted from 2-3 to 3-4
444
+ });
445
+
446
+ it("should not shift merge above insertion point", async () => {
447
+ const wb = new ExcelWorkbook();
448
+ const ws = await wb.addWorksheet("Test");
449
+
450
+ await ws.cell(0, 0).setValue("Row0");
451
+ await ws.cell(1, 0).setValue("Row1");
452
+ await ws.cell(2, 0).setValue("Row2");
453
+
454
+ // Create merge A1:B1 (row 0)
455
+ await ws.cell(0, 0).merge(0, 1);
456
+
457
+ // Insert copy of row 1 at position 2
458
+ await ws.insertCopyRow(1, 2);
459
+
460
+ const wsData = await ws["_getWsData"]();
461
+ const merges = wsData.getMergeCells();
462
+
463
+ // Merge should remain unchanged at A1:B1
464
+ expect(merges).toEqual([
465
+ { s: { r: 0, c: 0 }, e: { r: 0, c: 1 } },
466
+ ]);
467
+ });
468
+ });
389
469
  });