@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
@@ -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);
@@ -95,25 +95,12 @@ describe("ExcelWrapper", () => {
95
95
  });
96
96
 
97
97
  describe("Type conversion", () => {
98
- it("can convert strings to numbers", async () => {
99
- const wrapper = new ExcelWrapper(testSchema);
100
-
101
- // Simulate Excel with values stored as strings manually
102
- const wb = await wrapper.write("Test", [{ name: "Test", age: 25 }]);
103
- const buffer = await wb.getBytes();
104
- await wb.close();
105
-
106
- const records = await wrapper.read(buffer);
107
- expect(typeof records[0].age).toBe("number");
108
- expect(records[0].age).toBe(25);
109
- });
110
-
111
98
  it("applies default values", async () => {
112
99
  const wrapper = new ExcelWrapper(testSchema);
113
100
 
114
101
  // Save without active field
115
102
  const wb = await wrapper.write("Test", [{ name: "Test", age: 20 }]);
116
- const buffer = await wb.getBytes();
103
+ const buffer = await wb.toBytes();
117
104
  await wb.close();
118
105
 
119
106
  const records = await wrapper.read(buffer);
@@ -133,7 +120,7 @@ describe("ExcelWrapper", () => {
133
120
  const records = [{ title: "Event 1", date: new DateOnly(2024, 6, 15) }, { title: "Event 2" }];
134
121
 
135
122
  const wb = await wrapper.write("Events", records);
136
- const buffer = await wb.getBytes();
123
+ const buffer = await wb.toBytes();
137
124
  await wb.close();
138
125
 
139
126
  const readRecords = await wrapper.read(buffer, "Events");
@@ -157,7 +144,7 @@ describe("ExcelWrapper", () => {
157
144
  const records = [{ title: "Meeting", datetime: new DateTime(2024, 6, 15, 14, 30, 0) }];
158
145
 
159
146
  const wb = await wrapper.write("Events", records);
160
- const buffer = await wb.getBytes();
147
+ const buffer = await wb.toBytes();
161
148
  await wb.close();
162
149
 
163
150
  const readRecords = await wrapper.read(buffer, "Events");
@@ -181,7 +168,7 @@ describe("ExcelWrapper", () => {
181
168
  const records = [{ title: "Alarm", time: new Time(9, 30, 0) }];
182
169
 
183
170
  const wb = await wrapper.write("Events", records);
184
- const buffer = await wb.getBytes();
171
+ const buffer = await wb.toBytes();
185
172
  await wb.close();
186
173
 
187
174
  const readRecords = await wrapper.read(buffer, "Events");
@@ -198,7 +185,7 @@ describe("ExcelWrapper", () => {
198
185
 
199
186
  // Create empty Excel with only headers
200
187
  const wb = await wrapper.write("Empty", []);
201
- const buffer = await wb.getBytes();
188
+ const buffer = await wb.toBytes();
202
189
  await wb.close();
203
190
 
204
191
  await expect(wrapper.read(buffer, "Empty")).rejects.toThrow(
@@ -210,22 +197,12 @@ describe("ExcelWrapper", () => {
210
197
  const wrapper = new ExcelWrapper(testSchema);
211
198
 
212
199
  const wb = await wrapper.write("Test", [{ name: "Test", age: 20 }]);
213
- const buffer = await wb.getBytes();
200
+ const buffer = await wb.toBytes();
214
201
  await wb.close();
215
202
 
216
203
  await expect(wrapper.read(buffer, "NotExist")).rejects.toThrow();
217
204
  });
218
205
 
219
- it("throws error when reading with non-existent worksheet index", async () => {
220
- const wrapper = new ExcelWrapper(testSchema);
221
-
222
- const wb = await wrapper.write("Test", [{ name: "Test", age: 20 }]);
223
- const buffer = await wb.getBytes();
224
- await wb.close();
225
-
226
- await expect(wrapper.read(buffer, 99)).rejects.toThrow();
227
- });
228
-
229
206
  it("throws error with worksheet name and detailed error when schema validation fails", async () => {
230
207
  const strictSchema = z.object({
231
208
  name: z.string().min(5).describe("이름"), // At least 5 characters
@@ -238,9 +215,9 @@ describe("ExcelWrapper", () => {
238
215
 
239
216
  // Modify data directly to trigger validation failure
240
217
  const ws = await wb.getWorksheet("Validation");
241
- 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
242
219
 
243
- const buffer = await wb.getBytes();
220
+ const buffer = await wb.toBytes();
244
221
  await wb.close();
245
222
 
246
223
  // Should throw validation error
@@ -264,13 +241,13 @@ describe("ExcelWrapper", () => {
264
241
  const ws = await wb.getWorksheet("Test");
265
242
 
266
243
  // Headers: only name and age exist
267
- expect(await ws.cell(0, 0).getVal()).toBe("Name");
268
- expect(await ws.cell(0, 1).getVal()).toBe("Age");
269
- 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();
270
247
 
271
248
  // Check data
272
- expect(await ws.cell(1, 0).getVal()).toBe("John Doe");
273
- 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);
274
251
 
275
252
  await wb.close();
276
253
  });
@@ -281,7 +258,7 @@ describe("ExcelWrapper", () => {
281
258
  // Create Excel with all fields
282
259
  const records = [{ name: "John Doe", age: 30, email: "john@test.com", phone: "010-1234-5678" }];
283
260
  const wb = await wrapper.write("Test", records);
284
- const buffer = await wb.getBytes();
261
+ const buffer = await wb.toBytes();
285
262
  await wb.close();
286
263
 
287
264
  // Read with excludes
@@ -33,7 +33,7 @@ async function loadPngFile(): Promise<Uint8Array> {
33
33
  describe("ExcelWorksheet.addImage integration", () => {
34
34
  it("should write media, drawing, drawing rels, worksheet rel and content types", async () => {
35
35
  const wb = new ExcelWorkbook();
36
- const ws = await wb.createWorksheet("Sheet1");
36
+ const ws = await wb.addWorksheet("Sheet1");
37
37
 
38
38
  const bytes = await loadPngFile();
39
39
 
@@ -102,14 +102,14 @@ describe("ExcelWorksheet.addImage integration", () => {
102
102
  expect(drawingElems.some((d: any) => d.$ != null && d.$["r:id"] != null)).toBeTruthy();
103
103
 
104
104
  // Verify buffer creation
105
- const resultBuffer = await wb.getBytes();
105
+ const resultBuffer = await wb.toBytes();
106
106
  expect(resultBuffer).toBeDefined();
107
107
  expect(resultBuffer.length).toBeGreaterThan(0);
108
108
  });
109
109
 
110
110
  it("can insert multiple images into the same worksheet", async () => {
111
111
  const wb = new ExcelWorkbook();
112
- const ws = await wb.createWorksheet("Sheet1");
112
+ const ws = await wb.addWorksheet("Sheet1");
113
113
 
114
114
  const bytes = await loadPngFile();
115
115
 
@@ -170,14 +170,14 @@ describe("ExcelWorksheet.addImage integration", () => {
170
170
  expect(relsArr.some((r: any) => r.$.Target === "../media/image2.png")).toBeTruthy();
171
171
 
172
172
  // Verify buffer creation
173
- const resultBuffer = await wb.getBytes();
173
+ const resultBuffer = await wb.toBytes();
174
174
  expect(resultBuffer).toBeDefined();
175
175
  expect(resultBuffer.length).toBeGreaterThan(0);
176
176
  });
177
177
 
178
178
  it("throws error for unsupported file extensions", async () => {
179
179
  const wb = new ExcelWorkbook();
180
- const ws = await wb.createWorksheet("Sheet1");
180
+ const ws = await wb.addWorksheet("Sheet1");
181
181
 
182
182
  await expect(
183
183
  ws.addImage({
@@ -2,13 +2,7 @@ import { describe, expect, it } from "vitest";
2
2
  import { ExcelUtils } from "../../src/utils/excel-utils";
3
3
 
4
4
  describe("ExcelUtils", () => {
5
- describe("stringifyColAddr / parseColAddrCode", () => {
6
- it("converts 0-25 to A-Z", () => {
7
- expect(ExcelUtils.stringifyColAddr(0)).toBe("A");
8
- expect(ExcelUtils.stringifyColAddr(1)).toBe("B");
9
- expect(ExcelUtils.stringifyColAddr(25)).toBe("Z");
10
- });
11
-
5
+ describe("stringifyColAddr / parseColAddr", () => {
12
6
  it("converts 26 and above to AA, AB, etc.", () => {
13
7
  expect(ExcelUtils.stringifyColAddr(26)).toBe("AA");
14
8
  expect(ExcelUtils.stringifyColAddr(27)).toBe("AB");
@@ -24,32 +18,13 @@ describe("ExcelUtils", () => {
24
18
  it("handles Excel maximum column index (XFD, 16383)", () => {
25
19
  // Excel maximum column is XFD (index 16383, 0-based)
26
20
  expect(ExcelUtils.stringifyColAddr(16383)).toBe("XFD");
27
- expect(ExcelUtils.parseColAddrCode("XFD")).toBe(16383);
28
- });
29
-
30
- it("parses A-Z to 0-25", () => {
31
- expect(ExcelUtils.parseColAddrCode("A")).toBe(0);
32
- expect(ExcelUtils.parseColAddrCode("B")).toBe(1);
33
- expect(ExcelUtils.parseColAddrCode("Z")).toBe(25);
34
- });
35
-
36
- it("parses AA, AB, etc. to 26 and above", () => {
37
- expect(ExcelUtils.parseColAddrCode("AA")).toBe(26);
38
- expect(ExcelUtils.parseColAddrCode("AB")).toBe(27);
39
- expect(ExcelUtils.parseColAddrCode("AZ")).toBe(51);
40
- expect(ExcelUtils.parseColAddrCode("BA")).toBe(52);
41
- });
42
-
43
- it("parses column index from cell address", () => {
44
- expect(ExcelUtils.parseColAddrCode("A1")).toBe(0);
45
- expect(ExcelUtils.parseColAddrCode("B10")).toBe(1);
46
- expect(ExcelUtils.parseColAddrCode("AA100")).toBe(26);
21
+ expect(ExcelUtils.parseColAddr("XFD")).toBe(16383);
47
22
  });
48
23
 
49
24
  it("round-trip: stringify → parse returns original value", () => {
50
25
  for (let i = 0; i < 100; i++) {
51
26
  const stringified = ExcelUtils.stringifyColAddr(i);
52
- const parsed = ExcelUtils.parseColAddrCode(stringified);
27
+ const parsed = ExcelUtils.parseColAddr(stringified);
53
28
  expect(parsed).toBe(i);
54
29
  }
55
30
  });
@@ -60,7 +35,7 @@ describe("ExcelUtils", () => {
60
35
  });
61
36
  });
62
37
 
63
- describe("stringifyRowAddr / parseRowAddrCode", () => {
38
+ describe("stringifyRowAddr / parseRowAddr", () => {
64
39
  it("converts 0-based index to 1-based string", () => {
65
40
  expect(ExcelUtils.stringifyRowAddr(0)).toBe("1");
66
41
  expect(ExcelUtils.stringifyRowAddr(9)).toBe("10");
@@ -68,13 +43,13 @@ describe("ExcelUtils", () => {
68
43
  });
69
44
 
70
45
  it("parses 1-based string to 0-based index", () => {
71
- expect(ExcelUtils.parseRowAddrCode("A1")).toBe(0);
72
- expect(ExcelUtils.parseRowAddrCode("B10")).toBe(9);
73
- expect(ExcelUtils.parseRowAddrCode("AA100")).toBe(99);
46
+ expect(ExcelUtils.parseRowAddr("A1")).toBe(0);
47
+ expect(ExcelUtils.parseRowAddr("B10")).toBe(9);
48
+ expect(ExcelUtils.parseRowAddr("AA100")).toBe(99);
74
49
  });
75
50
  });
76
51
 
77
- describe("stringifyAddr / parseCellAddrCode", () => {
52
+ describe("stringifyAddr / parseCellAddr", () => {
78
53
  it("correctly converts cell address", () => {
79
54
  expect(ExcelUtils.stringifyAddr({ r: 0, c: 0 })).toBe("A1");
80
55
  expect(ExcelUtils.stringifyAddr({ r: 9, c: 1 })).toBe("B10");
@@ -82,21 +57,21 @@ describe("ExcelUtils", () => {
82
57
  });
83
58
 
84
59
  it("correctly parses cell address", () => {
85
- expect(ExcelUtils.parseCellAddrCode("A1")).toEqual({ r: 0, c: 0 });
86
- expect(ExcelUtils.parseCellAddrCode("B10")).toEqual({ r: 9, c: 1 });
87
- expect(ExcelUtils.parseCellAddrCode("AA100")).toEqual({ r: 99, c: 26 });
60
+ expect(ExcelUtils.parseCellAddr("A1")).toEqual({ r: 0, c: 0 });
61
+ expect(ExcelUtils.parseCellAddr("B10")).toEqual({ r: 9, c: 1 });
62
+ expect(ExcelUtils.parseCellAddr("AA100")).toEqual({ r: 99, c: 26 });
88
63
  });
89
64
  });
90
65
 
91
- describe("parseRangeAddrCode / stringifyRangeAddr", () => {
66
+ describe("parseRangeAddr / stringifyRangeAddr", () => {
92
67
  it("parses single cell range", () => {
93
- const range = ExcelUtils.parseRangeAddrCode("A1");
68
+ const range = ExcelUtils.parseRangeAddr("A1");
94
69
  expect(range.s).toEqual({ r: 0, c: 0 });
95
70
  expect(range.e).toEqual({ r: 0, c: 0 });
96
71
  });
97
72
 
98
73
  it("parses multi-cell range", () => {
99
- const range = ExcelUtils.parseRangeAddrCode("A1:C3");
74
+ const range = ExcelUtils.parseRangeAddr("A1:C3");
100
75
  expect(range.s).toEqual({ r: 0, c: 0 });
101
76
  expect(range.e).toEqual({ r: 2, c: 2 });
102
77
  });
@@ -127,25 +102,6 @@ describe("ExcelUtils", () => {
127
102
  expect(excelNum).toBeCloseTo(25569, 0);
128
103
  });
129
104
 
130
- it("correctly converts 2024-06-15", () => {
131
- const date = new Date(Date.UTC(2024, 5, 15, 0, 0, 0));
132
- const tick = date.getTime();
133
- const excelNum = ExcelUtils.convertTimeTickToNumber(tick);
134
- // Verify approximate value
135
- expect(excelNum).toBeGreaterThan(45000);
136
- });
137
-
138
- it("correctly converts date with time", () => {
139
- const date = new Date(Date.UTC(2024, 5, 15, 12, 0, 0));
140
- const tick = date.getTime();
141
- const excelNum = ExcelUtils.convertTimeTickToNumber(tick);
142
- // 12:00 = 0.5 days additional
143
- const baseNum = ExcelUtils.convertTimeTickToNumber(
144
- new Date(Date.UTC(2024, 5, 15, 0, 0, 0)).getTime(),
145
- );
146
- expect(excelNum - baseNum).toBeCloseTo(0.5, 1);
147
- });
148
-
149
105
  it("round-trip: tick → number → tick returns original value", () => {
150
106
  const originalDate = new Date(Date.UTC(2024, 5, 15, 14, 30, 45));
151
107
  const tick = originalDate.getTime();