@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.
- package/README.md +539 -17
- package/dist/excel-cell.d.ts +4 -4
- package/dist/excel-cell.d.ts.map +1 -1
- package/dist/excel-cell.js +9 -10
- package/dist/excel-cell.js.map +1 -1
- package/dist/excel-workbook.d.ts +3 -3
- package/dist/excel-workbook.d.ts.map +1 -1
- package/dist/excel-workbook.js +3 -3
- package/dist/excel-workbook.js.map +1 -1
- package/dist/excel-worksheet.d.ts +1 -1
- package/dist/excel-worksheet.d.ts.map +1 -1
- package/dist/excel-worksheet.js +13 -17
- package/dist/excel-worksheet.js.map +1 -1
- package/dist/excel-wrapper.d.ts +1 -1
- package/dist/excel-wrapper.js +7 -7
- package/dist/excel-wrapper.js.map +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/excel-utils.d.ts +5 -5
- package/dist/utils/excel-utils.d.ts.map +1 -1
- package/dist/utils/excel-utils.js +15 -15
- package/dist/utils/excel-utils.js.map +1 -1
- package/dist/utils/zip-cache.js +3 -3
- package/dist/utils/zip-cache.js.map +1 -1
- package/dist/xml/excel-xml-relationship.js +2 -2
- package/dist/xml/excel-xml-relationship.js.map +1 -1
- package/dist/xml/excel-xml-style.js +16 -16
- package/dist/xml/excel-xml-style.js.map +1 -1
- package/dist/xml/excel-xml-workbook.js +6 -6
- package/dist/xml/excel-xml-workbook.js.map +1 -1
- package/dist/xml/excel-xml-worksheet.d.ts +5 -2
- package/dist/xml/excel-xml-worksheet.d.ts.map +1 -1
- package/dist/xml/excel-xml-worksheet.js +38 -20
- package/dist/xml/excel-xml-worksheet.js.map +1 -1
- package/package.json +2 -2
- package/src/excel-cell.ts +10 -11
- package/src/excel-workbook.ts +3 -3
- package/src/excel-worksheet.ts +17 -18
- package/src/excel-wrapper.ts +7 -7
- package/src/types.ts +1 -1
- package/src/utils/excel-utils.ts +15 -15
- package/src/utils/zip-cache.ts +3 -3
- package/src/xml/excel-xml-relationship.ts +2 -2
- package/src/xml/excel-xml-style.ts +16 -16
- package/src/xml/excel-xml-workbook.ts +6 -6
- package/src/xml/excel-xml-worksheet.ts +47 -22
- package/tests/excel-cell.spec.ts +85 -140
- package/tests/excel-col.spec.ts +17 -48
- package/tests/excel-row.spec.ts +13 -23
- package/tests/excel-workbook.spec.ts +26 -40
- package/tests/excel-worksheet.spec.ts +217 -137
- package/tests/excel-wrapper.spec.ts +24 -47
- package/tests/image-insert.spec.ts +5 -5
- package/tests/utils/excel-utils.spec.ts +14 -58
package/tests/excel-cell.spec.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { ExcelWorkbook } from "../src/excel-workbook";
|
|
3
3
|
import { ExcelXmlWorksheet } from "../src/xml/excel-xml-worksheet";
|
|
4
4
|
import { DateOnly, DateTime, Time } from "@simplysm/core-common";
|
|
5
|
+
import type { ExcelCellData, ExcelCellType } from "../src";
|
|
5
6
|
|
|
6
7
|
describe("ExcelXmlWorksheet.getCellVal - inline string", () => {
|
|
7
8
|
it("should read plain string inline text (no attributes)", () => {
|
|
@@ -47,94 +48,70 @@ describe("ExcelCell", () => {
|
|
|
47
48
|
describe("Cell Value Read/Write - Basic Types", () => {
|
|
48
49
|
it("Can read and write string values", async () => {
|
|
49
50
|
const wb = new ExcelWorkbook();
|
|
50
|
-
const ws = await wb.
|
|
51
|
+
const ws = await wb.addWorksheet("Test");
|
|
51
52
|
|
|
52
|
-
await ws.cell(0, 0).
|
|
53
|
-
const val = await ws.cell(0, 0).
|
|
53
|
+
await ws.cell(0, 0).setValue("Hello World");
|
|
54
|
+
const val = await ws.cell(0, 0).getValue();
|
|
54
55
|
|
|
55
56
|
expect(val).toBe("Hello World");
|
|
56
57
|
});
|
|
57
58
|
|
|
58
59
|
it("Can read and write number values", async () => {
|
|
59
60
|
const wb = new ExcelWorkbook();
|
|
60
|
-
const ws = await wb.
|
|
61
|
+
const ws = await wb.addWorksheet("Test");
|
|
61
62
|
|
|
62
|
-
await ws.cell(0, 0).
|
|
63
|
-
await ws.cell(0, 1).
|
|
64
|
-
await ws.cell(0, 2).
|
|
65
|
-
await ws.cell(0, 3).
|
|
63
|
+
await ws.cell(0, 0).setValue(12345);
|
|
64
|
+
await ws.cell(0, 1).setValue(3.14159);
|
|
65
|
+
await ws.cell(0, 2).setValue(-100);
|
|
66
|
+
await ws.cell(0, 3).setValue(0);
|
|
66
67
|
|
|
67
|
-
expect(await ws.cell(0, 0).
|
|
68
|
-
expect(await ws.cell(0, 1).
|
|
69
|
-
expect(await ws.cell(0, 2).
|
|
70
|
-
expect(await ws.cell(0, 3).
|
|
68
|
+
expect(await ws.cell(0, 0).getValue()).toBe(12345);
|
|
69
|
+
expect(await ws.cell(0, 1).getValue()).toBe(3.14159);
|
|
70
|
+
expect(await ws.cell(0, 2).getValue()).toBe(-100);
|
|
71
|
+
expect(await ws.cell(0, 3).getValue()).toBe(0);
|
|
71
72
|
});
|
|
72
73
|
|
|
73
74
|
it("Can read and write boolean values", async () => {
|
|
74
75
|
const wb = new ExcelWorkbook();
|
|
75
|
-
const ws = await wb.
|
|
76
|
+
const ws = await wb.addWorksheet("Test");
|
|
76
77
|
|
|
77
|
-
await ws.cell(0, 0).
|
|
78
|
-
await ws.cell(0, 1).
|
|
78
|
+
await ws.cell(0, 0).setValue(true);
|
|
79
|
+
await ws.cell(0, 1).setValue(false);
|
|
79
80
|
|
|
80
|
-
expect(await ws.cell(0, 0).
|
|
81
|
-
expect(await ws.cell(0, 1).
|
|
81
|
+
expect(await ws.cell(0, 0).getValue()).toBe(true);
|
|
82
|
+
expect(await ws.cell(0, 1).getValue()).toBe(false);
|
|
82
83
|
});
|
|
83
84
|
|
|
84
85
|
it("Setting undefined value deletes the cell", async () => {
|
|
85
86
|
const wb = new ExcelWorkbook();
|
|
86
|
-
const ws = await wb.
|
|
87
|
+
const ws = await wb.addWorksheet("Test");
|
|
87
88
|
|
|
88
|
-
await ws.cell(0, 0).
|
|
89
|
-
expect(await ws.cell(0, 0).
|
|
89
|
+
await ws.cell(0, 0).setValue("Initial");
|
|
90
|
+
expect(await ws.cell(0, 0).getValue()).toBe("Initial");
|
|
90
91
|
|
|
91
|
-
await ws.cell(0, 0).
|
|
92
|
-
expect(await ws.cell(0, 0).
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("Can handle very large numbers", async () => {
|
|
96
|
-
const wb = new ExcelWorkbook();
|
|
97
|
-
const ws = await wb.createWorksheet("Test");
|
|
98
|
-
|
|
99
|
-
// Large number below MAX_SAFE_INTEGER
|
|
100
|
-
const bigNumber = Number.MAX_SAFE_INTEGER;
|
|
101
|
-
await ws.cell(0, 0).setVal(bigNumber);
|
|
102
|
-
|
|
103
|
-
const val = await ws.cell(0, 0).getVal();
|
|
104
|
-
expect(val).toBe(bigNumber);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("Can handle very small decimals", async () => {
|
|
108
|
-
const wb = new ExcelWorkbook();
|
|
109
|
-
const ws = await wb.createWorksheet("Test");
|
|
110
|
-
|
|
111
|
-
// Small decimal within Excel's precision range
|
|
112
|
-
const smallDecimal = 0.0001;
|
|
113
|
-
await ws.cell(0, 0).setVal(smallDecimal);
|
|
114
|
-
|
|
115
|
-
const val = await ws.cell(0, 0).getVal();
|
|
116
|
-
expect(val).toBeCloseTo(smallDecimal, 6);
|
|
92
|
+
await ws.cell(0, 0).setValue(undefined);
|
|
93
|
+
expect(await ws.cell(0, 0).getValue()).toBeUndefined();
|
|
117
94
|
});
|
|
118
95
|
|
|
119
96
|
it("Throws error when setting unsupported type", async () => {
|
|
120
97
|
const wb = new ExcelWorkbook();
|
|
121
|
-
const ws = await wb.
|
|
98
|
+
const ws = await wb.addWorksheet("Test");
|
|
122
99
|
|
|
123
|
-
await expect(ws.cell(0, 0).
|
|
100
|
+
await expect(ws.cell(0, 0).setValue({} as any)).rejects.toThrow("Unsupported type");
|
|
124
101
|
|
|
125
|
-
await expect(ws.cell(0, 1).
|
|
102
|
+
await expect(ws.cell(0, 1).setValue([] as any)).rejects.toThrow("Unsupported type");
|
|
126
103
|
});
|
|
127
104
|
});
|
|
128
105
|
|
|
129
106
|
describe("Cell Value Read/Write - Date/Time Types", () => {
|
|
130
107
|
it("Can read and write DateOnly values", async () => {
|
|
131
108
|
const wb = new ExcelWorkbook();
|
|
132
|
-
const ws = await wb.
|
|
109
|
+
const ws = await wb.addWorksheet("Test");
|
|
133
110
|
|
|
134
111
|
const date = new DateOnly(2024, 6, 15);
|
|
135
|
-
await ws.cell(0, 0).
|
|
112
|
+
await ws.cell(0, 0).setValue(date);
|
|
136
113
|
|
|
137
|
-
const val = await ws.cell(0, 0).
|
|
114
|
+
const val = await ws.cell(0, 0).getValue();
|
|
138
115
|
expect(val).toBeInstanceOf(DateOnly);
|
|
139
116
|
expect((val as DateOnly).year).toBe(2024);
|
|
140
117
|
expect((val as DateOnly).month).toBe(6);
|
|
@@ -143,12 +120,12 @@ describe("ExcelCell", () => {
|
|
|
143
120
|
|
|
144
121
|
it("Can read and write DateTime values", async () => {
|
|
145
122
|
const wb = new ExcelWorkbook();
|
|
146
|
-
const ws = await wb.
|
|
123
|
+
const ws = await wb.addWorksheet("Test");
|
|
147
124
|
|
|
148
125
|
const dateTime = new DateTime(2024, 6, 15, 14, 30, 45);
|
|
149
|
-
await ws.cell(0, 0).
|
|
126
|
+
await ws.cell(0, 0).setValue(dateTime);
|
|
150
127
|
|
|
151
|
-
const val = await ws.cell(0, 0).
|
|
128
|
+
const val = await ws.cell(0, 0).getValue();
|
|
152
129
|
expect(val).toBeInstanceOf(DateTime);
|
|
153
130
|
expect((val as DateTime).year).toBe(2024);
|
|
154
131
|
expect((val as DateTime).month).toBe(6);
|
|
@@ -160,12 +137,12 @@ describe("ExcelCell", () => {
|
|
|
160
137
|
|
|
161
138
|
it("Can read and write Time values", async () => {
|
|
162
139
|
const wb = new ExcelWorkbook();
|
|
163
|
-
const ws = await wb.
|
|
140
|
+
const ws = await wb.addWorksheet("Test");
|
|
164
141
|
|
|
165
142
|
const time = new Time(14, 30, 45);
|
|
166
|
-
await ws.cell(0, 0).
|
|
143
|
+
await ws.cell(0, 0).setValue(time);
|
|
167
144
|
|
|
168
|
-
const val = await ws.cell(0, 0).
|
|
145
|
+
const val = await ws.cell(0, 0).getValue();
|
|
169
146
|
expect(val).toBeInstanceOf(Time);
|
|
170
147
|
expect((val as Time).hour).toBe(14);
|
|
171
148
|
expect((val as Time).minute).toBe(30);
|
|
@@ -174,18 +151,18 @@ describe("ExcelCell", () => {
|
|
|
174
151
|
|
|
175
152
|
it("DateOnly values persist after round-trip", async () => {
|
|
176
153
|
const wb = new ExcelWorkbook();
|
|
177
|
-
const ws = await wb.
|
|
154
|
+
const ws = await wb.addWorksheet("Test");
|
|
178
155
|
|
|
179
156
|
const date = new DateOnly(2024, 6, 15);
|
|
180
|
-
await ws.cell(0, 0).
|
|
157
|
+
await ws.cell(0, 0).setValue(date);
|
|
181
158
|
|
|
182
|
-
const bytes = await wb.
|
|
159
|
+
const bytes = await wb.toBytes();
|
|
183
160
|
await wb.close();
|
|
184
161
|
|
|
185
162
|
const wb2 = new ExcelWorkbook(bytes);
|
|
186
163
|
const ws2 = await wb2.getWorksheet(0);
|
|
187
164
|
|
|
188
|
-
const val = await ws2.cell(0, 0).
|
|
165
|
+
const val = await ws2.cell(0, 0).getValue();
|
|
189
166
|
expect(val).toBeInstanceOf(DateOnly);
|
|
190
167
|
expect((val as DateOnly).year).toBe(2024);
|
|
191
168
|
expect((val as DateOnly).month).toBe(6);
|
|
@@ -195,18 +172,18 @@ describe("ExcelCell", () => {
|
|
|
195
172
|
|
|
196
173
|
it("DateTime values persist after round-trip", async () => {
|
|
197
174
|
const wb = new ExcelWorkbook();
|
|
198
|
-
const ws = await wb.
|
|
175
|
+
const ws = await wb.addWorksheet("Test");
|
|
199
176
|
|
|
200
177
|
const dateTime = new DateTime(2024, 6, 15, 14, 30, 45);
|
|
201
|
-
await ws.cell(0, 0).
|
|
178
|
+
await ws.cell(0, 0).setValue(dateTime);
|
|
202
179
|
|
|
203
|
-
const bytes = await wb.
|
|
180
|
+
const bytes = await wb.toBytes();
|
|
204
181
|
await wb.close();
|
|
205
182
|
|
|
206
183
|
const wb2 = new ExcelWorkbook(bytes);
|
|
207
184
|
const ws2 = await wb2.getWorksheet(0);
|
|
208
185
|
|
|
209
|
-
const val = await ws2.cell(0, 0).
|
|
186
|
+
const val = await ws2.cell(0, 0).getValue();
|
|
210
187
|
expect(val).toBeInstanceOf(DateTime);
|
|
211
188
|
expect((val as DateTime).year).toBe(2024);
|
|
212
189
|
expect((val as DateTime).month).toBe(6);
|
|
@@ -219,18 +196,18 @@ describe("ExcelCell", () => {
|
|
|
219
196
|
|
|
220
197
|
it("Time values persist after round-trip", async () => {
|
|
221
198
|
const wb = new ExcelWorkbook();
|
|
222
|
-
const ws = await wb.
|
|
199
|
+
const ws = await wb.addWorksheet("Test");
|
|
223
200
|
|
|
224
201
|
const time = new Time(14, 30, 45);
|
|
225
|
-
await ws.cell(0, 0).
|
|
202
|
+
await ws.cell(0, 0).setValue(time);
|
|
226
203
|
|
|
227
|
-
const bytes = await wb.
|
|
204
|
+
const bytes = await wb.toBytes();
|
|
228
205
|
await wb.close();
|
|
229
206
|
|
|
230
207
|
const wb2 = new ExcelWorkbook(bytes);
|
|
231
208
|
const ws2 = await wb2.getWorksheet(0);
|
|
232
209
|
|
|
233
|
-
const val = await ws2.cell(0, 0).
|
|
210
|
+
const val = await ws2.cell(0, 0).getValue();
|
|
234
211
|
expect(val).toBeInstanceOf(Time);
|
|
235
212
|
expect((val as Time).hour).toBe(14);
|
|
236
213
|
expect((val as Time).minute).toBe(30);
|
|
@@ -242,10 +219,10 @@ describe("ExcelCell", () => {
|
|
|
242
219
|
describe("Formulas", () => {
|
|
243
220
|
it("Can set formulas", async () => {
|
|
244
221
|
const wb = new ExcelWorkbook();
|
|
245
|
-
const ws = await wb.
|
|
222
|
+
const ws = await wb.addWorksheet("Test");
|
|
246
223
|
|
|
247
|
-
await ws.cell(0, 0).
|
|
248
|
-
await ws.cell(0, 1).
|
|
224
|
+
await ws.cell(0, 0).setValue(10);
|
|
225
|
+
await ws.cell(0, 1).setValue(20);
|
|
249
226
|
await ws.cell(0, 2).setFormula("A1+B1");
|
|
250
227
|
|
|
251
228
|
// Verify formula directly
|
|
@@ -253,7 +230,7 @@ describe("ExcelCell", () => {
|
|
|
253
230
|
expect(formula).toBe("A1+B1");
|
|
254
231
|
|
|
255
232
|
// Also verify with round-trip
|
|
256
|
-
const buffer = await wb.
|
|
233
|
+
const buffer = await wb.toBytes();
|
|
257
234
|
|
|
258
235
|
const wb2 = new ExcelWorkbook(buffer);
|
|
259
236
|
const ws2 = await wb2.getWorksheet(0);
|
|
@@ -263,13 +240,13 @@ describe("ExcelCell", () => {
|
|
|
263
240
|
|
|
264
241
|
it("Formulas persist after round-trip", async () => {
|
|
265
242
|
const wb = new ExcelWorkbook();
|
|
266
|
-
const ws = await wb.
|
|
243
|
+
const ws = await wb.addWorksheet("Test");
|
|
267
244
|
|
|
268
|
-
await ws.cell(0, 0).
|
|
269
|
-
await ws.cell(0, 1).
|
|
245
|
+
await ws.cell(0, 0).setValue(10);
|
|
246
|
+
await ws.cell(0, 1).setValue(20);
|
|
270
247
|
await ws.cell(0, 2).setFormula("SUM(A1:B1)");
|
|
271
248
|
|
|
272
|
-
const buffer = await wb.
|
|
249
|
+
const buffer = await wb.toBytes();
|
|
273
250
|
await wb.close();
|
|
274
251
|
|
|
275
252
|
const wb2 = new ExcelWorkbook(buffer);
|
|
@@ -283,35 +260,35 @@ describe("ExcelCell", () => {
|
|
|
283
260
|
|
|
284
261
|
it("Setting formula to undefined deletes it", async () => {
|
|
285
262
|
const wb = new ExcelWorkbook();
|
|
286
|
-
const ws = await wb.
|
|
263
|
+
const ws = await wb.addWorksheet("Test");
|
|
287
264
|
|
|
288
265
|
await ws.cell(0, 0).setFormula("A1+B1");
|
|
289
266
|
await ws.cell(0, 0).setFormula(undefined);
|
|
290
267
|
|
|
291
|
-
expect(await ws.cell(0, 0).
|
|
268
|
+
expect(await ws.cell(0, 0).getValue()).toBeUndefined();
|
|
292
269
|
});
|
|
293
270
|
});
|
|
294
271
|
|
|
295
272
|
describe("Cell Merge", () => {
|
|
296
273
|
it("Can merge cells", async () => {
|
|
297
274
|
const wb = new ExcelWorkbook();
|
|
298
|
-
const ws = await wb.
|
|
275
|
+
const ws = await wb.addWorksheet("Test");
|
|
299
276
|
|
|
300
|
-
await ws.cell(0, 0).
|
|
277
|
+
await ws.cell(0, 0).setValue("Merged");
|
|
301
278
|
await ws.cell(0, 0).merge(2, 3); // Merge 2 rows x 3 columns
|
|
302
279
|
|
|
303
280
|
// Verify merge with round-trip
|
|
304
|
-
const buffer = await wb.
|
|
281
|
+
const buffer = await wb.toBytes();
|
|
305
282
|
const wb2 = new ExcelWorkbook(buffer);
|
|
306
283
|
const ws2 = await wb2.getWorksheet(0);
|
|
307
284
|
|
|
308
|
-
const val = await ws2.cell(0, 0).
|
|
285
|
+
const val = await ws2.cell(0, 0).getValue();
|
|
309
286
|
expect(val).toBe("Merged");
|
|
310
287
|
});
|
|
311
288
|
|
|
312
289
|
it("Throws error when attempting to merge overlapping ranges", async () => {
|
|
313
290
|
const wb = new ExcelWorkbook();
|
|
314
|
-
const ws = await wb.
|
|
291
|
+
const ws = await wb.addWorksheet("Test");
|
|
315
292
|
|
|
316
293
|
await ws.cell(0, 0).merge(2, 2); // Merge A1:B2
|
|
317
294
|
|
|
@@ -321,58 +298,11 @@ describe("ExcelCell", () => {
|
|
|
321
298
|
});
|
|
322
299
|
|
|
323
300
|
describe("Cell Style", () => {
|
|
324
|
-
it("Can set background color", async () => {
|
|
325
|
-
const wb = new ExcelWorkbook();
|
|
326
|
-
const ws = await wb.createWorksheet("Test");
|
|
327
|
-
|
|
328
|
-
await ws.cell(0, 0).setVal("Colored");
|
|
329
|
-
await ws.cell(0, 0).setStyle({ background: "00FF0000" }); // Red
|
|
330
|
-
|
|
331
|
-
const styleId = await ws.cell(0, 0).getStyleId();
|
|
332
|
-
expect(styleId).toBeDefined();
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
it("Can set borders", async () => {
|
|
336
|
-
const wb = new ExcelWorkbook();
|
|
337
|
-
const ws = await wb.createWorksheet("Test");
|
|
338
|
-
|
|
339
|
-
await ws.cell(0, 0).setVal("Bordered");
|
|
340
|
-
await ws.cell(0, 0).setStyle({ border: ["left", "right", "top", "bottom"] });
|
|
341
|
-
|
|
342
|
-
const styleId = await ws.cell(0, 0).getStyleId();
|
|
343
|
-
expect(styleId).toBeDefined();
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
it("Can set alignment", async () => {
|
|
347
|
-
const wb = new ExcelWorkbook();
|
|
348
|
-
const ws = await wb.createWorksheet("Test");
|
|
349
|
-
|
|
350
|
-
await ws.cell(0, 0).setVal("Aligned");
|
|
351
|
-
await ws.cell(0, 0).setStyle({
|
|
352
|
-
horizontalAlign: "center",
|
|
353
|
-
verticalAlign: "center",
|
|
354
|
-
});
|
|
355
|
-
|
|
356
|
-
const styleId = await ws.cell(0, 0).getStyleId();
|
|
357
|
-
expect(styleId).toBeDefined();
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
it("Can set number format", async () => {
|
|
361
|
-
const wb = new ExcelWorkbook();
|
|
362
|
-
const ws = await wb.createWorksheet("Test");
|
|
363
|
-
|
|
364
|
-
await ws.cell(0, 0).setVal(12345.6789);
|
|
365
|
-
await ws.cell(0, 0).setStyle({ numberFormat: "number" });
|
|
366
|
-
|
|
367
|
-
const styleId = await ws.cell(0, 0).getStyleId();
|
|
368
|
-
expect(styleId).toBeDefined();
|
|
369
|
-
});
|
|
370
|
-
|
|
371
301
|
it("Can set multiple styles simultaneously", async () => {
|
|
372
302
|
const wb = new ExcelWorkbook();
|
|
373
|
-
const ws = await wb.
|
|
303
|
+
const ws = await wb.addWorksheet("Test");
|
|
374
304
|
|
|
375
|
-
await ws.cell(0, 0).
|
|
305
|
+
await ws.cell(0, 0).setValue("Multi-Style");
|
|
376
306
|
await ws.cell(0, 0).setStyle({
|
|
377
307
|
background: "00FFFF00",
|
|
378
308
|
border: ["left", "right"],
|
|
@@ -386,18 +316,18 @@ describe("ExcelCell", () => {
|
|
|
386
316
|
|
|
387
317
|
it("Throws error for invalid color format", async () => {
|
|
388
318
|
const wb = new ExcelWorkbook();
|
|
389
|
-
const ws = await wb.
|
|
319
|
+
const ws = await wb.addWorksheet("Test");
|
|
390
320
|
|
|
391
|
-
await ws.cell(0, 0).
|
|
321
|
+
await ws.cell(0, 0).setValue("Test");
|
|
392
322
|
await expect(ws.cell(0, 0).setStyle({ background: "invalid" })).rejects.toThrow();
|
|
393
323
|
});
|
|
394
324
|
|
|
395
325
|
it("Styles persist after round-trip", async () => {
|
|
396
326
|
const wb = new ExcelWorkbook();
|
|
397
|
-
const ws = await wb.
|
|
327
|
+
const ws = await wb.addWorksheet("Test");
|
|
398
328
|
|
|
399
329
|
// Set various styles
|
|
400
|
-
await ws.cell(0, 0).
|
|
330
|
+
await ws.cell(0, 0).setValue("Styled");
|
|
401
331
|
await ws.cell(0, 0).setStyle({
|
|
402
332
|
background: "00FF0000", // Red
|
|
403
333
|
border: ["left", "right", "top", "bottom"],
|
|
@@ -405,14 +335,14 @@ describe("ExcelCell", () => {
|
|
|
405
335
|
verticalAlign: "top",
|
|
406
336
|
});
|
|
407
337
|
|
|
408
|
-
const bytes = await wb.
|
|
338
|
+
const bytes = await wb.toBytes();
|
|
409
339
|
|
|
410
340
|
// Verify styles after round-trip
|
|
411
341
|
const wb2 = new ExcelWorkbook(bytes);
|
|
412
342
|
const ws2 = await wb2.getWorksheet("Test");
|
|
413
343
|
|
|
414
344
|
// Verify value
|
|
415
|
-
const val = await ws2.cell(0, 0).
|
|
345
|
+
const val = await ws2.cell(0, 0).getValue();
|
|
416
346
|
expect(val).toBe("Styled");
|
|
417
347
|
|
|
418
348
|
// Verify style ID exists
|
|
@@ -446,3 +376,18 @@ describe("ExcelCell", () => {
|
|
|
446
376
|
});
|
|
447
377
|
});
|
|
448
378
|
});
|
|
379
|
+
|
|
380
|
+
describe("ExcelCellData type narrowing", () => {
|
|
381
|
+
it("should type cell type field as ExcelCellType", () => {
|
|
382
|
+
const cellData: ExcelCellData = {
|
|
383
|
+
$: { r: "A1", t: "s" },
|
|
384
|
+
v: ["test"],
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
const cellType: ExcelCellType | undefined = cellData.$.t;
|
|
388
|
+
expect(cellType).toBe("s");
|
|
389
|
+
|
|
390
|
+
// This should compile: no cast needed
|
|
391
|
+
expect(["s", "b", "str", "n", "inlineStr", "e", undefined].includes(cellData.$.t)).toBe(true);
|
|
392
|
+
});
|
|
393
|
+
});
|
package/tests/excel-col.spec.ts
CHANGED
|
@@ -5,18 +5,18 @@ describe("ExcelCol", () => {
|
|
|
5
5
|
describe("cell()", () => {
|
|
6
6
|
it("Returns cell corresponding to row index", async () => {
|
|
7
7
|
const wb = new ExcelWorkbook();
|
|
8
|
-
const ws = await wb.
|
|
8
|
+
const ws = await wb.addWorksheet("Test");
|
|
9
9
|
|
|
10
10
|
const col = ws.col(0);
|
|
11
11
|
const cell = col.cell(0);
|
|
12
12
|
|
|
13
|
-
await cell.
|
|
14
|
-
expect(await cell.
|
|
13
|
+
await cell.setValue("Hello");
|
|
14
|
+
expect(await cell.getValue()).toBe("Hello");
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it("Returns same instance for same index (caching)", async () => {
|
|
18
18
|
const wb = new ExcelWorkbook();
|
|
19
|
-
const ws = await wb.
|
|
19
|
+
const ws = await wb.addWorksheet("Test");
|
|
20
20
|
|
|
21
21
|
const col = ws.col(0);
|
|
22
22
|
const cell1 = col.cell(0);
|
|
@@ -25,88 +25,57 @@ describe("ExcelCol", () => {
|
|
|
25
25
|
expect(cell1).toBe(cell2);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
it("Returns different instance for different index", async () => {
|
|
29
|
-
const wb = new ExcelWorkbook();
|
|
30
|
-
const ws = await wb.createWorksheet("Test");
|
|
31
|
-
|
|
32
|
-
const col = ws.col(0);
|
|
33
|
-
const cell1 = col.cell(0);
|
|
34
|
-
const cell2 = col.cell(1);
|
|
35
|
-
|
|
36
|
-
expect(cell1).not.toBe(cell2);
|
|
37
|
-
});
|
|
38
28
|
});
|
|
39
29
|
|
|
40
30
|
describe("getCells()", () => {
|
|
41
31
|
it("Returns all cells within range", async () => {
|
|
42
32
|
const wb = new ExcelWorkbook();
|
|
43
|
-
const ws = await wb.
|
|
33
|
+
const ws = await wb.addWorksheet("Test");
|
|
44
34
|
|
|
45
35
|
// Set data to define range
|
|
46
|
-
await ws.cell(0, 0).
|
|
47
|
-
await ws.cell(1, 0).
|
|
48
|
-
await ws.cell(2, 0).
|
|
36
|
+
await ws.cell(0, 0).setValue("A1");
|
|
37
|
+
await ws.cell(1, 0).setValue("A2");
|
|
38
|
+
await ws.cell(2, 0).setValue("A3");
|
|
49
39
|
|
|
50
40
|
const col = ws.col(0);
|
|
51
41
|
const cells = await col.getCells();
|
|
52
42
|
|
|
53
43
|
expect(cells.length).toBeGreaterThanOrEqual(3);
|
|
54
|
-
expect(await cells[0].
|
|
55
|
-
expect(await cells[1].
|
|
56
|
-
expect(await cells[2].
|
|
44
|
+
expect(await cells[0].getValue()).toBe("A1");
|
|
45
|
+
expect(await cells[1].getValue()).toBe("A2");
|
|
46
|
+
expect(await cells[2].getValue()).toBe("A3");
|
|
57
47
|
});
|
|
58
48
|
|
|
59
49
|
it("Returns cell corresponding to default range (0,0) from empty worksheet", async () => {
|
|
60
50
|
const wb = new ExcelWorkbook();
|
|
61
|
-
const ws = await wb.
|
|
51
|
+
const ws = await wb.addWorksheet("Test");
|
|
62
52
|
|
|
63
53
|
const col = ws.col(0);
|
|
64
54
|
const cells = await col.getCells();
|
|
65
55
|
|
|
66
56
|
// Default range of empty worksheet is (0,0)-(0,0), so returns one cell
|
|
67
57
|
expect(cells.length).toBe(1);
|
|
68
|
-
expect(await cells[0].
|
|
58
|
+
expect(await cells[0].getValue()).toBeUndefined();
|
|
69
59
|
});
|
|
70
60
|
});
|
|
71
61
|
|
|
72
62
|
describe("setWidth()", () => {
|
|
73
63
|
it("Can set column width", async () => {
|
|
74
64
|
const wb = new ExcelWorkbook();
|
|
75
|
-
const ws = await wb.
|
|
65
|
+
const ws = await wb.addWorksheet("Test");
|
|
76
66
|
|
|
77
67
|
// Add data and set width
|
|
78
|
-
await ws.cell(0, 0).
|
|
68
|
+
await ws.cell(0, 0).setValue("Test");
|
|
79
69
|
await ws.col(0).setWidth(20);
|
|
80
70
|
|
|
81
71
|
// Verify settings via round-trip
|
|
82
|
-
const bytes = await wb.
|
|
72
|
+
const bytes = await wb.toBytes();
|
|
83
73
|
const wb2 = new ExcelWorkbook(bytes);
|
|
84
74
|
const ws2 = await wb2.getWorksheet(0);
|
|
85
75
|
|
|
86
76
|
// Verify value is preserved (width is hard to verify directly, so just check it works without error)
|
|
87
|
-
expect(await ws2.cell(0, 0).
|
|
77
|
+
expect(await ws2.cell(0, 0).getValue()).toBe("Test");
|
|
88
78
|
});
|
|
89
79
|
|
|
90
|
-
it("Can set different widths for multiple columns", async () => {
|
|
91
|
-
const wb = new ExcelWorkbook();
|
|
92
|
-
const ws = await wb.createWorksheet("Test");
|
|
93
|
-
|
|
94
|
-
await ws.cell(0, 0).setVal("A");
|
|
95
|
-
await ws.cell(0, 1).setVal("B");
|
|
96
|
-
await ws.cell(0, 2).setVal("C");
|
|
97
|
-
|
|
98
|
-
await ws.col(0).setWidth(10);
|
|
99
|
-
await ws.col(1).setWidth(20);
|
|
100
|
-
await ws.col(2).setWidth(30);
|
|
101
|
-
|
|
102
|
-
// Can round-trip without error
|
|
103
|
-
const bytes = await wb.getBytes();
|
|
104
|
-
const wb2 = new ExcelWorkbook(bytes);
|
|
105
|
-
const ws2 = await wb2.getWorksheet(0);
|
|
106
|
-
|
|
107
|
-
expect(await ws2.cell(0, 0).getVal()).toBe("A");
|
|
108
|
-
expect(await ws2.cell(0, 1).getVal()).toBe("B");
|
|
109
|
-
expect(await ws2.cell(0, 2).getVal()).toBe("C");
|
|
110
|
-
});
|
|
111
80
|
});
|
|
112
81
|
});
|
package/tests/excel-row.spec.ts
CHANGED
|
@@ -5,18 +5,18 @@ describe("ExcelRow", () => {
|
|
|
5
5
|
describe("cell()", () => {
|
|
6
6
|
it("returns cell corresponding to column index", async () => {
|
|
7
7
|
const wb = new ExcelWorkbook();
|
|
8
|
-
const ws = await wb.
|
|
8
|
+
const ws = await wb.addWorksheet("Test");
|
|
9
9
|
|
|
10
10
|
const row = ws.row(0);
|
|
11
11
|
const cell = row.cell(0);
|
|
12
12
|
|
|
13
|
-
await cell.
|
|
14
|
-
expect(await cell.
|
|
13
|
+
await cell.setValue("Hello");
|
|
14
|
+
expect(await cell.getValue()).toBe("Hello");
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it("returns same instance for same index (caching)", async () => {
|
|
18
18
|
const wb = new ExcelWorkbook();
|
|
19
|
-
const ws = await wb.
|
|
19
|
+
const ws = await wb.addWorksheet("Test");
|
|
20
20
|
|
|
21
21
|
const row = ws.row(0);
|
|
22
22
|
const cell1 = row.cell(0);
|
|
@@ -25,47 +25,37 @@ describe("ExcelRow", () => {
|
|
|
25
25
|
expect(cell1).toBe(cell2);
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
it("returns different instances for different indices", async () => {
|
|
29
|
-
const wb = new ExcelWorkbook();
|
|
30
|
-
const ws = await wb.createWorksheet("Test");
|
|
31
|
-
|
|
32
|
-
const row = ws.row(0);
|
|
33
|
-
const cell1 = row.cell(0);
|
|
34
|
-
const cell2 = row.cell(1);
|
|
35
|
-
|
|
36
|
-
expect(cell1).not.toBe(cell2);
|
|
37
|
-
});
|
|
38
28
|
});
|
|
39
29
|
|
|
40
30
|
describe("getCells()", () => {
|
|
41
31
|
it("returns all cells within range", async () => {
|
|
42
32
|
const wb = new ExcelWorkbook();
|
|
43
|
-
const ws = await wb.
|
|
33
|
+
const ws = await wb.addWorksheet("Test");
|
|
44
34
|
|
|
45
35
|
// Set range by configuring data
|
|
46
|
-
await ws.cell(0, 0).
|
|
47
|
-
await ws.cell(0, 1).
|
|
48
|
-
await ws.cell(0, 2).
|
|
36
|
+
await ws.cell(0, 0).setValue("A1");
|
|
37
|
+
await ws.cell(0, 1).setValue("B1");
|
|
38
|
+
await ws.cell(0, 2).setValue("C1");
|
|
49
39
|
|
|
50
40
|
const row = ws.row(0);
|
|
51
41
|
const cells = await row.getCells();
|
|
52
42
|
|
|
53
43
|
expect(cells.length).toBeGreaterThanOrEqual(3);
|
|
54
|
-
expect(await cells[0].
|
|
55
|
-
expect(await cells[1].
|
|
56
|
-
expect(await cells[2].
|
|
44
|
+
expect(await cells[0].getValue()).toBe("A1");
|
|
45
|
+
expect(await cells[1].getValue()).toBe("B1");
|
|
46
|
+
expect(await cells[2].getValue()).toBe("C1");
|
|
57
47
|
});
|
|
58
48
|
|
|
59
49
|
it("returns cell corresponding to default range (0,0) in empty worksheet", async () => {
|
|
60
50
|
const wb = new ExcelWorkbook();
|
|
61
|
-
const ws = await wb.
|
|
51
|
+
const ws = await wb.addWorksheet("Test");
|
|
62
52
|
|
|
63
53
|
const row = ws.row(0);
|
|
64
54
|
const cells = await row.getCells();
|
|
65
55
|
|
|
66
56
|
// Empty worksheet default range is (0,0)-(0,0) so returns one cell
|
|
67
57
|
expect(cells.length).toBe(1);
|
|
68
|
-
expect(await cells[0].
|
|
58
|
+
expect(await cells[0].getValue()).toBeUndefined();
|
|
69
59
|
});
|
|
70
60
|
});
|
|
71
61
|
});
|