@simplysm/excel 13.0.76 → 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 -69
  48. package/tests/excel-col.spec.ts +17 -17
  49. package/tests/excel-row.spec.ts +13 -13
  50. package/tests/excel-workbook.spec.ts +26 -26
  51. package/tests/excel-worksheet.spec.ts +217 -101
  52. package/tests/excel-wrapper.spec.ts +24 -24
  53. package/tests/image-insert.spec.ts +5 -5
  54. package/tests/utils/excel-utils.spec.ts +14 -14
@@ -5,7 +5,7 @@ describe("ExcelWorksheet", () => {
5
5
  describe("Sheet name", () => {
6
6
  it("should change sheet name", async () => {
7
7
  const wb = new ExcelWorkbook();
8
- const ws = await wb.createWorksheet("OldName");
8
+ const ws = await wb.addWorksheet("OldName");
9
9
 
10
10
  await ws.setName("NewName");
11
11
  const name = await ws.getName();
@@ -14,10 +14,10 @@ describe("ExcelWorksheet", () => {
14
14
 
15
15
  it("should preserve changed sheet name after roundtrip", async () => {
16
16
  const wb = new ExcelWorkbook();
17
- const ws = await wb.createWorksheet("OldName");
17
+ const ws = await wb.addWorksheet("OldName");
18
18
  await ws.setName("NewName");
19
19
 
20
- const bytes = await wb.getBytes();
20
+ const bytes = await wb.toBytes();
21
21
 
22
22
  const wb2 = new ExcelWorkbook(bytes);
23
23
  const names = await wb2.getWorksheetNames();
@@ -33,47 +33,47 @@ describe("ExcelWorksheet", () => {
33
33
  describe("Row/Column copy", () => {
34
34
  it("should copy row", async () => {
35
35
  const wb = new ExcelWorkbook();
36
- const ws = await wb.createWorksheet("Test");
36
+ const ws = await wb.addWorksheet("Test");
37
37
 
38
38
  // Set source row
39
- await ws.cell(0, 0).setVal("A");
40
- await ws.cell(0, 1).setVal("B");
41
- 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");
42
42
 
43
43
  // Copy row
44
44
  await ws.copyRow(0, 2);
45
45
 
46
- expect(await ws.cell(2, 0).getVal()).toBe("A");
47
- expect(await ws.cell(2, 1).getVal()).toBe("B");
48
- 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");
49
49
  });
50
50
 
51
51
  it("should copy cell", async () => {
52
52
  const wb = new ExcelWorkbook();
53
- const ws = await wb.createWorksheet("Test");
53
+ const ws = await wb.addWorksheet("Test");
54
54
 
55
- await ws.cell(0, 0).setVal("Original");
55
+ await ws.cell(0, 0).setValue("Original");
56
56
  await ws.copyCell({ r: 0, c: 0 }, { r: 1, c: 1 });
57
57
 
58
- expect(await ws.cell(1, 1).getVal()).toBe("Original");
58
+ expect(await ws.cell(1, 1).getValue()).toBe("Original");
59
59
  });
60
60
 
61
61
  it("should copy only row style", async () => {
62
62
  const wb = new ExcelWorkbook();
63
- const ws = await wb.createWorksheet("Test");
63
+ const ws = await wb.addWorksheet("Test");
64
64
 
65
65
  // Set styles
66
- await ws.cell(0, 0).setVal("Styled");
66
+ await ws.cell(0, 0).setValue("Styled");
67
67
  await ws.cell(0, 0).setStyle({ background: "00FF0000" });
68
- await ws.cell(0, 1).setVal("Also Styled");
68
+ await ws.cell(0, 1).setValue("Also Styled");
69
69
  await ws.cell(0, 1).setStyle({ background: "0000FF00" });
70
70
 
71
71
  // Copy only styles
72
72
  await ws.copyRowStyle(0, 2);
73
73
 
74
74
  // Values should not be copied
75
- expect(await ws.cell(2, 0).getVal()).toBeUndefined();
76
- 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();
77
77
 
78
78
  // Styles should be copied
79
79
  const styleId0 = await ws.cell(0, 0).getStyleId();
@@ -83,65 +83,85 @@ describe("ExcelWorksheet", () => {
83
83
 
84
84
  it("should insert copy row when srcR < targetR", async () => {
85
85
  const wb = new ExcelWorkbook();
86
- const ws = await wb.createWorksheet("Test");
86
+ const ws = await wb.addWorksheet("Test");
87
87
 
88
- await ws.cell(0, 0).setVal("Row0");
89
- await ws.cell(1, 0).setVal("Row1");
90
- 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");
91
91
 
92
92
  // Insert copy row 0 at position 1 (existing rows are shifted)
93
93
  await ws.insertCopyRow(0, 1);
94
94
 
95
- expect(await ws.cell(0, 0).getVal()).toBe("Row0");
96
- expect(await ws.cell(1, 0).getVal()).toBe("Row0"); // copied
97
- expect(await ws.cell(2, 0).getVal()).toBe("Row1"); // shifted
98
- 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
99
99
  });
100
100
 
101
101
  it("should insert copy row when srcR > targetR", async () => {
102
102
  const wb = new ExcelWorkbook();
103
- const ws = await wb.createWorksheet("Test");
103
+ const ws = await wb.addWorksheet("Test");
104
104
 
105
- await ws.cell(0, 0).setVal("Row0");
106
- await ws.cell(1, 0).setVal("Row1");
107
- await ws.cell(2, 0).setVal("Row2");
108
- 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");
109
109
 
110
110
  // Insert copy row 2 at position 1 (existing rows are shifted)
111
111
  await ws.insertCopyRow(2, 1);
112
112
 
113
- expect(await ws.cell(0, 0).getVal()).toBe("Row0");
114
- expect(await ws.cell(1, 0).getVal()).toBe("Row2"); // copied
115
- expect(await ws.cell(2, 0).getVal()).toBe("Row1"); // shifted
116
- expect(await ws.cell(3, 0).getVal()).toBe("Row2"); // shifted (original Row2)
117
- 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
118
118
  });
119
119
 
120
120
  it("should insert copy row when srcR == targetR", async () => {
121
121
  const wb = new ExcelWorkbook();
122
- const ws = await wb.createWorksheet("Test");
122
+ const ws = await wb.addWorksheet("Test");
123
123
 
124
- await ws.cell(0, 0).setVal("Row0");
125
- await ws.cell(1, 0).setVal("Row1");
126
- 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");
127
127
 
128
128
  // Insert copy row 1 at position 1 (copy itself)
129
129
  await ws.insertCopyRow(1, 1);
130
130
 
131
- expect(await ws.cell(0, 0).getVal()).toBe("Row0");
132
- expect(await ws.cell(1, 0).getVal()).toBe("Row1"); // copied
133
- expect(await ws.cell(2, 0).getVal()).toBe("Row1"); // shifted (original Row1)
134
- 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
+ ]);
135
155
  });
136
156
  });
137
157
 
138
158
  describe("Range and cell access", () => {
139
159
  it("should get data range", async () => {
140
160
  const wb = new ExcelWorkbook();
141
- const ws = await wb.createWorksheet("Test");
161
+ const ws = await wb.addWorksheet("Test");
142
162
 
143
- await ws.cell(0, 0).setVal("A");
144
- await ws.cell(2, 3).setVal("D");
163
+ await ws.cell(0, 0).setValue("A");
164
+ await ws.cell(2, 3).setValue("D");
145
165
 
146
166
  const range = await ws.getRange();
147
167
  expect(range.s.r).toBe(0);
@@ -152,12 +172,12 @@ describe("ExcelWorksheet", () => {
152
172
 
153
173
  it("should get all cells", async () => {
154
174
  const wb = new ExcelWorkbook();
155
- const ws = await wb.createWorksheet("Test");
175
+ const ws = await wb.addWorksheet("Test");
156
176
 
157
- await ws.cell(0, 0).setVal("A");
158
- await ws.cell(0, 1).setVal("B");
159
- await ws.cell(1, 0).setVal("C");
160
- 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");
161
181
 
162
182
  const cells = await ws.getCells();
163
183
  expect(cells.length).toBe(2);
@@ -168,16 +188,16 @@ describe("ExcelWorksheet", () => {
168
188
  describe("Data table", () => {
169
189
  it("should get data table", async () => {
170
190
  const wb = new ExcelWorkbook();
171
- const ws = await wb.createWorksheet("Test");
191
+ const ws = await wb.addWorksheet("Test");
172
192
 
173
193
  // Headers
174
- await ws.cell(0, 0).setVal("Name");
175
- await ws.cell(0, 1).setVal("Age");
194
+ await ws.cell(0, 0).setValue("Name");
195
+ await ws.cell(0, 1).setValue("Age");
176
196
  // Data
177
- await ws.cell(1, 0).setVal("Alice");
178
- await ws.cell(1, 1).setVal(30);
179
- await ws.cell(2, 0).setVal("Bob");
180
- 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);
181
201
 
182
202
  const data = await ws.getDataTable();
183
203
  expect(data.length).toBe(2);
@@ -189,14 +209,14 @@ describe("ExcelWorksheet", () => {
189
209
 
190
210
  it("should filter specific headers only", async () => {
191
211
  const wb = new ExcelWorkbook();
192
- const ws = await wb.createWorksheet("Test");
212
+ const ws = await wb.addWorksheet("Test");
193
213
 
194
- await ws.cell(0, 0).setVal("Name");
195
- await ws.cell(0, 1).setVal("Age");
196
- await ws.cell(0, 2).setVal("Ignore");
197
- await ws.cell(1, 0).setVal("Alice");
198
- await ws.cell(1, 1).setVal(30);
199
- 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");
200
220
 
201
221
  const data = await ws.getDataTable({
202
222
  usableHeaderNameFn: (name) => name !== "Ignore",
@@ -209,7 +229,7 @@ describe("ExcelWorksheet", () => {
209
229
 
210
230
  it("should set data matrix", async () => {
211
231
  const wb = new ExcelWorkbook();
212
- const ws = await wb.createWorksheet("Test");
232
+ const ws = await wb.addWorksheet("Test");
213
233
 
214
234
  const matrix = [
215
235
  ["A", "B", "C"],
@@ -219,14 +239,14 @@ describe("ExcelWorksheet", () => {
219
239
 
220
240
  await ws.setDataMatrix(matrix);
221
241
 
222
- expect(await ws.cell(0, 0).getVal()).toBe("A");
223
- expect(await ws.cell(0, 2).getVal()).toBe("C");
224
- 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);
225
245
  });
226
246
 
227
247
  it("should set records array", async () => {
228
248
  const wb = new ExcelWorkbook();
229
- const ws = await wb.createWorksheet("Test");
249
+ const ws = await wb.addWorksheet("Test");
230
250
 
231
251
  const records = [
232
252
  { Name: "Alice", Age: 30 },
@@ -236,7 +256,7 @@ describe("ExcelWorksheet", () => {
236
256
  await ws.setRecords(records);
237
257
 
238
258
  // Check headers
239
- 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()];
240
260
  expect(headers).toContain("Name");
241
261
  expect(headers).toContain("Age");
242
262
 
@@ -249,13 +269,13 @@ describe("ExcelWorksheet", () => {
249
269
  describe("Column width", () => {
250
270
  it("should preserve column width after roundtrip", async () => {
251
271
  const wb = new ExcelWorkbook();
252
- const ws = await wb.createWorksheet("Test");
272
+ const ws = await wb.addWorksheet("Test");
253
273
 
254
- await ws.cell(0, 0).setVal("A1");
274
+ await ws.cell(0, 0).setValue("A1");
255
275
  await ws.col(0).setWidth(25);
256
276
  await ws.col(2).setWidth(30);
257
277
 
258
- const bytes = await wb.getBytes();
278
+ const bytes = await wb.toBytes();
259
279
 
260
280
  const wb2 = new ExcelWorkbook(bytes);
261
281
  await wb2.getWorksheet("Test");
@@ -279,33 +299,33 @@ describe("ExcelWorksheet", () => {
279
299
  describe("Column access", () => {
280
300
  it("should get all cells in column", async () => {
281
301
  const wb = new ExcelWorkbook();
282
- const ws = await wb.createWorksheet("Test");
302
+ const ws = await wb.addWorksheet("Test");
283
303
 
284
- await ws.cell(0, 0).setVal("A1");
285
- await ws.cell(1, 0).setVal("A2");
286
- 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");
287
307
 
288
308
  const cells = await ws.col(0).getCells();
289
309
  expect(cells.length).toBe(3);
290
- expect(await cells[0].getVal()).toBe("A1");
291
- expect(await cells[1].getVal()).toBe("A2");
292
- 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");
293
313
  });
294
314
  });
295
315
 
296
316
  describe("Data table edge cases", () => {
297
317
  it("should return empty array when calling getDataTable on empty sheet", async () => {
298
318
  const wb = new ExcelWorkbook();
299
- const ws = await wb.createWorksheet("Empty");
319
+ const ws = await wb.addWorksheet("Empty");
300
320
  const data = await ws.getDataTable();
301
321
  expect(data).toEqual([]);
302
322
  });
303
323
 
304
324
  it("should return empty array when only headers exist without data", async () => {
305
325
  const wb = new ExcelWorkbook();
306
- const ws = await wb.createWorksheet("Test");
307
- await ws.cell(0, 0).setVal("Header1");
308
- 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");
309
329
  const data = await ws.getDataTable();
310
330
  expect(data).toEqual([]);
311
331
  });
@@ -314,16 +334,16 @@ describe("ExcelWorksheet", () => {
314
334
  describe("Data table options", () => {
315
335
  it("should specify header row with headerRowIndex", async () => {
316
336
  const wb = new ExcelWorkbook();
317
- const ws = await wb.createWorksheet("Test");
337
+ const ws = await wb.addWorksheet("Test");
318
338
 
319
339
  // Row 0 is title
320
- await ws.cell(0, 0).setVal("Title");
340
+ await ws.cell(0, 0).setValue("Title");
321
341
  // Row 1 is header
322
- await ws.cell(1, 0).setVal("Name");
323
- await ws.cell(1, 1).setVal("Age");
342
+ await ws.cell(1, 0).setValue("Name");
343
+ await ws.cell(1, 1).setValue("Age");
324
344
  // Data starts from row 2
325
- await ws.cell(2, 0).setVal("Alice");
326
- await ws.cell(2, 1).setVal(30);
345
+ await ws.cell(2, 0).setValue("Alice");
346
+ await ws.cell(2, 1).setValue(30);
327
347
 
328
348
  const data = await ws.getDataTable({ headerRowIndex: 1 });
329
349
  expect(data.length).toBe(1);
@@ -333,16 +353,16 @@ describe("ExcelWorksheet", () => {
333
353
 
334
354
  it("should detect data end with checkEndColIndex", async () => {
335
355
  const wb = new ExcelWorkbook();
336
- const ws = await wb.createWorksheet("Test");
337
-
338
- await ws.cell(0, 0).setVal("Name");
339
- await ws.cell(0, 1).setVal("Age");
340
- await ws.cell(1, 0).setVal("Alice");
341
- await ws.cell(1, 1).setVal(30);
342
- await ws.cell(2, 0).setVal("Bob");
343
- 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);
344
364
  // Row 3 has empty Name column -> data end
345
- await ws.cell(3, 1).setVal(999);
365
+ await ws.cell(3, 1).setValue(999);
346
366
 
347
367
  const data = await ws.getDataTable({ checkEndColIndex: 0 });
348
368
  expect(data.length).toBe(2);
@@ -350,4 +370,100 @@ describe("ExcelWorksheet", () => {
350
370
  expect(data[1]["Name"]).toBe("Bob");
351
371
  });
352
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
+ });
353
469
  });
@@ -24,16 +24,16 @@ describe("ExcelWrapper", () => {
24
24
  const ws = await wb.getWorksheet("Users");
25
25
 
26
26
  // Check headers
27
- expect(await ws.cell(0, 0).getVal()).toBe("Name");
28
- expect(await ws.cell(0, 1).getVal()).toBe("Age");
29
- expect(await ws.cell(0, 2).getVal()).toBe("Email");
30
- expect(await ws.cell(0, 3).getVal()).toBe("Active");
27
+ expect(await ws.cell(0, 0).getValue()).toBe("Name");
28
+ expect(await ws.cell(0, 1).getValue()).toBe("Age");
29
+ expect(await ws.cell(0, 2).getValue()).toBe("Email");
30
+ expect(await ws.cell(0, 3).getValue()).toBe("Active");
31
31
 
32
32
  // Check data
33
- expect(await ws.cell(1, 0).getVal()).toBe("John Doe");
34
- expect(await ws.cell(1, 1).getVal()).toBe(30);
35
- expect(await ws.cell(2, 0).getVal()).toBe("Jane Smith");
36
- expect(await ws.cell(2, 1).getVal()).toBe(25);
33
+ expect(await ws.cell(1, 0).getValue()).toBe("John Doe");
34
+ expect(await ws.cell(1, 1).getValue()).toBe(30);
35
+ expect(await ws.cell(2, 0).getValue()).toBe("Jane Smith");
36
+ expect(await ws.cell(2, 1).getValue()).toBe(25);
37
37
 
38
38
  await wb.close();
39
39
  });
@@ -65,7 +65,7 @@ describe("ExcelWrapper", () => {
65
65
  ];
66
66
 
67
67
  const wb = await wrapper.write("Users", records);
68
- const buffer = await wb.getBytes();
68
+ const buffer = await wb.toBytes();
69
69
  await wb.close();
70
70
 
71
71
  // Read from Excel
@@ -85,7 +85,7 @@ describe("ExcelWrapper", () => {
85
85
 
86
86
  const records = [{ name: "Test", age: 20 }];
87
87
  const wb = await wrapper.write("Sheet1", records);
88
- const buffer = await wb.getBytes();
88
+ const buffer = await wb.toBytes();
89
89
  await wb.close();
90
90
 
91
91
  const readRecords = await wrapper.read(buffer, 0);
@@ -100,7 +100,7 @@ describe("ExcelWrapper", () => {
100
100
 
101
101
  // Save without active field
102
102
  const wb = await wrapper.write("Test", [{ name: "Test", age: 20 }]);
103
- const buffer = await wb.getBytes();
103
+ const buffer = await wb.toBytes();
104
104
  await wb.close();
105
105
 
106
106
  const records = await wrapper.read(buffer);
@@ -120,7 +120,7 @@ describe("ExcelWrapper", () => {
120
120
  const records = [{ title: "Event 1", date: new DateOnly(2024, 6, 15) }, { title: "Event 2" }];
121
121
 
122
122
  const wb = await wrapper.write("Events", records);
123
- const buffer = await wb.getBytes();
123
+ const buffer = await wb.toBytes();
124
124
  await wb.close();
125
125
 
126
126
  const readRecords = await wrapper.read(buffer, "Events");
@@ -144,7 +144,7 @@ describe("ExcelWrapper", () => {
144
144
  const records = [{ title: "Meeting", datetime: new DateTime(2024, 6, 15, 14, 30, 0) }];
145
145
 
146
146
  const wb = await wrapper.write("Events", records);
147
- const buffer = await wb.getBytes();
147
+ const buffer = await wb.toBytes();
148
148
  await wb.close();
149
149
 
150
150
  const readRecords = await wrapper.read(buffer, "Events");
@@ -168,7 +168,7 @@ describe("ExcelWrapper", () => {
168
168
  const records = [{ title: "Alarm", time: new Time(9, 30, 0) }];
169
169
 
170
170
  const wb = await wrapper.write("Events", records);
171
- const buffer = await wb.getBytes();
171
+ const buffer = await wb.toBytes();
172
172
  await wb.close();
173
173
 
174
174
  const readRecords = await wrapper.read(buffer, "Events");
@@ -185,7 +185,7 @@ describe("ExcelWrapper", () => {
185
185
 
186
186
  // Create empty Excel with only headers
187
187
  const wb = await wrapper.write("Empty", []);
188
- const buffer = await wb.getBytes();
188
+ const buffer = await wb.toBytes();
189
189
  await wb.close();
190
190
 
191
191
  await expect(wrapper.read(buffer, "Empty")).rejects.toThrow(
@@ -197,7 +197,7 @@ describe("ExcelWrapper", () => {
197
197
  const wrapper = new ExcelWrapper(testSchema);
198
198
 
199
199
  const wb = await wrapper.write("Test", [{ name: "Test", age: 20 }]);
200
- const buffer = await wb.getBytes();
200
+ const buffer = await wb.toBytes();
201
201
  await wb.close();
202
202
 
203
203
  await expect(wrapper.read(buffer, "NotExist")).rejects.toThrow();
@@ -215,9 +215,9 @@ describe("ExcelWrapper", () => {
215
215
 
216
216
  // Modify data directly to trigger validation failure
217
217
  const ws = await wb.getWorksheet("Validation");
218
- await ws.cell(1, 0).setVal("AB"); // Change to less than 5 characters
218
+ await ws.cell(1, 0).setValue("AB"); // Change to less than 5 characters
219
219
 
220
- const buffer = await wb.getBytes();
220
+ const buffer = await wb.toBytes();
221
221
  await wb.close();
222
222
 
223
223
  // Should throw validation error
@@ -241,13 +241,13 @@ describe("ExcelWrapper", () => {
241
241
  const ws = await wb.getWorksheet("Test");
242
242
 
243
243
  // Headers: only name and age exist
244
- expect(await ws.cell(0, 0).getVal()).toBe("Name");
245
- expect(await ws.cell(0, 1).getVal()).toBe("Age");
246
- expect(await ws.cell(0, 2).getVal()).toBeUndefined();
244
+ expect(await ws.cell(0, 0).getValue()).toBe("Name");
245
+ expect(await ws.cell(0, 1).getValue()).toBe("Age");
246
+ expect(await ws.cell(0, 2).getValue()).toBeUndefined();
247
247
 
248
248
  // Check data
249
- expect(await ws.cell(1, 0).getVal()).toBe("John Doe");
250
- expect(await ws.cell(1, 1).getVal()).toBe(30);
249
+ expect(await ws.cell(1, 0).getValue()).toBe("John Doe");
250
+ expect(await ws.cell(1, 1).getValue()).toBe(30);
251
251
 
252
252
  await wb.close();
253
253
  });
@@ -258,7 +258,7 @@ describe("ExcelWrapper", () => {
258
258
  // Create Excel with all fields
259
259
  const records = [{ name: "John Doe", age: 30, email: "john@test.com", phone: "010-1234-5678" }];
260
260
  const wb = await wrapper.write("Test", records);
261
- const buffer = await wb.getBytes();
261
+ const buffer = await wb.toBytes();
262
262
  await wb.close();
263
263
 
264
264
  // Read with excludes