@origints/xlsx 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/convert.d.ts +85 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.es.js +2257 -0
- package/dist/index.es.js.map +1 -0
- package/dist/parse.d.ts +85 -0
- package/dist/util.d.ts +68 -0
- package/dist/xlsx-cell.d.ts +212 -0
- package/dist/xlsx-cursor.d.ts +203 -0
- package/dist/xlsx-query.d.ts +155 -0
- package/dist/xlsx-range.d.ts +166 -0
- package/dist/xlsx-result.d.ts +94 -0
- package/dist/xlsx-sheet.d.ts +149 -0
- package/dist/xlsx-workbook.d.ts +128 -0
- package/package.json +46 -0
package/dist/index.es.js
ADDED
|
@@ -0,0 +1,2257 @@
|
|
|
1
|
+
import $ from "exceljs";
|
|
2
|
+
function l(s, t) {
|
|
3
|
+
return { ok: !0, value: s, path: t };
|
|
4
|
+
}
|
|
5
|
+
function h(s, t, e, r) {
|
|
6
|
+
return {
|
|
7
|
+
ok: !1,
|
|
8
|
+
failure: { kind: s, message: t, path: e, sourceLocation: r }
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
function F(s) {
|
|
12
|
+
const t = [];
|
|
13
|
+
return s.file && t.push(s.file), s.sheet && t.push(`[${s.sheet}]`), s.range ? t.push(`!${s.range}`) : s.cell && t.push(`!${s.cell}`), t.join("") || "workbook";
|
|
14
|
+
}
|
|
15
|
+
function U(s) {
|
|
16
|
+
if (s.sheet)
|
|
17
|
+
return {
|
|
18
|
+
kind: "excel",
|
|
19
|
+
file: s.file ?? "",
|
|
20
|
+
sheet: s.sheet,
|
|
21
|
+
range: s.range ?? s.cell ?? ""
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
function b(s) {
|
|
25
|
+
return typeof s == "object" && s !== null && !(s instanceof Date) && "formula" in s;
|
|
26
|
+
}
|
|
27
|
+
function S(s) {
|
|
28
|
+
return typeof s == "object" && s !== null && !(s instanceof Date) && "error" in s;
|
|
29
|
+
}
|
|
30
|
+
async function M(s) {
|
|
31
|
+
const t = s.getReader(), e = [];
|
|
32
|
+
try {
|
|
33
|
+
for (; ; ) {
|
|
34
|
+
const { done: r, value: n } = await t.read();
|
|
35
|
+
if (r) break;
|
|
36
|
+
e.push(n);
|
|
37
|
+
}
|
|
38
|
+
return Buffer.concat(e);
|
|
39
|
+
} finally {
|
|
40
|
+
t.releaseLock();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function T(s) {
|
|
44
|
+
let t = 0;
|
|
45
|
+
for (let e = 0; e < s.length; e++)
|
|
46
|
+
t = t * 26 + (s.charCodeAt(e) - 64);
|
|
47
|
+
return t;
|
|
48
|
+
}
|
|
49
|
+
function N(s) {
|
|
50
|
+
let t = "";
|
|
51
|
+
for (; s > 0; ) {
|
|
52
|
+
const e = (s - 1) % 26;
|
|
53
|
+
t = String.fromCharCode(65 + e) + t, s = Math.floor((s - 1) / 26);
|
|
54
|
+
}
|
|
55
|
+
return t;
|
|
56
|
+
}
|
|
57
|
+
function p(s) {
|
|
58
|
+
const t = s.match(/^([A-Z]+)(\d+)$/i);
|
|
59
|
+
if (!t)
|
|
60
|
+
throw new Error(`Invalid cell address: ${s}`);
|
|
61
|
+
const e = t[1].toUpperCase();
|
|
62
|
+
return {
|
|
63
|
+
row: parseInt(t[2], 10),
|
|
64
|
+
col: T(e),
|
|
65
|
+
colLetter: e
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function R(s, t) {
|
|
69
|
+
return `${N(t)}${s}`;
|
|
70
|
+
}
|
|
71
|
+
function y(s) {
|
|
72
|
+
const t = s.split(":");
|
|
73
|
+
if (t.length === 1) {
|
|
74
|
+
const n = p(t[0]);
|
|
75
|
+
return {
|
|
76
|
+
start: { row: n.row, col: n.col },
|
|
77
|
+
end: { row: n.row, col: n.col }
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (t.length !== 2)
|
|
81
|
+
throw new Error(`Invalid range: ${s}`);
|
|
82
|
+
const e = p(t[0]), r = p(t[1]);
|
|
83
|
+
return {
|
|
84
|
+
start: { row: e.row, col: e.col },
|
|
85
|
+
end: { row: r.row, col: r.col }
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function A(s, t, e, r) {
|
|
89
|
+
const n = R(s, t), o = R(e, r);
|
|
90
|
+
return n === o ? n : `${n}:${o}`;
|
|
91
|
+
}
|
|
92
|
+
function O(s, t, e) {
|
|
93
|
+
return s >= e.start.row && s <= e.end.row && t >= e.start.col && t <= e.end.col;
|
|
94
|
+
}
|
|
95
|
+
class w {
|
|
96
|
+
constructor(t, e, r) {
|
|
97
|
+
this.cell = t, this._path = e, this._sheetName = r;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates an XlsxCell from an ExcelJS cell.
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
static fromExcelJS(t, e, r) {
|
|
104
|
+
const n = {
|
|
105
|
+
file: r,
|
|
106
|
+
sheet: e,
|
|
107
|
+
cell: t.address
|
|
108
|
+
};
|
|
109
|
+
return new w(t, n, e);
|
|
110
|
+
}
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
// IDENTITY & LOCATION
|
|
113
|
+
// ---------------------------------------------------------------------------
|
|
114
|
+
/**
|
|
115
|
+
* Returns the cell address (e.g., "A1").
|
|
116
|
+
*/
|
|
117
|
+
get address() {
|
|
118
|
+
return this.cell.address;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Returns the 1-based row number.
|
|
122
|
+
*/
|
|
123
|
+
get row() {
|
|
124
|
+
return typeof this.cell.row == "number" ? this.cell.row : parseInt(String(this.cell.row), 10);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Returns the 1-based column number.
|
|
128
|
+
*/
|
|
129
|
+
get col() {
|
|
130
|
+
return typeof this.cell.col == "number" ? this.cell.col : parseInt(String(this.cell.col), 10);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Returns the column letter(s) (e.g., "A", "AA").
|
|
134
|
+
*/
|
|
135
|
+
get colLetter() {
|
|
136
|
+
return this.address.replace(/\d+$/, "");
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Returns the current path for lineage tracking.
|
|
140
|
+
*/
|
|
141
|
+
get path() {
|
|
142
|
+
return this._path;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Returns the sheet name this cell belongs to.
|
|
146
|
+
*/
|
|
147
|
+
get sheetName() {
|
|
148
|
+
return this._sheetName;
|
|
149
|
+
}
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
// VALUE EXTRACTION
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
/**
|
|
154
|
+
* Returns the raw cell value.
|
|
155
|
+
*/
|
|
156
|
+
value() {
|
|
157
|
+
const t = this.getRawValue();
|
|
158
|
+
return b(t) ? l(t.result ?? null, this._path) : S(t) ? h("formula", `Cell contains error: ${t.error}`, this._path) : l(t, this._path);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Returns the extended cell value (including formula info).
|
|
162
|
+
*/
|
|
163
|
+
extendedValue() {
|
|
164
|
+
return l(this.getRawValue(), this._path);
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Extract value as a string.
|
|
168
|
+
*/
|
|
169
|
+
string() {
|
|
170
|
+
const t = this.getResolvedValue();
|
|
171
|
+
return t == null ? h("type", "Expected string, got null", this._path) : typeof t == "string" ? l(t, this._path) : typeof t == "number" || typeof t == "boolean" ? l(String(t), this._path) : t instanceof Date ? l(t.toISOString(), this._path) : h("type", `Expected string, got ${typeof t}`, this._path);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Extract value as a number.
|
|
175
|
+
*/
|
|
176
|
+
number() {
|
|
177
|
+
const t = this.getResolvedValue();
|
|
178
|
+
if (typeof t == "number")
|
|
179
|
+
return l(t, this._path);
|
|
180
|
+
if (typeof t == "string") {
|
|
181
|
+
const e = parseFloat(t);
|
|
182
|
+
if (!isNaN(e))
|
|
183
|
+
return l(e, this._path);
|
|
184
|
+
}
|
|
185
|
+
return h("type", `Expected number, got ${E(t)}`, this._path);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Extract value as a boolean.
|
|
189
|
+
*/
|
|
190
|
+
boolean() {
|
|
191
|
+
const t = this.getResolvedValue();
|
|
192
|
+
return typeof t == "boolean" ? l(t, this._path) : h("type", `Expected boolean, got ${E(t)}`, this._path);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Extract value as a Date.
|
|
196
|
+
*/
|
|
197
|
+
date() {
|
|
198
|
+
const t = this.getResolvedValue();
|
|
199
|
+
if (t instanceof Date)
|
|
200
|
+
return l(t, this._path);
|
|
201
|
+
if (typeof t == "number") {
|
|
202
|
+
const e = this.excelDateToJS(t);
|
|
203
|
+
return l(e, this._path);
|
|
204
|
+
}
|
|
205
|
+
if (typeof t == "string") {
|
|
206
|
+
const e = new Date(t);
|
|
207
|
+
if (!isNaN(e.getTime()))
|
|
208
|
+
return l(e, this._path);
|
|
209
|
+
}
|
|
210
|
+
return h("type", `Expected date, got ${E(t)}`, this._path);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Get the formula if this cell contains one.
|
|
214
|
+
*/
|
|
215
|
+
formula() {
|
|
216
|
+
const t = this.getRawValue();
|
|
217
|
+
return b(t) ? l(t.formula, this._path) : h("type", "Cell does not contain a formula", this._path);
|
|
218
|
+
}
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
220
|
+
// RICH TEXT & MARKDOWN
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
/**
|
|
223
|
+
* Get the cell content as rich text with formatting preserved.
|
|
224
|
+
* Returns segments with their individual formatting properties.
|
|
225
|
+
*/
|
|
226
|
+
richText() {
|
|
227
|
+
const t = this.cell.value, e = this.cell.hyperlink;
|
|
228
|
+
if (t && typeof t == "object" && "richText" in t) {
|
|
229
|
+
const u = t.richText.map((c) => ({
|
|
230
|
+
text: c.text,
|
|
231
|
+
bold: c.font?.bold,
|
|
232
|
+
italic: c.font?.italic,
|
|
233
|
+
underline: c.font?.underline === !0 || c.font?.underline === "single",
|
|
234
|
+
strikethrough: c.font?.strike,
|
|
235
|
+
color: c.font?.color?.argb,
|
|
236
|
+
size: c.font?.size,
|
|
237
|
+
font: c.font?.name
|
|
238
|
+
}));
|
|
239
|
+
return l({ segments: u, hyperlink: e }, this._path);
|
|
240
|
+
}
|
|
241
|
+
if (t && typeof t == "object" && "text" in t && "hyperlink" in t) {
|
|
242
|
+
const a = t, u = this.style(), c = {
|
|
243
|
+
text: a.text,
|
|
244
|
+
bold: u.font?.bold,
|
|
245
|
+
italic: u.font?.italic,
|
|
246
|
+
underline: u.font?.underline,
|
|
247
|
+
strikethrough: u.font?.strikethrough,
|
|
248
|
+
color: u.font?.color,
|
|
249
|
+
size: u.font?.size,
|
|
250
|
+
font: u.font?.name
|
|
251
|
+
};
|
|
252
|
+
return l(
|
|
253
|
+
{
|
|
254
|
+
segments: [c],
|
|
255
|
+
hyperlink: a.hyperlink
|
|
256
|
+
},
|
|
257
|
+
this._path
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
const r = this.getResolvedValue(), n = r !== null ? String(r) : "", o = this.style(), i = {
|
|
261
|
+
text: n,
|
|
262
|
+
bold: o.font?.bold,
|
|
263
|
+
italic: o.font?.italic,
|
|
264
|
+
underline: o.font?.underline,
|
|
265
|
+
strikethrough: o.font?.strikethrough,
|
|
266
|
+
color: o.font?.color,
|
|
267
|
+
size: o.font?.size,
|
|
268
|
+
font: o.font?.name
|
|
269
|
+
};
|
|
270
|
+
return l({ segments: [i], hyperlink: e }, this._path);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Get the cell content as Markdown.
|
|
274
|
+
*
|
|
275
|
+
* Converts cell content including:
|
|
276
|
+
* - Bold text -> **text**
|
|
277
|
+
* - Italic text -> *text*
|
|
278
|
+
* - Strikethrough -> ~~text~~
|
|
279
|
+
* - Hyperlinks -> [text](url)
|
|
280
|
+
* - Rich text segments with mixed formatting
|
|
281
|
+
*/
|
|
282
|
+
markdown() {
|
|
283
|
+
const t = this.richText();
|
|
284
|
+
if (!t.ok)
|
|
285
|
+
return t;
|
|
286
|
+
const { segments: e, hyperlink: r } = t.value;
|
|
287
|
+
let n = "";
|
|
288
|
+
for (const o of e) {
|
|
289
|
+
let i = o.text;
|
|
290
|
+
o.strikethrough && (i = `~~${i}~~`), o.bold && (i = `**${i}**`), o.italic && (i = `*${i}*`), n += i;
|
|
291
|
+
}
|
|
292
|
+
return r && (n = `[${n}](${r})`), l(n, this._path);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Check if the cell contains rich text (multiple formatted segments).
|
|
296
|
+
*/
|
|
297
|
+
isRichText() {
|
|
298
|
+
const t = this.cell.value;
|
|
299
|
+
return t !== null && typeof t == "object" && "richText" in t;
|
|
300
|
+
}
|
|
301
|
+
// ---------------------------------------------------------------------------
|
|
302
|
+
// TYPE CHECKING
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
/**
|
|
305
|
+
* Check if the cell is empty.
|
|
306
|
+
*/
|
|
307
|
+
isEmpty() {
|
|
308
|
+
const t = this.cell.value;
|
|
309
|
+
return t == null || t === "";
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Check if the cell contains a formula.
|
|
313
|
+
*/
|
|
314
|
+
isFormula() {
|
|
315
|
+
return b(this.getRawValue());
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Check if the cell is part of a merged range.
|
|
319
|
+
*/
|
|
320
|
+
isMerged() {
|
|
321
|
+
return this.cell.isMerged;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Check if this is the master cell of a merged range.
|
|
325
|
+
*/
|
|
326
|
+
isMergedMaster() {
|
|
327
|
+
return this.cell.isMerged ? this.cell.master.address === this.cell.address : !1;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Check if the cell contains a string.
|
|
331
|
+
*/
|
|
332
|
+
isString() {
|
|
333
|
+
return typeof this.getResolvedValue() == "string";
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Check if the cell contains a number.
|
|
337
|
+
*/
|
|
338
|
+
isNumber() {
|
|
339
|
+
return typeof this.getResolvedValue() == "number";
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Check if the cell contains a boolean.
|
|
343
|
+
*/
|
|
344
|
+
isBoolean() {
|
|
345
|
+
return typeof this.getResolvedValue() == "boolean";
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Check if the cell contains a date.
|
|
349
|
+
*/
|
|
350
|
+
isDate() {
|
|
351
|
+
return this.getResolvedValue() instanceof Date;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Check if the cell contains an error.
|
|
355
|
+
*/
|
|
356
|
+
isError() {
|
|
357
|
+
return S(this.getRawValue());
|
|
358
|
+
}
|
|
359
|
+
// ---------------------------------------------------------------------------
|
|
360
|
+
// METADATA
|
|
361
|
+
// ---------------------------------------------------------------------------
|
|
362
|
+
/**
|
|
363
|
+
* Get the cell's style information.
|
|
364
|
+
*/
|
|
365
|
+
style() {
|
|
366
|
+
const t = this.cell.font, e = this.cell.fill, r = this.cell.border, n = this.cell.alignment;
|
|
367
|
+
return {
|
|
368
|
+
font: t ? {
|
|
369
|
+
name: t.name,
|
|
370
|
+
size: t.size,
|
|
371
|
+
bold: t.bold,
|
|
372
|
+
italic: t.italic,
|
|
373
|
+
underline: t.underline === !0 || t.underline === "single",
|
|
374
|
+
strikethrough: t.strike,
|
|
375
|
+
color: t.color?.argb ?? (t.color?.theme !== void 0 ? `theme:${t.color.theme}` : void 0)
|
|
376
|
+
} : void 0,
|
|
377
|
+
fill: e && e.type === "pattern" ? {
|
|
378
|
+
type: e.pattern,
|
|
379
|
+
color: e.fgColor?.argb
|
|
380
|
+
} : void 0,
|
|
381
|
+
border: r ? {
|
|
382
|
+
top: !!r.top,
|
|
383
|
+
bottom: !!r.bottom,
|
|
384
|
+
left: !!r.left,
|
|
385
|
+
right: !!r.right
|
|
386
|
+
} : void 0,
|
|
387
|
+
alignment: n ? {
|
|
388
|
+
horizontal: n.horizontal,
|
|
389
|
+
vertical: n.vertical,
|
|
390
|
+
wrapText: n.wrapText
|
|
391
|
+
} : void 0,
|
|
392
|
+
numFmt: this.cell.numFmt
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Get the hyperlink URL if the cell contains one.
|
|
397
|
+
*/
|
|
398
|
+
hyperlink() {
|
|
399
|
+
const t = this.cell.hyperlink;
|
|
400
|
+
return t ? l(t, this._path) : h("missing", "Cell does not contain a hyperlink", this._path);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Get the comment/note if the cell has one.
|
|
404
|
+
*/
|
|
405
|
+
comment() {
|
|
406
|
+
const t = this.cell.note;
|
|
407
|
+
return t ? typeof t == "string" ? l(t, this._path) : t.texts ? l(
|
|
408
|
+
t.texts.map((e) => e.text).join(""),
|
|
409
|
+
this._path
|
|
410
|
+
) : h("format", "Unable to extract comment text", this._path) : h("missing", "Cell does not contain a comment", this._path);
|
|
411
|
+
}
|
|
412
|
+
// ---------------------------------------------------------------------------
|
|
413
|
+
// NAVIGATION FROM CELL
|
|
414
|
+
// ---------------------------------------------------------------------------
|
|
415
|
+
/**
|
|
416
|
+
* Get a cell offset from this one.
|
|
417
|
+
* @internal Used by navigation methods
|
|
418
|
+
*/
|
|
419
|
+
getOffsetCell(t, e, r) {
|
|
420
|
+
const n = this.row + t, o = this.col + e;
|
|
421
|
+
if (n < 1 || o < 1)
|
|
422
|
+
return h(
|
|
423
|
+
"bounds",
|
|
424
|
+
`Cell offset (${t}, ${e}) from ${this.address} is out of bounds`,
|
|
425
|
+
this._path
|
|
426
|
+
);
|
|
427
|
+
const i = r(n, o);
|
|
428
|
+
return i ? l(i, i.path) : h(
|
|
429
|
+
"missing",
|
|
430
|
+
`Cell at ${R(n, o)} not found`,
|
|
431
|
+
this._path
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
// ---------------------------------------------------------------------------
|
|
435
|
+
// INTERNAL HELPERS
|
|
436
|
+
// ---------------------------------------------------------------------------
|
|
437
|
+
/**
|
|
438
|
+
* Get the raw value, handling ExcelJS value types.
|
|
439
|
+
*/
|
|
440
|
+
getRawValue() {
|
|
441
|
+
const t = this.cell.value;
|
|
442
|
+
if (t == null)
|
|
443
|
+
return null;
|
|
444
|
+
if (typeof t == "object") {
|
|
445
|
+
if ("error" in t)
|
|
446
|
+
return { error: String(t.error) };
|
|
447
|
+
if ("formula" in t) {
|
|
448
|
+
const e = t;
|
|
449
|
+
return {
|
|
450
|
+
formula: e.formula,
|
|
451
|
+
result: this.normalizeResult(e.result)
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
if ("sharedFormula" in t) {
|
|
455
|
+
const e = t;
|
|
456
|
+
return {
|
|
457
|
+
formula: e.sharedFormula,
|
|
458
|
+
result: this.normalizeResult(e.result)
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
if ("richText" in t)
|
|
462
|
+
return t.richText.map((r) => r.text).join("");
|
|
463
|
+
if (t instanceof Date)
|
|
464
|
+
return t;
|
|
465
|
+
}
|
|
466
|
+
return typeof t == "string" || typeof t == "number" || typeof t == "boolean" ? t : null;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Get the resolved value (formula result or plain value).
|
|
470
|
+
*/
|
|
471
|
+
getResolvedValue() {
|
|
472
|
+
const t = this.getRawValue();
|
|
473
|
+
return b(t) ? t.result ?? null : S(t) ? null : t;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Normalize a formula result value.
|
|
477
|
+
*/
|
|
478
|
+
normalizeResult(t) {
|
|
479
|
+
return t == null ? null : typeof t == "string" || typeof t == "number" || typeof t == "boolean" || t instanceof Date ? t : null;
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Convert Excel date number to JavaScript Date.
|
|
483
|
+
* Excel dates are days since 1900-01-01 (with a leap year bug).
|
|
484
|
+
*/
|
|
485
|
+
excelDateToJS(t) {
|
|
486
|
+
const e = t > 60 ? -1 : 0, r = t + e - 1, n = new Date(1900, 0, 1);
|
|
487
|
+
return new Date(n.getTime() + r * 24 * 60 * 60 * 1e3);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
function E(s) {
|
|
491
|
+
return s === null ? "null" : s === void 0 ? "undefined" : s instanceof Date ? "date" : Array.isArray(s) ? "array" : typeof s;
|
|
492
|
+
}
|
|
493
|
+
class m {
|
|
494
|
+
constructor(t, e, r, n, o, i, a, u) {
|
|
495
|
+
this.worksheet = t, this._startRow = e, this._startCol = r, this._endRow = n, this._endCol = o, this._path = i, this._sheetName = a, this._file = u;
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Creates an XlsxRange from coordinates.
|
|
499
|
+
* @internal
|
|
500
|
+
*/
|
|
501
|
+
static fromCoords(t, e, r, n, o, i, a) {
|
|
502
|
+
const u = A(e, r, n, o), c = {
|
|
503
|
+
file: a,
|
|
504
|
+
sheet: i,
|
|
505
|
+
range: u
|
|
506
|
+
};
|
|
507
|
+
return new m(
|
|
508
|
+
t,
|
|
509
|
+
e,
|
|
510
|
+
r,
|
|
511
|
+
n,
|
|
512
|
+
o,
|
|
513
|
+
c,
|
|
514
|
+
i,
|
|
515
|
+
a
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Creates an XlsxRange from an address string.
|
|
520
|
+
* @internal
|
|
521
|
+
*/
|
|
522
|
+
static fromAddress(t, e, r, n) {
|
|
523
|
+
try {
|
|
524
|
+
const { start: o, end: i } = y(e);
|
|
525
|
+
return l(
|
|
526
|
+
m.fromCoords(
|
|
527
|
+
t,
|
|
528
|
+
o.row,
|
|
529
|
+
o.col,
|
|
530
|
+
i.row,
|
|
531
|
+
i.col,
|
|
532
|
+
r,
|
|
533
|
+
n
|
|
534
|
+
),
|
|
535
|
+
{ file: n, sheet: r, range: e }
|
|
536
|
+
);
|
|
537
|
+
} catch {
|
|
538
|
+
return h(
|
|
539
|
+
"range",
|
|
540
|
+
`Invalid range address: ${e}`,
|
|
541
|
+
{ file: n, sheet: r }
|
|
542
|
+
);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
// ---------------------------------------------------------------------------
|
|
546
|
+
// IDENTITY
|
|
547
|
+
// ---------------------------------------------------------------------------
|
|
548
|
+
/**
|
|
549
|
+
* Returns the range address (e.g., "A1:C10").
|
|
550
|
+
*/
|
|
551
|
+
get address() {
|
|
552
|
+
return A(
|
|
553
|
+
this._startRow,
|
|
554
|
+
this._startCol,
|
|
555
|
+
this._endRow,
|
|
556
|
+
this._endCol
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Returns the start row (1-based).
|
|
561
|
+
*/
|
|
562
|
+
get startRow() {
|
|
563
|
+
return this._startRow;
|
|
564
|
+
}
|
|
565
|
+
/**
|
|
566
|
+
* Returns the start column (1-based).
|
|
567
|
+
*/
|
|
568
|
+
get startCol() {
|
|
569
|
+
return this._startCol;
|
|
570
|
+
}
|
|
571
|
+
/**
|
|
572
|
+
* Returns the end row (1-based).
|
|
573
|
+
*/
|
|
574
|
+
get endRow() {
|
|
575
|
+
return this._endRow;
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Returns the end column (1-based).
|
|
579
|
+
*/
|
|
580
|
+
get endCol() {
|
|
581
|
+
return this._endCol;
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* Returns the current path for lineage tracking.
|
|
585
|
+
*/
|
|
586
|
+
get path() {
|
|
587
|
+
return this._path;
|
|
588
|
+
}
|
|
589
|
+
/**
|
|
590
|
+
* Returns the number of rows in the range.
|
|
591
|
+
*/
|
|
592
|
+
get rowCount() {
|
|
593
|
+
return this._endRow - this._startRow + 1;
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* Returns the number of columns in the range.
|
|
597
|
+
*/
|
|
598
|
+
get colCount() {
|
|
599
|
+
return this._endCol - this._startCol + 1;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Returns the total number of cells in the range.
|
|
603
|
+
*/
|
|
604
|
+
get cellCount() {
|
|
605
|
+
return this.rowCount * this.colCount;
|
|
606
|
+
}
|
|
607
|
+
// ---------------------------------------------------------------------------
|
|
608
|
+
// CELL ACCESS
|
|
609
|
+
// ---------------------------------------------------------------------------
|
|
610
|
+
/**
|
|
611
|
+
* Get a cell at specific row and column within this range.
|
|
612
|
+
* Coordinates are relative to the range start (0-indexed).
|
|
613
|
+
*/
|
|
614
|
+
cellAt(t, e) {
|
|
615
|
+
const r = this._startRow + t, n = this._startCol + e;
|
|
616
|
+
if (r < this._startRow || r > this._endRow || n < this._startCol || n > this._endCol)
|
|
617
|
+
return h(
|
|
618
|
+
"bounds",
|
|
619
|
+
`Offset (${t}, ${e}) is outside range ${this.address}`,
|
|
620
|
+
this._path
|
|
621
|
+
);
|
|
622
|
+
const o = this.worksheet.getCell(r, n);
|
|
623
|
+
return l(w.fromExcelJS(o, this._sheetName, this._file), {
|
|
624
|
+
...this._path,
|
|
625
|
+
cell: o.address,
|
|
626
|
+
range: void 0
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Get a cell by its address within this range.
|
|
631
|
+
*/
|
|
632
|
+
cell(t) {
|
|
633
|
+
try {
|
|
634
|
+
const { start: e } = y(t);
|
|
635
|
+
if (e.row < this._startRow || e.row > this._endRow || e.col < this._startCol || e.col > this._endCol)
|
|
636
|
+
return h(
|
|
637
|
+
"bounds",
|
|
638
|
+
`Cell ${t} is outside range ${this.address}`,
|
|
639
|
+
this._path
|
|
640
|
+
);
|
|
641
|
+
const r = this.worksheet.getCell(t);
|
|
642
|
+
return l(w.fromExcelJS(r, this._sheetName, this._file), {
|
|
643
|
+
...this._path,
|
|
644
|
+
cell: t,
|
|
645
|
+
range: void 0
|
|
646
|
+
});
|
|
647
|
+
} catch {
|
|
648
|
+
return h("range", `Invalid cell address: ${t}`, this._path);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
// ---------------------------------------------------------------------------
|
|
652
|
+
// ITERATION
|
|
653
|
+
// ---------------------------------------------------------------------------
|
|
654
|
+
/**
|
|
655
|
+
* Iterate over all cells in the range (row by row).
|
|
656
|
+
*/
|
|
657
|
+
*cells() {
|
|
658
|
+
for (let t = this._startRow; t <= this._endRow; t++)
|
|
659
|
+
for (let e = this._startCol; e <= this._endCol; e++) {
|
|
660
|
+
const r = this.worksheet.getCell(t, e);
|
|
661
|
+
yield w.fromExcelJS(r, this._sheetName, this._file);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Iterate over rows, returning arrays of cells.
|
|
666
|
+
*/
|
|
667
|
+
*rows() {
|
|
668
|
+
for (let t = this._startRow; t <= this._endRow; t++) {
|
|
669
|
+
const e = [];
|
|
670
|
+
for (let r = this._startCol; r <= this._endCol; r++) {
|
|
671
|
+
const n = this.worksheet.getCell(t, r);
|
|
672
|
+
e.push(w.fromExcelJS(n, this._sheetName, this._file));
|
|
673
|
+
}
|
|
674
|
+
yield e;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Iterate over columns, returning arrays of cells.
|
|
679
|
+
*/
|
|
680
|
+
*cols() {
|
|
681
|
+
for (let t = this._startCol; t <= this._endCol; t++) {
|
|
682
|
+
const e = [];
|
|
683
|
+
for (let r = this._startRow; r <= this._endRow; r++) {
|
|
684
|
+
const n = this.worksheet.getCell(r, t);
|
|
685
|
+
e.push(w.fromExcelJS(n, this._sheetName, this._file));
|
|
686
|
+
}
|
|
687
|
+
yield e;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Get all values in the range as a 2D array.
|
|
692
|
+
*/
|
|
693
|
+
values() {
|
|
694
|
+
const t = [];
|
|
695
|
+
for (const e of this.rows()) {
|
|
696
|
+
const r = [];
|
|
697
|
+
for (const n of e) {
|
|
698
|
+
const o = n.value();
|
|
699
|
+
r.push(o.ok ? o.value : null);
|
|
700
|
+
}
|
|
701
|
+
t.push(r);
|
|
702
|
+
}
|
|
703
|
+
return t;
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Get all cells as a flat array.
|
|
707
|
+
*/
|
|
708
|
+
cellsArray() {
|
|
709
|
+
return [...this.cells()];
|
|
710
|
+
}
|
|
711
|
+
// ---------------------------------------------------------------------------
|
|
712
|
+
// SUBRANGE
|
|
713
|
+
// ---------------------------------------------------------------------------
|
|
714
|
+
/**
|
|
715
|
+
* Get a subrange within this range.
|
|
716
|
+
*/
|
|
717
|
+
subRange(t) {
|
|
718
|
+
try {
|
|
719
|
+
const { start: e, end: r } = y(t);
|
|
720
|
+
return e.row < this._startRow || r.row > this._endRow || e.col < this._startCol || r.col > this._endCol ? h(
|
|
721
|
+
"bounds",
|
|
722
|
+
`Subrange ${t} extends outside range ${this.address}`,
|
|
723
|
+
this._path
|
|
724
|
+
) : l(
|
|
725
|
+
m.fromCoords(
|
|
726
|
+
this.worksheet,
|
|
727
|
+
e.row,
|
|
728
|
+
e.col,
|
|
729
|
+
r.row,
|
|
730
|
+
r.col,
|
|
731
|
+
this._sheetName,
|
|
732
|
+
this._file
|
|
733
|
+
),
|
|
734
|
+
{ ...this._path, range: t }
|
|
735
|
+
);
|
|
736
|
+
} catch {
|
|
737
|
+
return h("range", `Invalid range address: ${t}`, this._path);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Get the first row as a range.
|
|
742
|
+
*/
|
|
743
|
+
firstRow() {
|
|
744
|
+
return m.fromCoords(
|
|
745
|
+
this.worksheet,
|
|
746
|
+
this._startRow,
|
|
747
|
+
this._startCol,
|
|
748
|
+
this._startRow,
|
|
749
|
+
this._endCol,
|
|
750
|
+
this._sheetName,
|
|
751
|
+
this._file
|
|
752
|
+
);
|
|
753
|
+
}
|
|
754
|
+
/**
|
|
755
|
+
* Get the last row as a range.
|
|
756
|
+
*/
|
|
757
|
+
lastRow() {
|
|
758
|
+
return m.fromCoords(
|
|
759
|
+
this.worksheet,
|
|
760
|
+
this._endRow,
|
|
761
|
+
this._startCol,
|
|
762
|
+
this._endRow,
|
|
763
|
+
this._endCol,
|
|
764
|
+
this._sheetName,
|
|
765
|
+
this._file
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Get the first column as a range.
|
|
770
|
+
*/
|
|
771
|
+
firstCol() {
|
|
772
|
+
return m.fromCoords(
|
|
773
|
+
this.worksheet,
|
|
774
|
+
this._startRow,
|
|
775
|
+
this._startCol,
|
|
776
|
+
this._endRow,
|
|
777
|
+
this._startCol,
|
|
778
|
+
this._sheetName,
|
|
779
|
+
this._file
|
|
780
|
+
);
|
|
781
|
+
}
|
|
782
|
+
/**
|
|
783
|
+
* Get the last column as a range.
|
|
784
|
+
*/
|
|
785
|
+
lastCol() {
|
|
786
|
+
return m.fromCoords(
|
|
787
|
+
this.worksheet,
|
|
788
|
+
this._startRow,
|
|
789
|
+
this._endCol,
|
|
790
|
+
this._endRow,
|
|
791
|
+
this._endCol,
|
|
792
|
+
this._sheetName,
|
|
793
|
+
this._file
|
|
794
|
+
);
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Get a specific row as a range (0-indexed offset from start).
|
|
798
|
+
*/
|
|
799
|
+
rowAt(t) {
|
|
800
|
+
const e = this._startRow + t;
|
|
801
|
+
return e < this._startRow || e > this._endRow ? h(
|
|
802
|
+
"bounds",
|
|
803
|
+
`Row offset ${t} is outside range ${this.address}`,
|
|
804
|
+
this._path
|
|
805
|
+
) : l(
|
|
806
|
+
m.fromCoords(
|
|
807
|
+
this.worksheet,
|
|
808
|
+
e,
|
|
809
|
+
this._startCol,
|
|
810
|
+
e,
|
|
811
|
+
this._endCol,
|
|
812
|
+
this._sheetName,
|
|
813
|
+
this._file
|
|
814
|
+
),
|
|
815
|
+
this._path
|
|
816
|
+
);
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Get a specific column as a range (0-indexed offset from start).
|
|
820
|
+
*/
|
|
821
|
+
colAt(t) {
|
|
822
|
+
const e = this._startCol + t;
|
|
823
|
+
return e < this._startCol || e > this._endCol ? h(
|
|
824
|
+
"bounds",
|
|
825
|
+
`Column offset ${t} is outside range ${this.address}`,
|
|
826
|
+
this._path
|
|
827
|
+
) : l(
|
|
828
|
+
m.fromCoords(
|
|
829
|
+
this.worksheet,
|
|
830
|
+
this._startRow,
|
|
831
|
+
e,
|
|
832
|
+
this._endRow,
|
|
833
|
+
e,
|
|
834
|
+
this._sheetName,
|
|
835
|
+
this._file
|
|
836
|
+
),
|
|
837
|
+
this._path
|
|
838
|
+
);
|
|
839
|
+
}
|
|
840
|
+
// ---------------------------------------------------------------------------
|
|
841
|
+
// QUERY
|
|
842
|
+
// ---------------------------------------------------------------------------
|
|
843
|
+
/**
|
|
844
|
+
* Find the first cell matching the predicate.
|
|
845
|
+
*/
|
|
846
|
+
find(t) {
|
|
847
|
+
for (const e of this.cells())
|
|
848
|
+
if (t(e))
|
|
849
|
+
return l(e, e.path);
|
|
850
|
+
return h(
|
|
851
|
+
"missing",
|
|
852
|
+
`No cell matching predicate found in range ${this.address}`,
|
|
853
|
+
this._path
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Find all cells matching the predicate.
|
|
858
|
+
*/
|
|
859
|
+
findAll(t) {
|
|
860
|
+
const e = [];
|
|
861
|
+
for (const r of this.cells())
|
|
862
|
+
t(r) && e.push(r);
|
|
863
|
+
return e;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Find the first cell with the specified value.
|
|
867
|
+
*/
|
|
868
|
+
findValue(t) {
|
|
869
|
+
for (const e of this.cells()) {
|
|
870
|
+
const r = e.value();
|
|
871
|
+
if (r.ok && r.value === t)
|
|
872
|
+
return l(e, e.path);
|
|
873
|
+
}
|
|
874
|
+
return h(
|
|
875
|
+
"missing",
|
|
876
|
+
`Value "${t}" not found in range ${this.address}`,
|
|
877
|
+
this._path
|
|
878
|
+
);
|
|
879
|
+
}
|
|
880
|
+
/**
|
|
881
|
+
* Check if any cell matches the predicate.
|
|
882
|
+
*/
|
|
883
|
+
some(t) {
|
|
884
|
+
for (const e of this.cells())
|
|
885
|
+
if (t(e))
|
|
886
|
+
return !0;
|
|
887
|
+
return !1;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* Check if all cells match the predicate.
|
|
891
|
+
*/
|
|
892
|
+
every(t) {
|
|
893
|
+
for (const e of this.cells())
|
|
894
|
+
if (!t(e))
|
|
895
|
+
return !1;
|
|
896
|
+
return !0;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Count cells matching the predicate.
|
|
900
|
+
*/
|
|
901
|
+
count(t) {
|
|
902
|
+
let e = 0;
|
|
903
|
+
for (const r of this.cells())
|
|
904
|
+
t(r) && e++;
|
|
905
|
+
return e;
|
|
906
|
+
}
|
|
907
|
+
// ---------------------------------------------------------------------------
|
|
908
|
+
// CONVERSION
|
|
909
|
+
// ---------------------------------------------------------------------------
|
|
910
|
+
/**
|
|
911
|
+
* Convert range to a 2D array of values.
|
|
912
|
+
*/
|
|
913
|
+
toArray() {
|
|
914
|
+
return this.values();
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* Convert range to array of objects using a header row.
|
|
918
|
+
* @param headerRowOffset - Row offset for headers (default: 0, first row)
|
|
919
|
+
* @param dataStartOffset - Row offset where data starts (default: 1, second row)
|
|
920
|
+
*/
|
|
921
|
+
toObjects(t = 0, e = 1) {
|
|
922
|
+
const r = [...this.rows()];
|
|
923
|
+
if (r.length === 0) return [];
|
|
924
|
+
const n = r[t];
|
|
925
|
+
if (!n) return [];
|
|
926
|
+
const o = n.map((a) => {
|
|
927
|
+
const u = a.value();
|
|
928
|
+
return u.ok && u.value !== null ? String(u.value) : "";
|
|
929
|
+
}), i = [];
|
|
930
|
+
for (let a = e; a < r.length; a++) {
|
|
931
|
+
const u = r[a], c = {};
|
|
932
|
+
for (let f = 0; f < o.length; f++) {
|
|
933
|
+
const g = o[f];
|
|
934
|
+
if (g) {
|
|
935
|
+
const _ = u[f]?.value();
|
|
936
|
+
c[g] = _?.ok ? _.value : null;
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
i.push(c);
|
|
940
|
+
}
|
|
941
|
+
return i;
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Convert range to JSON-compatible structure.
|
|
945
|
+
*/
|
|
946
|
+
toJson() {
|
|
947
|
+
return {
|
|
948
|
+
address: this.address,
|
|
949
|
+
rows: this.values()
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
class d {
|
|
954
|
+
constructor(t, e, r, n = "right") {
|
|
955
|
+
this.sheet = t, this._row = e, this._col = r, this._direction = n;
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Create a cursor from an address string.
|
|
959
|
+
* @internal
|
|
960
|
+
*/
|
|
961
|
+
static create(t, e) {
|
|
962
|
+
const { row: r, col: n } = p(e);
|
|
963
|
+
return new d(t, r, n);
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* Create a cursor from row and column coordinates.
|
|
967
|
+
* @internal
|
|
968
|
+
*/
|
|
969
|
+
static createAt(t, e, r) {
|
|
970
|
+
return new d(t, Math.max(1, e), Math.max(1, r));
|
|
971
|
+
}
|
|
972
|
+
// ---------------------------------------------------------------------------
|
|
973
|
+
// POSITION
|
|
974
|
+
// ---------------------------------------------------------------------------
|
|
975
|
+
/**
|
|
976
|
+
* Get the current row (1-based).
|
|
977
|
+
*/
|
|
978
|
+
get row() {
|
|
979
|
+
return this._row;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Get the current column (1-based).
|
|
983
|
+
*/
|
|
984
|
+
get col() {
|
|
985
|
+
return this._col;
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Get the current address.
|
|
989
|
+
*/
|
|
990
|
+
get address() {
|
|
991
|
+
return R(this._row, this._col);
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Get the current column letter.
|
|
995
|
+
*/
|
|
996
|
+
get colLetter() {
|
|
997
|
+
return N(this._col);
|
|
998
|
+
}
|
|
999
|
+
/**
|
|
1000
|
+
* Get the current direction.
|
|
1001
|
+
*/
|
|
1002
|
+
get direction() {
|
|
1003
|
+
return this._direction;
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* Get the path for lineage tracking.
|
|
1007
|
+
*/
|
|
1008
|
+
get path() {
|
|
1009
|
+
return {
|
|
1010
|
+
...this.sheet.path,
|
|
1011
|
+
cell: this.address
|
|
1012
|
+
};
|
|
1013
|
+
}
|
|
1014
|
+
// ---------------------------------------------------------------------------
|
|
1015
|
+
// MOVEMENT
|
|
1016
|
+
// ---------------------------------------------------------------------------
|
|
1017
|
+
/**
|
|
1018
|
+
* Move by a delta (returns new cursor).
|
|
1019
|
+
*/
|
|
1020
|
+
move(t, e) {
|
|
1021
|
+
return new d(
|
|
1022
|
+
this.sheet,
|
|
1023
|
+
Math.max(1, this._row + t),
|
|
1024
|
+
Math.max(1, this._col + e),
|
|
1025
|
+
this._direction
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Move to a specific address.
|
|
1030
|
+
*/
|
|
1031
|
+
moveTo(t) {
|
|
1032
|
+
const { row: e, col: r } = p(t);
|
|
1033
|
+
return new d(this.sheet, e, r, this._direction);
|
|
1034
|
+
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Move to a specific row.
|
|
1037
|
+
*/
|
|
1038
|
+
moveToRow(t) {
|
|
1039
|
+
return new d(this.sheet, Math.max(1, t), this._col, this._direction);
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Move to a specific column.
|
|
1043
|
+
*/
|
|
1044
|
+
moveToCol(t) {
|
|
1045
|
+
const e = typeof t == "string" ? T(t.toUpperCase()) : t;
|
|
1046
|
+
return new d(this.sheet, this._row, Math.max(1, e), this._direction);
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Move left by count cells.
|
|
1050
|
+
*/
|
|
1051
|
+
left(t = 1) {
|
|
1052
|
+
return new d(
|
|
1053
|
+
this.sheet,
|
|
1054
|
+
this._row,
|
|
1055
|
+
Math.max(1, this._col - t),
|
|
1056
|
+
"left"
|
|
1057
|
+
);
|
|
1058
|
+
}
|
|
1059
|
+
/**
|
|
1060
|
+
* Move right by count cells.
|
|
1061
|
+
*/
|
|
1062
|
+
right(t = 1) {
|
|
1063
|
+
return new d(this.sheet, this._row, this._col + t, "right");
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Move up by count cells.
|
|
1067
|
+
*/
|
|
1068
|
+
up(t = 1) {
|
|
1069
|
+
return new d(
|
|
1070
|
+
this.sheet,
|
|
1071
|
+
Math.max(1, this._row - t),
|
|
1072
|
+
this._col,
|
|
1073
|
+
"up"
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Move down by count cells.
|
|
1078
|
+
*/
|
|
1079
|
+
down(t = 1) {
|
|
1080
|
+
return new d(this.sheet, this._row + t, this._col, "down");
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Set the current direction.
|
|
1084
|
+
*/
|
|
1085
|
+
setDirection(t) {
|
|
1086
|
+
return new d(this.sheet, this._row, this._col, t);
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Move forward in the current direction.
|
|
1090
|
+
*/
|
|
1091
|
+
forward(t = 1) {
|
|
1092
|
+
switch (this._direction) {
|
|
1093
|
+
case "right":
|
|
1094
|
+
return this.right(t);
|
|
1095
|
+
case "left":
|
|
1096
|
+
return this.left(t);
|
|
1097
|
+
case "down":
|
|
1098
|
+
return this.down(t);
|
|
1099
|
+
case "up":
|
|
1100
|
+
return this.up(t);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Move to the start of the current row.
|
|
1105
|
+
*/
|
|
1106
|
+
startOfRow() {
|
|
1107
|
+
return new d(this.sheet, this._row, 1, this._direction);
|
|
1108
|
+
}
|
|
1109
|
+
/**
|
|
1110
|
+
* Move to the start of the current column.
|
|
1111
|
+
*/
|
|
1112
|
+
startOfCol() {
|
|
1113
|
+
return new d(this.sheet, 1, this._col, this._direction);
|
|
1114
|
+
}
|
|
1115
|
+
// ---------------------------------------------------------------------------
|
|
1116
|
+
// SKIP OPERATIONS
|
|
1117
|
+
// ---------------------------------------------------------------------------
|
|
1118
|
+
/**
|
|
1119
|
+
* Skip empty cells in the current direction.
|
|
1120
|
+
*/
|
|
1121
|
+
skipEmpty() {
|
|
1122
|
+
return this.skipWhile((t) => t.isEmpty());
|
|
1123
|
+
}
|
|
1124
|
+
/**
|
|
1125
|
+
* Skip cells while the predicate is true.
|
|
1126
|
+
*/
|
|
1127
|
+
skipWhile(t) {
|
|
1128
|
+
let e = this;
|
|
1129
|
+
const r = this.sheet.dimensions(), n = Math.max(r.rowCount, r.colCount) * 2;
|
|
1130
|
+
for (let o = 0; o < n; o++) {
|
|
1131
|
+
const i = e.cell();
|
|
1132
|
+
if (!i.ok || !t(i.value)) break;
|
|
1133
|
+
e = e.forward();
|
|
1134
|
+
}
|
|
1135
|
+
return e;
|
|
1136
|
+
}
|
|
1137
|
+
/**
|
|
1138
|
+
* Skip cells until the predicate is true.
|
|
1139
|
+
*/
|
|
1140
|
+
skipUntil(t) {
|
|
1141
|
+
return this.skipWhile((e) => !t(e));
|
|
1142
|
+
}
|
|
1143
|
+
/**
|
|
1144
|
+
* Skip cells until a specific value is found.
|
|
1145
|
+
*/
|
|
1146
|
+
skipToValue(t) {
|
|
1147
|
+
return this.skipUntil((e) => {
|
|
1148
|
+
const r = e.value();
|
|
1149
|
+
return r.ok && r.value === t;
|
|
1150
|
+
});
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Skip a specific number of cells.
|
|
1154
|
+
*/
|
|
1155
|
+
skip(t) {
|
|
1156
|
+
return this.forward(t);
|
|
1157
|
+
}
|
|
1158
|
+
// ---------------------------------------------------------------------------
|
|
1159
|
+
// GRAB OPERATIONS
|
|
1160
|
+
// ---------------------------------------------------------------------------
|
|
1161
|
+
/**
|
|
1162
|
+
* Grab the current cell and move forward.
|
|
1163
|
+
*/
|
|
1164
|
+
grab() {
|
|
1165
|
+
const t = this.cell();
|
|
1166
|
+
return t.ok ? l(
|
|
1167
|
+
{
|
|
1168
|
+
cell: t.value,
|
|
1169
|
+
cursor: this.forward()
|
|
1170
|
+
},
|
|
1171
|
+
this.path
|
|
1172
|
+
) : t;
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* Grab n cells in the current direction.
|
|
1176
|
+
*/
|
|
1177
|
+
grabN(t) {
|
|
1178
|
+
const e = [];
|
|
1179
|
+
let r = this;
|
|
1180
|
+
for (let n = 0; n < t; n++) {
|
|
1181
|
+
const o = r.cell();
|
|
1182
|
+
if (!o.ok)
|
|
1183
|
+
break;
|
|
1184
|
+
e.push(o.value), r = r.forward();
|
|
1185
|
+
}
|
|
1186
|
+
return e.length === 0 ? h("bounds", "No cells to grab", this.path) : l({ cells: e, cursor: r }, this.path);
|
|
1187
|
+
}
|
|
1188
|
+
/**
|
|
1189
|
+
* Grab cells while the predicate is true.
|
|
1190
|
+
*/
|
|
1191
|
+
grabWhile(t) {
|
|
1192
|
+
const e = [];
|
|
1193
|
+
let r = this;
|
|
1194
|
+
const n = this.sheet.dimensions(), o = Math.max(n.rowCount, n.colCount) * 2;
|
|
1195
|
+
for (let i = 0; i < o; i++) {
|
|
1196
|
+
const a = r.cell();
|
|
1197
|
+
if (!a.ok || !t(a.value)) break;
|
|
1198
|
+
e.push(a.value), r = r.forward();
|
|
1199
|
+
}
|
|
1200
|
+
return l({ cells: e, cursor: r }, this.path);
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Grab cells until the predicate is true (not including the matching cell).
|
|
1204
|
+
*/
|
|
1205
|
+
grabUntil(t) {
|
|
1206
|
+
return this.grabWhile((e) => !t(e));
|
|
1207
|
+
}
|
|
1208
|
+
/**
|
|
1209
|
+
* Grab the rest of the current row.
|
|
1210
|
+
*/
|
|
1211
|
+
grabRow() {
|
|
1212
|
+
const t = [], e = this.sheet.dimensions();
|
|
1213
|
+
let r = this.setDirection("right");
|
|
1214
|
+
for (let n = this._col; n <= e.endCol; n++) {
|
|
1215
|
+
const o = r.cell();
|
|
1216
|
+
if (!o.ok) break;
|
|
1217
|
+
t.push(o.value), r = r.forward();
|
|
1218
|
+
}
|
|
1219
|
+
return l({ cells: t, cursor: r }, this.path);
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Grab the rest of the current column.
|
|
1223
|
+
*/
|
|
1224
|
+
grabCol() {
|
|
1225
|
+
const t = [], e = this.sheet.dimensions();
|
|
1226
|
+
let r = this.setDirection("down");
|
|
1227
|
+
for (let n = this._row; n <= e.endRow; n++) {
|
|
1228
|
+
const o = r.cell();
|
|
1229
|
+
if (!o.ok) break;
|
|
1230
|
+
t.push(o.value), r = r.forward();
|
|
1231
|
+
}
|
|
1232
|
+
return l({ cells: t, cursor: r }, this.path);
|
|
1233
|
+
}
|
|
1234
|
+
/**
|
|
1235
|
+
* Grab non-empty cells in the current direction.
|
|
1236
|
+
*/
|
|
1237
|
+
grabNonEmpty() {
|
|
1238
|
+
return this.grabWhile((t) => !t.isEmpty());
|
|
1239
|
+
}
|
|
1240
|
+
// ---------------------------------------------------------------------------
|
|
1241
|
+
// PEEK OPERATIONS
|
|
1242
|
+
// ---------------------------------------------------------------------------
|
|
1243
|
+
/**
|
|
1244
|
+
* Peek at the current cell without moving.
|
|
1245
|
+
*/
|
|
1246
|
+
peek() {
|
|
1247
|
+
return this.cell();
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1250
|
+
* Peek at cells ahead without moving.
|
|
1251
|
+
*/
|
|
1252
|
+
peekAhead(t) {
|
|
1253
|
+
const e = [];
|
|
1254
|
+
let r = this;
|
|
1255
|
+
for (let n = 0; n < t; n++) {
|
|
1256
|
+
const o = r.cell();
|
|
1257
|
+
if (!o.ok) break;
|
|
1258
|
+
e.push(o.value), r = r.forward();
|
|
1259
|
+
}
|
|
1260
|
+
return l(e, this.path);
|
|
1261
|
+
}
|
|
1262
|
+
/**
|
|
1263
|
+
* Peek at a cell at an offset without moving.
|
|
1264
|
+
*/
|
|
1265
|
+
peekAt(t, e) {
|
|
1266
|
+
return this.move(t, e).cell();
|
|
1267
|
+
}
|
|
1268
|
+
// ---------------------------------------------------------------------------
|
|
1269
|
+
// CURRENT CELL
|
|
1270
|
+
// ---------------------------------------------------------------------------
|
|
1271
|
+
/**
|
|
1272
|
+
* Get the cell at the current position.
|
|
1273
|
+
*/
|
|
1274
|
+
cell() {
|
|
1275
|
+
return this.sheet.cellAt(this._row, this._col);
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Get the value of the current cell.
|
|
1279
|
+
*/
|
|
1280
|
+
value() {
|
|
1281
|
+
const t = this.cell();
|
|
1282
|
+
return t.ok ? t.value.value() : t;
|
|
1283
|
+
}
|
|
1284
|
+
// ---------------------------------------------------------------------------
|
|
1285
|
+
// UTILITIES
|
|
1286
|
+
// ---------------------------------------------------------------------------
|
|
1287
|
+
/**
|
|
1288
|
+
* Check if the cursor is at a valid position with data.
|
|
1289
|
+
*/
|
|
1290
|
+
isValid() {
|
|
1291
|
+
return this.cell().ok;
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Check if the current cell is empty.
|
|
1295
|
+
*/
|
|
1296
|
+
isEmpty() {
|
|
1297
|
+
const t = this.cell();
|
|
1298
|
+
return t.ok && t.value.isEmpty();
|
|
1299
|
+
}
|
|
1300
|
+
/**
|
|
1301
|
+
* Check if the current cell is non-empty.
|
|
1302
|
+
*/
|
|
1303
|
+
isNotEmpty() {
|
|
1304
|
+
const t = this.cell();
|
|
1305
|
+
return t.ok && !t.value.isEmpty();
|
|
1306
|
+
}
|
|
1307
|
+
/**
|
|
1308
|
+
* Create a new cursor at the same position.
|
|
1309
|
+
*/
|
|
1310
|
+
clone() {
|
|
1311
|
+
return new d(this.sheet, this._row, this._col, this._direction);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
class k {
|
|
1315
|
+
constructor(t, e, r) {
|
|
1316
|
+
this.worksheet = t, this._path = e, this._file = r;
|
|
1317
|
+
}
|
|
1318
|
+
/**
|
|
1319
|
+
* Creates an XlsxSheet from an ExcelJS worksheet.
|
|
1320
|
+
* @internal
|
|
1321
|
+
*/
|
|
1322
|
+
static fromExcelJS(t, e) {
|
|
1323
|
+
const r = {
|
|
1324
|
+
file: e,
|
|
1325
|
+
sheet: t.name
|
|
1326
|
+
};
|
|
1327
|
+
return new k(t, r, e);
|
|
1328
|
+
}
|
|
1329
|
+
// ---------------------------------------------------------------------------
|
|
1330
|
+
// IDENTITY
|
|
1331
|
+
// ---------------------------------------------------------------------------
|
|
1332
|
+
/**
|
|
1333
|
+
* Returns the sheet name.
|
|
1334
|
+
*/
|
|
1335
|
+
get name() {
|
|
1336
|
+
return this.worksheet.name;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Returns the sheet index (1-based).
|
|
1340
|
+
*/
|
|
1341
|
+
get index() {
|
|
1342
|
+
return this.worksheet.id;
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* Returns the current path for lineage tracking.
|
|
1346
|
+
*/
|
|
1347
|
+
get path() {
|
|
1348
|
+
return this._path;
|
|
1349
|
+
}
|
|
1350
|
+
// ---------------------------------------------------------------------------
|
|
1351
|
+
// CELL ACCESS
|
|
1352
|
+
// ---------------------------------------------------------------------------
|
|
1353
|
+
/**
|
|
1354
|
+
* Get a cell by its address (e.g., "A1", "B2").
|
|
1355
|
+
*/
|
|
1356
|
+
cell(t) {
|
|
1357
|
+
try {
|
|
1358
|
+
p(t);
|
|
1359
|
+
const e = this.worksheet.getCell(t);
|
|
1360
|
+
return l(w.fromExcelJS(e, this.name, this._file), {
|
|
1361
|
+
...this._path,
|
|
1362
|
+
cell: t
|
|
1363
|
+
});
|
|
1364
|
+
} catch {
|
|
1365
|
+
return h("range", `Invalid cell address: ${t}`, this._path);
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
/**
|
|
1369
|
+
* Get a cell by row and column numbers (1-based).
|
|
1370
|
+
*/
|
|
1371
|
+
cellAt(t, e) {
|
|
1372
|
+
if (t < 1 || e < 1)
|
|
1373
|
+
return h(
|
|
1374
|
+
"bounds",
|
|
1375
|
+
`Invalid cell coordinates: row=${t}, col=${e}`,
|
|
1376
|
+
this._path
|
|
1377
|
+
);
|
|
1378
|
+
const r = this.worksheet.getCell(t, e);
|
|
1379
|
+
return l(w.fromExcelJS(r, this.name, this._file), {
|
|
1380
|
+
...this._path,
|
|
1381
|
+
cell: r.address
|
|
1382
|
+
});
|
|
1383
|
+
}
|
|
1384
|
+
/**
|
|
1385
|
+
* Get the value of a cell directly.
|
|
1386
|
+
*/
|
|
1387
|
+
getValue(t) {
|
|
1388
|
+
const e = this.cell(t);
|
|
1389
|
+
return e.ok ? e.value.value() : e;
|
|
1390
|
+
}
|
|
1391
|
+
// ---------------------------------------------------------------------------
|
|
1392
|
+
// RANGE OPERATIONS
|
|
1393
|
+
// ---------------------------------------------------------------------------
|
|
1394
|
+
/**
|
|
1395
|
+
* Get a range by its address (e.g., "A1:C10").
|
|
1396
|
+
*/
|
|
1397
|
+
range(t) {
|
|
1398
|
+
return m.fromAddress(this.worksheet, t, this.name, this._file);
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Get a range from start to end addresses.
|
|
1402
|
+
*/
|
|
1403
|
+
rangeFrom(t, e) {
|
|
1404
|
+
return this.range(`${t}:${e}`);
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Get a range by coordinates (1-based).
|
|
1408
|
+
*/
|
|
1409
|
+
rangeAt(t, e, r, n) {
|
|
1410
|
+
return t < 1 || e < 1 || r < 1 || n < 1 ? h("bounds", "Invalid range coordinates", this._path) : l(
|
|
1411
|
+
m.fromCoords(
|
|
1412
|
+
this.worksheet,
|
|
1413
|
+
t,
|
|
1414
|
+
e,
|
|
1415
|
+
r,
|
|
1416
|
+
n,
|
|
1417
|
+
this.name,
|
|
1418
|
+
this._file
|
|
1419
|
+
),
|
|
1420
|
+
this._path
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* Get the used range of the sheet (cells with data).
|
|
1425
|
+
*/
|
|
1426
|
+
usedRange() {
|
|
1427
|
+
const t = this.dimensions();
|
|
1428
|
+
return t.rowCount === 0 || t.colCount === 0 ? h("missing", "Sheet has no used cells", this._path) : l(
|
|
1429
|
+
m.fromCoords(
|
|
1430
|
+
this.worksheet,
|
|
1431
|
+
t.startRow,
|
|
1432
|
+
t.startCol,
|
|
1433
|
+
t.endRow,
|
|
1434
|
+
t.endCol,
|
|
1435
|
+
this.name,
|
|
1436
|
+
this._file
|
|
1437
|
+
),
|
|
1438
|
+
this._path
|
|
1439
|
+
);
|
|
1440
|
+
}
|
|
1441
|
+
// ---------------------------------------------------------------------------
|
|
1442
|
+
// ROW / COLUMN ACCESS
|
|
1443
|
+
// ---------------------------------------------------------------------------
|
|
1444
|
+
/**
|
|
1445
|
+
* Get a row as a range.
|
|
1446
|
+
*/
|
|
1447
|
+
row(t) {
|
|
1448
|
+
const e = this.dimensions();
|
|
1449
|
+
if (t < 1)
|
|
1450
|
+
return h("bounds", `Invalid row number: ${t}`, this._path);
|
|
1451
|
+
const r = Math.max(e.endCol, 1);
|
|
1452
|
+
return l(
|
|
1453
|
+
m.fromCoords(
|
|
1454
|
+
this.worksheet,
|
|
1455
|
+
t,
|
|
1456
|
+
1,
|
|
1457
|
+
t,
|
|
1458
|
+
r,
|
|
1459
|
+
this.name,
|
|
1460
|
+
this._file
|
|
1461
|
+
),
|
|
1462
|
+
this._path
|
|
1463
|
+
);
|
|
1464
|
+
}
|
|
1465
|
+
/**
|
|
1466
|
+
* Get a column as a range.
|
|
1467
|
+
*/
|
|
1468
|
+
col(t) {
|
|
1469
|
+
const e = typeof t == "string" ? T(t.toUpperCase()) : t;
|
|
1470
|
+
if (e < 1)
|
|
1471
|
+
return h("bounds", `Invalid column: ${t}`, this._path);
|
|
1472
|
+
const r = this.dimensions(), n = Math.max(r.endRow, 1);
|
|
1473
|
+
return l(
|
|
1474
|
+
m.fromCoords(
|
|
1475
|
+
this.worksheet,
|
|
1476
|
+
1,
|
|
1477
|
+
e,
|
|
1478
|
+
n,
|
|
1479
|
+
e,
|
|
1480
|
+
this.name,
|
|
1481
|
+
this._file
|
|
1482
|
+
),
|
|
1483
|
+
this._path
|
|
1484
|
+
);
|
|
1485
|
+
}
|
|
1486
|
+
/**
|
|
1487
|
+
* Iterate over all rows with data.
|
|
1488
|
+
*/
|
|
1489
|
+
*rows() {
|
|
1490
|
+
const t = this.dimensions();
|
|
1491
|
+
for (let e = t.startRow; e <= t.endRow; e++)
|
|
1492
|
+
yield m.fromCoords(
|
|
1493
|
+
this.worksheet,
|
|
1494
|
+
e,
|
|
1495
|
+
t.startCol,
|
|
1496
|
+
e,
|
|
1497
|
+
t.endCol,
|
|
1498
|
+
this.name,
|
|
1499
|
+
this._file
|
|
1500
|
+
);
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* Iterate over all columns with data.
|
|
1504
|
+
*/
|
|
1505
|
+
*cols() {
|
|
1506
|
+
const t = this.dimensions();
|
|
1507
|
+
for (let e = t.startCol; e <= t.endCol; e++)
|
|
1508
|
+
yield m.fromCoords(
|
|
1509
|
+
this.worksheet,
|
|
1510
|
+
t.startRow,
|
|
1511
|
+
e,
|
|
1512
|
+
t.endRow,
|
|
1513
|
+
e,
|
|
1514
|
+
this.name,
|
|
1515
|
+
this._file
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
// ---------------------------------------------------------------------------
|
|
1519
|
+
// CURSOR CREATION
|
|
1520
|
+
// ---------------------------------------------------------------------------
|
|
1521
|
+
/**
|
|
1522
|
+
* Create a cursor starting at the specified address.
|
|
1523
|
+
*/
|
|
1524
|
+
cursor(t) {
|
|
1525
|
+
const e = t ?? "A1";
|
|
1526
|
+
return d.create(this, e);
|
|
1527
|
+
}
|
|
1528
|
+
/**
|
|
1529
|
+
* Create a cursor starting at the specified coordinates (1-based).
|
|
1530
|
+
*/
|
|
1531
|
+
cursorAt(t, e) {
|
|
1532
|
+
return d.createAt(this, t, e);
|
|
1533
|
+
}
|
|
1534
|
+
// ---------------------------------------------------------------------------
|
|
1535
|
+
// QUERY METHODS
|
|
1536
|
+
// ---------------------------------------------------------------------------
|
|
1537
|
+
/**
|
|
1538
|
+
* Find the first cell matching the predicate.
|
|
1539
|
+
*/
|
|
1540
|
+
find(t) {
|
|
1541
|
+
const e = this.usedRange();
|
|
1542
|
+
return e.ok ? e.value.find(t) : e;
|
|
1543
|
+
}
|
|
1544
|
+
/**
|
|
1545
|
+
* Find all cells matching the predicate.
|
|
1546
|
+
*/
|
|
1547
|
+
findAll(t) {
|
|
1548
|
+
const e = this.usedRange();
|
|
1549
|
+
return e.ok ? e.value.findAll(t) : [];
|
|
1550
|
+
}
|
|
1551
|
+
/**
|
|
1552
|
+
* Find the first cell with the specified value.
|
|
1553
|
+
*/
|
|
1554
|
+
findValue(t) {
|
|
1555
|
+
const e = this.usedRange();
|
|
1556
|
+
return e.ok ? e.value.findValue(t) : e;
|
|
1557
|
+
}
|
|
1558
|
+
/**
|
|
1559
|
+
* Find cells within a specific range matching the predicate.
|
|
1560
|
+
*/
|
|
1561
|
+
findInRange(t, e) {
|
|
1562
|
+
const r = this.range(t);
|
|
1563
|
+
return r.ok ? r.value.find(e) : r;
|
|
1564
|
+
}
|
|
1565
|
+
/**
|
|
1566
|
+
* Find all cells within a specific range matching the predicate.
|
|
1567
|
+
*/
|
|
1568
|
+
findAllInRange(t, e) {
|
|
1569
|
+
const r = this.range(t);
|
|
1570
|
+
return r.ok ? r.value.findAll(e) : [];
|
|
1571
|
+
}
|
|
1572
|
+
// ---------------------------------------------------------------------------
|
|
1573
|
+
// DIMENSIONS
|
|
1574
|
+
// ---------------------------------------------------------------------------
|
|
1575
|
+
/**
|
|
1576
|
+
* Get the dimensions of the used area.
|
|
1577
|
+
*/
|
|
1578
|
+
dimensions() {
|
|
1579
|
+
const t = this.worksheet.rowCount, e = this.worksheet.columnCount;
|
|
1580
|
+
let r = 1, n = t, o = 1, i = e;
|
|
1581
|
+
if (this.worksheet.dimensions) {
|
|
1582
|
+
const a = this.worksheet.dimensions;
|
|
1583
|
+
if (typeof a == "string")
|
|
1584
|
+
try {
|
|
1585
|
+
const u = y(a);
|
|
1586
|
+
r = u.start.row, o = u.start.col, n = u.end.row, i = u.end.col;
|
|
1587
|
+
} catch {
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
return {
|
|
1591
|
+
startRow: r,
|
|
1592
|
+
endRow: n,
|
|
1593
|
+
startCol: o,
|
|
1594
|
+
endCol: i,
|
|
1595
|
+
rowCount: n - r + 1,
|
|
1596
|
+
colCount: i - o + 1
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
/**
|
|
1600
|
+
* Get the number of rows with data.
|
|
1601
|
+
*/
|
|
1602
|
+
rowCount() {
|
|
1603
|
+
return this.dimensions().rowCount;
|
|
1604
|
+
}
|
|
1605
|
+
/**
|
|
1606
|
+
* Get the number of columns with data.
|
|
1607
|
+
*/
|
|
1608
|
+
colCount() {
|
|
1609
|
+
return this.dimensions().colCount;
|
|
1610
|
+
}
|
|
1611
|
+
// ---------------------------------------------------------------------------
|
|
1612
|
+
// MERGED CELLS
|
|
1613
|
+
// ---------------------------------------------------------------------------
|
|
1614
|
+
/**
|
|
1615
|
+
* Get all merged cell ranges.
|
|
1616
|
+
*/
|
|
1617
|
+
mergedRanges() {
|
|
1618
|
+
const t = this.worksheet._merges;
|
|
1619
|
+
return t ? Object.keys(t) : [];
|
|
1620
|
+
}
|
|
1621
|
+
/**
|
|
1622
|
+
* Check if a cell is part of a merged range.
|
|
1623
|
+
*/
|
|
1624
|
+
isMerged(t) {
|
|
1625
|
+
const e = this.cell(t);
|
|
1626
|
+
return e.ok ? e.value.isMerged() : !1;
|
|
1627
|
+
}
|
|
1628
|
+
// ---------------------------------------------------------------------------
|
|
1629
|
+
// INTERNAL HELPERS
|
|
1630
|
+
// ---------------------------------------------------------------------------
|
|
1631
|
+
/**
|
|
1632
|
+
* Get the underlying ExcelJS worksheet.
|
|
1633
|
+
* @internal
|
|
1634
|
+
*/
|
|
1635
|
+
getWorksheet() {
|
|
1636
|
+
return this.worksheet;
|
|
1637
|
+
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Get a cell by coordinates for internal use.
|
|
1640
|
+
* @internal
|
|
1641
|
+
*/
|
|
1642
|
+
getCellInternal(t, e) {
|
|
1643
|
+
if (t < 1 || e < 1) return;
|
|
1644
|
+
const r = this.worksheet.getCell(t, e);
|
|
1645
|
+
return w.fromExcelJS(r, this.name, this._file);
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
class v {
|
|
1649
|
+
constructor(t, e) {
|
|
1650
|
+
this.workbook = t, this._path = e, this.sheetsCache = /* @__PURE__ */ new Map();
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Creates an XlsxWorkbook from an ExcelJS workbook.
|
|
1654
|
+
* @internal
|
|
1655
|
+
*/
|
|
1656
|
+
static fromExcelJS(t, e) {
|
|
1657
|
+
const r = { file: e };
|
|
1658
|
+
return new v(t, r);
|
|
1659
|
+
}
|
|
1660
|
+
// ---------------------------------------------------------------------------
|
|
1661
|
+
// IDENTITY
|
|
1662
|
+
// ---------------------------------------------------------------------------
|
|
1663
|
+
/**
|
|
1664
|
+
* Returns the path for lineage tracking.
|
|
1665
|
+
*/
|
|
1666
|
+
get path() {
|
|
1667
|
+
return this._path;
|
|
1668
|
+
}
|
|
1669
|
+
/**
|
|
1670
|
+
* Returns the file name if known.
|
|
1671
|
+
*/
|
|
1672
|
+
get file() {
|
|
1673
|
+
return this._path.file;
|
|
1674
|
+
}
|
|
1675
|
+
// ---------------------------------------------------------------------------
|
|
1676
|
+
// SHEET ACCESS
|
|
1677
|
+
// ---------------------------------------------------------------------------
|
|
1678
|
+
/**
|
|
1679
|
+
* Get a sheet by name.
|
|
1680
|
+
*/
|
|
1681
|
+
sheet(t) {
|
|
1682
|
+
const e = this.sheetsCache.get(t);
|
|
1683
|
+
if (e)
|
|
1684
|
+
return l(e, { ...this._path, sheet: t });
|
|
1685
|
+
const r = this.workbook.getWorksheet(t);
|
|
1686
|
+
if (!r)
|
|
1687
|
+
return h(
|
|
1688
|
+
"missing",
|
|
1689
|
+
`Sheet "${t}" not found`,
|
|
1690
|
+
this._path
|
|
1691
|
+
);
|
|
1692
|
+
const n = k.fromExcelJS(r, this._path.file);
|
|
1693
|
+
return this.sheetsCache.set(t, n), l(n, n.path);
|
|
1694
|
+
}
|
|
1695
|
+
/**
|
|
1696
|
+
* Get a sheet by index (1-based, as per Excel convention).
|
|
1697
|
+
*/
|
|
1698
|
+
sheetAt(t) {
|
|
1699
|
+
if (t < 1)
|
|
1700
|
+
return h(
|
|
1701
|
+
"bounds",
|
|
1702
|
+
`Sheet index must be >= 1, got ${t}`,
|
|
1703
|
+
this._path
|
|
1704
|
+
);
|
|
1705
|
+
const e = this.workbook.getWorksheet(t);
|
|
1706
|
+
if (!e)
|
|
1707
|
+
return h(
|
|
1708
|
+
"missing",
|
|
1709
|
+
`Sheet at index ${t} not found`,
|
|
1710
|
+
this._path
|
|
1711
|
+
);
|
|
1712
|
+
const r = this.sheetsCache.get(e.name);
|
|
1713
|
+
if (r)
|
|
1714
|
+
return l(r, r.path);
|
|
1715
|
+
const n = k.fromExcelJS(e, this._path.file);
|
|
1716
|
+
return this.sheetsCache.set(e.name, n), l(n, n.path);
|
|
1717
|
+
}
|
|
1718
|
+
/**
|
|
1719
|
+
* Get all sheets.
|
|
1720
|
+
*/
|
|
1721
|
+
sheets() {
|
|
1722
|
+
const t = [];
|
|
1723
|
+
return this.workbook.eachSheet((e) => {
|
|
1724
|
+
const r = this.sheetsCache.get(e.name);
|
|
1725
|
+
if (r)
|
|
1726
|
+
t.push(r);
|
|
1727
|
+
else {
|
|
1728
|
+
const n = k.fromExcelJS(e, this._path.file);
|
|
1729
|
+
this.sheetsCache.set(e.name, n), t.push(n);
|
|
1730
|
+
}
|
|
1731
|
+
}), t;
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* Get all sheet names.
|
|
1735
|
+
*/
|
|
1736
|
+
sheetNames() {
|
|
1737
|
+
const t = [];
|
|
1738
|
+
return this.workbook.eachSheet((e) => {
|
|
1739
|
+
t.push(e.name);
|
|
1740
|
+
}), t;
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Get the number of sheets.
|
|
1744
|
+
*/
|
|
1745
|
+
sheetCount() {
|
|
1746
|
+
return this.workbook.worksheets.length;
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* Get the first sheet.
|
|
1750
|
+
*/
|
|
1751
|
+
firstSheet() {
|
|
1752
|
+
return this.sheetAt(1);
|
|
1753
|
+
}
|
|
1754
|
+
/**
|
|
1755
|
+
* Get the last sheet.
|
|
1756
|
+
*/
|
|
1757
|
+
lastSheet() {
|
|
1758
|
+
const t = this.sheetCount();
|
|
1759
|
+
return t === 0 ? h("missing", "Workbook has no sheets", this._path) : this.sheetAt(t);
|
|
1760
|
+
}
|
|
1761
|
+
// ---------------------------------------------------------------------------
|
|
1762
|
+
// PREDICATES
|
|
1763
|
+
// ---------------------------------------------------------------------------
|
|
1764
|
+
/**
|
|
1765
|
+
* Check if a sheet with the given name exists.
|
|
1766
|
+
*/
|
|
1767
|
+
hasSheet(t) {
|
|
1768
|
+
return this.workbook.getWorksheet(t) !== void 0;
|
|
1769
|
+
}
|
|
1770
|
+
/**
|
|
1771
|
+
* Find the first sheet matching the predicate.
|
|
1772
|
+
*/
|
|
1773
|
+
findSheet(t) {
|
|
1774
|
+
for (const e of this.sheets())
|
|
1775
|
+
if (t(e))
|
|
1776
|
+
return l(e, e.path);
|
|
1777
|
+
return h(
|
|
1778
|
+
"missing",
|
|
1779
|
+
"No sheet matching predicate found",
|
|
1780
|
+
this._path
|
|
1781
|
+
);
|
|
1782
|
+
}
|
|
1783
|
+
/**
|
|
1784
|
+
* Find all sheets matching the predicate.
|
|
1785
|
+
*/
|
|
1786
|
+
filterSheets(t) {
|
|
1787
|
+
return this.sheets().filter(t);
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Find a sheet by name pattern (regex).
|
|
1791
|
+
*/
|
|
1792
|
+
findSheetByPattern(t) {
|
|
1793
|
+
return this.findSheet((e) => t.test(e.name));
|
|
1794
|
+
}
|
|
1795
|
+
/**
|
|
1796
|
+
* Find all sheets by name pattern (regex).
|
|
1797
|
+
*/
|
|
1798
|
+
filterSheetsByPattern(t) {
|
|
1799
|
+
return this.filterSheets((e) => t.test(e.name));
|
|
1800
|
+
}
|
|
1801
|
+
// ---------------------------------------------------------------------------
|
|
1802
|
+
// WORKBOOK PROPERTIES
|
|
1803
|
+
// ---------------------------------------------------------------------------
|
|
1804
|
+
/**
|
|
1805
|
+
* Get workbook properties.
|
|
1806
|
+
*/
|
|
1807
|
+
properties() {
|
|
1808
|
+
return {
|
|
1809
|
+
title: this.workbook.title,
|
|
1810
|
+
subject: this.workbook.subject,
|
|
1811
|
+
creator: this.workbook.creator,
|
|
1812
|
+
lastModifiedBy: this.workbook.lastModifiedBy,
|
|
1813
|
+
created: this.workbook.created,
|
|
1814
|
+
modified: this.workbook.modified
|
|
1815
|
+
};
|
|
1816
|
+
}
|
|
1817
|
+
/**
|
|
1818
|
+
* Get the workbook creator.
|
|
1819
|
+
*/
|
|
1820
|
+
creator() {
|
|
1821
|
+
return this.workbook.creator;
|
|
1822
|
+
}
|
|
1823
|
+
/**
|
|
1824
|
+
* Get the workbook creation date.
|
|
1825
|
+
*/
|
|
1826
|
+
created() {
|
|
1827
|
+
return this.workbook.created;
|
|
1828
|
+
}
|
|
1829
|
+
/**
|
|
1830
|
+
* Get the workbook modification date.
|
|
1831
|
+
*/
|
|
1832
|
+
modified() {
|
|
1833
|
+
return this.workbook.modified;
|
|
1834
|
+
}
|
|
1835
|
+
// ---------------------------------------------------------------------------
|
|
1836
|
+
// DEFINED NAMES
|
|
1837
|
+
// ---------------------------------------------------------------------------
|
|
1838
|
+
/**
|
|
1839
|
+
* Get all defined names in the workbook.
|
|
1840
|
+
*/
|
|
1841
|
+
definedNames() {
|
|
1842
|
+
return [];
|
|
1843
|
+
}
|
|
1844
|
+
// ---------------------------------------------------------------------------
|
|
1845
|
+
// ITERATION
|
|
1846
|
+
// ---------------------------------------------------------------------------
|
|
1847
|
+
/**
|
|
1848
|
+
* Iterate over all sheets.
|
|
1849
|
+
*/
|
|
1850
|
+
*[Symbol.iterator]() {
|
|
1851
|
+
for (const t of this.sheets())
|
|
1852
|
+
yield t;
|
|
1853
|
+
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Execute a function for each sheet.
|
|
1856
|
+
*/
|
|
1857
|
+
forEach(t) {
|
|
1858
|
+
this.sheets().forEach(t);
|
|
1859
|
+
}
|
|
1860
|
+
/**
|
|
1861
|
+
* Map over all sheets.
|
|
1862
|
+
*/
|
|
1863
|
+
map(t) {
|
|
1864
|
+
return this.sheets().map(t);
|
|
1865
|
+
}
|
|
1866
|
+
// ---------------------------------------------------------------------------
|
|
1867
|
+
// INTERNAL
|
|
1868
|
+
// ---------------------------------------------------------------------------
|
|
1869
|
+
/**
|
|
1870
|
+
* Get the underlying ExcelJS workbook.
|
|
1871
|
+
* @internal
|
|
1872
|
+
*/
|
|
1873
|
+
getWorkbook() {
|
|
1874
|
+
return this.workbook;
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
const q = {
|
|
1878
|
+
// ---------------------------------------------------------------------------
|
|
1879
|
+
// VALUE PREDICATES
|
|
1880
|
+
// ---------------------------------------------------------------------------
|
|
1881
|
+
/**
|
|
1882
|
+
* Match cells with the exact value.
|
|
1883
|
+
*/
|
|
1884
|
+
equals: (s) => (t) => {
|
|
1885
|
+
const e = t.value();
|
|
1886
|
+
return e.ok ? s === null ? e.value === null : e.value === null ? !1 : s instanceof Date && e.value instanceof Date ? s.getTime() === e.value.getTime() : e.value === s : !1;
|
|
1887
|
+
},
|
|
1888
|
+
/**
|
|
1889
|
+
* Match cells containing the specified text (case-insensitive by default).
|
|
1890
|
+
*/
|
|
1891
|
+
contains: (s, t = !1) => (e) => {
|
|
1892
|
+
const r = e.string();
|
|
1893
|
+
return r.ok ? t ? r.value.includes(s) : r.value.toLowerCase().includes(s.toLowerCase()) : !1;
|
|
1894
|
+
},
|
|
1895
|
+
/**
|
|
1896
|
+
* Match cells whose value matches the regex pattern.
|
|
1897
|
+
*/
|
|
1898
|
+
matches: (s) => (t) => {
|
|
1899
|
+
const e = t.string();
|
|
1900
|
+
return e.ok ? s.test(e.value) : !1;
|
|
1901
|
+
},
|
|
1902
|
+
/**
|
|
1903
|
+
* Match cells whose string value starts with the prefix.
|
|
1904
|
+
*/
|
|
1905
|
+
startsWith: (s, t = !1) => (e) => {
|
|
1906
|
+
const r = e.string();
|
|
1907
|
+
return r.ok ? t ? r.value.startsWith(s) : r.value.toLowerCase().startsWith(s.toLowerCase()) : !1;
|
|
1908
|
+
},
|
|
1909
|
+
/**
|
|
1910
|
+
* Match cells whose string value ends with the suffix.
|
|
1911
|
+
*/
|
|
1912
|
+
endsWith: (s, t = !1) => (e) => {
|
|
1913
|
+
const r = e.string();
|
|
1914
|
+
return r.ok ? t ? r.value.endsWith(s) : r.value.toLowerCase().endsWith(s.toLowerCase()) : !1;
|
|
1915
|
+
},
|
|
1916
|
+
// ---------------------------------------------------------------------------
|
|
1917
|
+
// TYPE PREDICATES
|
|
1918
|
+
// ---------------------------------------------------------------------------
|
|
1919
|
+
/**
|
|
1920
|
+
* Match cells containing a string value.
|
|
1921
|
+
*/
|
|
1922
|
+
isString: () => (s) => s.isString(),
|
|
1923
|
+
/**
|
|
1924
|
+
* Match cells containing a numeric value.
|
|
1925
|
+
*/
|
|
1926
|
+
isNumber: () => (s) => s.isNumber(),
|
|
1927
|
+
/**
|
|
1928
|
+
* Match cells containing a boolean value.
|
|
1929
|
+
*/
|
|
1930
|
+
isBoolean: () => (s) => s.isBoolean(),
|
|
1931
|
+
/**
|
|
1932
|
+
* Match cells containing a date value.
|
|
1933
|
+
*/
|
|
1934
|
+
isDate: () => (s) => s.isDate(),
|
|
1935
|
+
/**
|
|
1936
|
+
* Match empty cells.
|
|
1937
|
+
*/
|
|
1938
|
+
isEmpty: () => (s) => s.isEmpty(),
|
|
1939
|
+
/**
|
|
1940
|
+
* Match non-empty cells.
|
|
1941
|
+
*/
|
|
1942
|
+
isNotEmpty: () => (s) => !s.isEmpty(),
|
|
1943
|
+
/**
|
|
1944
|
+
* Match cells containing a formula.
|
|
1945
|
+
*/
|
|
1946
|
+
isFormula: () => (s) => s.isFormula(),
|
|
1947
|
+
/**
|
|
1948
|
+
* Match cells containing an error.
|
|
1949
|
+
*/
|
|
1950
|
+
isError: () => (s) => s.isError(),
|
|
1951
|
+
/**
|
|
1952
|
+
* Match merged cells.
|
|
1953
|
+
*/
|
|
1954
|
+
isMerged: () => (s) => s.isMerged(),
|
|
1955
|
+
// ---------------------------------------------------------------------------
|
|
1956
|
+
// NUMERIC PREDICATES
|
|
1957
|
+
// ---------------------------------------------------------------------------
|
|
1958
|
+
/**
|
|
1959
|
+
* Match cells with numeric value greater than n.
|
|
1960
|
+
*/
|
|
1961
|
+
greaterThan: (s) => (t) => {
|
|
1962
|
+
const e = t.number();
|
|
1963
|
+
return e.ok && e.value > s;
|
|
1964
|
+
},
|
|
1965
|
+
/**
|
|
1966
|
+
* Match cells with numeric value greater than or equal to n.
|
|
1967
|
+
*/
|
|
1968
|
+
greaterThanOrEqual: (s) => (t) => {
|
|
1969
|
+
const e = t.number();
|
|
1970
|
+
return e.ok && e.value >= s;
|
|
1971
|
+
},
|
|
1972
|
+
/**
|
|
1973
|
+
* Match cells with numeric value less than n.
|
|
1974
|
+
*/
|
|
1975
|
+
lessThan: (s) => (t) => {
|
|
1976
|
+
const e = t.number();
|
|
1977
|
+
return e.ok && e.value < s;
|
|
1978
|
+
},
|
|
1979
|
+
/**
|
|
1980
|
+
* Match cells with numeric value less than or equal to n.
|
|
1981
|
+
*/
|
|
1982
|
+
lessThanOrEqual: (s) => (t) => {
|
|
1983
|
+
const e = t.number();
|
|
1984
|
+
return e.ok && e.value <= s;
|
|
1985
|
+
},
|
|
1986
|
+
/**
|
|
1987
|
+
* Match cells with numeric value between min and max (inclusive).
|
|
1988
|
+
*/
|
|
1989
|
+
between: (s, t) => (e) => {
|
|
1990
|
+
const r = e.number();
|
|
1991
|
+
return r.ok && r.value >= s && r.value <= t;
|
|
1992
|
+
},
|
|
1993
|
+
// ---------------------------------------------------------------------------
|
|
1994
|
+
// DATE PREDICATES
|
|
1995
|
+
// ---------------------------------------------------------------------------
|
|
1996
|
+
/**
|
|
1997
|
+
* Match cells with date before the specified date.
|
|
1998
|
+
*/
|
|
1999
|
+
dateBefore: (s) => (t) => {
|
|
2000
|
+
const e = t.date();
|
|
2001
|
+
return e.ok && e.value.getTime() < s.getTime();
|
|
2002
|
+
},
|
|
2003
|
+
/**
|
|
2004
|
+
* Match cells with date after the specified date.
|
|
2005
|
+
*/
|
|
2006
|
+
dateAfter: (s) => (t) => {
|
|
2007
|
+
const e = t.date();
|
|
2008
|
+
return e.ok && e.value.getTime() > s.getTime();
|
|
2009
|
+
},
|
|
2010
|
+
/**
|
|
2011
|
+
* Match cells with date between start and end (inclusive).
|
|
2012
|
+
*/
|
|
2013
|
+
dateBetween: (s, t) => (e) => {
|
|
2014
|
+
const r = e.date();
|
|
2015
|
+
if (!r.ok) return !1;
|
|
2016
|
+
const n = r.value.getTime();
|
|
2017
|
+
return n >= s.getTime() && n <= t.getTime();
|
|
2018
|
+
},
|
|
2019
|
+
// ---------------------------------------------------------------------------
|
|
2020
|
+
// LOCATION PREDICATES
|
|
2021
|
+
// ---------------------------------------------------------------------------
|
|
2022
|
+
/**
|
|
2023
|
+
* Match cells in the specified row.
|
|
2024
|
+
*/
|
|
2025
|
+
inRow: (s) => (t) => t.row === s,
|
|
2026
|
+
/**
|
|
2027
|
+
* Match cells in the specified column.
|
|
2028
|
+
*/
|
|
2029
|
+
inCol: (s) => (t) => t.col === s,
|
|
2030
|
+
/**
|
|
2031
|
+
* Match cells in the specified column (by letter).
|
|
2032
|
+
*/
|
|
2033
|
+
inColLetter: (s) => (t) => t.colLetter.toUpperCase() === s.toUpperCase(),
|
|
2034
|
+
// ---------------------------------------------------------------------------
|
|
2035
|
+
// COMPOSITION
|
|
2036
|
+
// ---------------------------------------------------------------------------
|
|
2037
|
+
/**
|
|
2038
|
+
* Match cells that satisfy all predicates.
|
|
2039
|
+
*/
|
|
2040
|
+
and: (...s) => (t) => s.every((e) => e(t)),
|
|
2041
|
+
/**
|
|
2042
|
+
* Match cells that satisfy at least one predicate.
|
|
2043
|
+
*/
|
|
2044
|
+
or: (...s) => (t) => s.some((e) => e(t)),
|
|
2045
|
+
/**
|
|
2046
|
+
* Match cells that do not satisfy the predicate.
|
|
2047
|
+
*/
|
|
2048
|
+
not: (s) => (t) => !s(t),
|
|
2049
|
+
// ---------------------------------------------------------------------------
|
|
2050
|
+
// STYLE PREDICATES
|
|
2051
|
+
// ---------------------------------------------------------------------------
|
|
2052
|
+
/**
|
|
2053
|
+
* Match cells with bold font.
|
|
2054
|
+
*/
|
|
2055
|
+
isBold: () => (s) => s.style().font?.bold === !0,
|
|
2056
|
+
/**
|
|
2057
|
+
* Match cells with italic font.
|
|
2058
|
+
*/
|
|
2059
|
+
isItalic: () => (s) => s.style().font?.italic === !0,
|
|
2060
|
+
/**
|
|
2061
|
+
* Match cells with a hyperlink.
|
|
2062
|
+
*/
|
|
2063
|
+
hasHyperlink: () => (s) => s.hyperlink().ok,
|
|
2064
|
+
/**
|
|
2065
|
+
* Match cells with a comment.
|
|
2066
|
+
*/
|
|
2067
|
+
hasComment: () => (s) => s.comment().ok,
|
|
2068
|
+
// ---------------------------------------------------------------------------
|
|
2069
|
+
// UTILITY
|
|
2070
|
+
// ---------------------------------------------------------------------------
|
|
2071
|
+
/**
|
|
2072
|
+
* Always match.
|
|
2073
|
+
*/
|
|
2074
|
+
always: () => () => !0,
|
|
2075
|
+
/**
|
|
2076
|
+
* Never match.
|
|
2077
|
+
*/
|
|
2078
|
+
never: () => () => !1,
|
|
2079
|
+
/**
|
|
2080
|
+
* Create a custom predicate from a function.
|
|
2081
|
+
*/
|
|
2082
|
+
custom: (s) => s
|
|
2083
|
+
};
|
|
2084
|
+
function H(s) {
|
|
2085
|
+
return {
|
|
2086
|
+
kind: "transform",
|
|
2087
|
+
namespace: "@origints/xlsx",
|
|
2088
|
+
name: "parseXlsx",
|
|
2089
|
+
args: s
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2092
|
+
const P = {
|
|
2093
|
+
namespace: "@origints/xlsx",
|
|
2094
|
+
name: "parseXlsx",
|
|
2095
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2096
|
+
execute(s, t) {
|
|
2097
|
+
throw new Error(
|
|
2098
|
+
"parseXlsx requires async execution. Use parseXlsxAsyncImpl instead."
|
|
2099
|
+
);
|
|
2100
|
+
}
|
|
2101
|
+
};
|
|
2102
|
+
function C(s) {
|
|
2103
|
+
return new Uint8Array(s).buffer;
|
|
2104
|
+
}
|
|
2105
|
+
const I = {
|
|
2106
|
+
namespace: "@origints/xlsx",
|
|
2107
|
+
name: "parseXlsx",
|
|
2108
|
+
async execute(s, t) {
|
|
2109
|
+
const e = t ?? {};
|
|
2110
|
+
let r;
|
|
2111
|
+
if (s instanceof ReadableStream) {
|
|
2112
|
+
const o = await M(s);
|
|
2113
|
+
r = C(o);
|
|
2114
|
+
} else if (Buffer.isBuffer(s))
|
|
2115
|
+
r = C(s);
|
|
2116
|
+
else if (s instanceof ArrayBuffer)
|
|
2117
|
+
r = s;
|
|
2118
|
+
else if (s instanceof Uint8Array)
|
|
2119
|
+
r = C(s);
|
|
2120
|
+
else
|
|
2121
|
+
throw new Error(
|
|
2122
|
+
`parseXlsx expects stream or buffer input, got ${typeof s}`
|
|
2123
|
+
);
|
|
2124
|
+
const n = new $.Workbook();
|
|
2125
|
+
return await n.xlsx.load(r), v.fromExcelJS(n, e.fileName);
|
|
2126
|
+
}
|
|
2127
|
+
};
|
|
2128
|
+
async function Z(s, t) {
|
|
2129
|
+
const e = new $.Workbook();
|
|
2130
|
+
let r;
|
|
2131
|
+
return s instanceof ArrayBuffer ? r = s : r = C(s), await e.xlsx.load(r), v.fromExcelJS(e, t?.fileName);
|
|
2132
|
+
}
|
|
2133
|
+
async function G(s, t) {
|
|
2134
|
+
const e = new $.Workbook();
|
|
2135
|
+
return await e.xlsx.readFile(s), v.fromExcelJS(e, t?.fileName ?? s);
|
|
2136
|
+
}
|
|
2137
|
+
function D(s, t) {
|
|
2138
|
+
return s == null ? null : s instanceof Date ? t?.dateAsIsoString !== !1 ? s.toISOString() : s.getTime() : typeof s == "string" || typeof s == "number" || typeof s == "boolean" ? s : null;
|
|
2139
|
+
}
|
|
2140
|
+
function J(s, t) {
|
|
2141
|
+
const e = s.value(), r = e.ok ? D(e.value, t) : null;
|
|
2142
|
+
return t?.includeCellAddresses ? {
|
|
2143
|
+
address: s.address,
|
|
2144
|
+
value: r
|
|
2145
|
+
} : r;
|
|
2146
|
+
}
|
|
2147
|
+
function j(s, t) {
|
|
2148
|
+
return t?.firstRowAsHeaders ? B(s, t) : W(s, t);
|
|
2149
|
+
}
|
|
2150
|
+
function W(s, t) {
|
|
2151
|
+
const e = [];
|
|
2152
|
+
for (const r of s.rows()) {
|
|
2153
|
+
const n = [];
|
|
2154
|
+
for (const o of r) {
|
|
2155
|
+
const i = J(o, t);
|
|
2156
|
+
i !== null || t?.includeEmpty ? n.push(i) : (n.length > 0 || t?.includeEmpty) && n.push(null);
|
|
2157
|
+
}
|
|
2158
|
+
(n.length > 0 || t?.includeEmpty) && e.push(n);
|
|
2159
|
+
}
|
|
2160
|
+
return e;
|
|
2161
|
+
}
|
|
2162
|
+
function B(s, t) {
|
|
2163
|
+
const e = [...s.rows()];
|
|
2164
|
+
if (e.length === 0) return [];
|
|
2165
|
+
const n = e[0].map((i) => {
|
|
2166
|
+
const a = i.value();
|
|
2167
|
+
return a.ok && a.value !== null ? String(a.value) : `col_${i.col}`;
|
|
2168
|
+
}), o = [];
|
|
2169
|
+
for (let i = 1; i < e.length; i++) {
|
|
2170
|
+
const a = e[i], u = {};
|
|
2171
|
+
let c = !1;
|
|
2172
|
+
for (let f = 0; f < n.length; f++) {
|
|
2173
|
+
const g = n[f], x = a[f];
|
|
2174
|
+
if (x) {
|
|
2175
|
+
const _ = J(x, t);
|
|
2176
|
+
_ !== null && (c = !0), u[g] = _;
|
|
2177
|
+
} else
|
|
2178
|
+
u[g] = null;
|
|
2179
|
+
}
|
|
2180
|
+
(c || t?.includeEmpty) && o.push(u);
|
|
2181
|
+
}
|
|
2182
|
+
return o;
|
|
2183
|
+
}
|
|
2184
|
+
function V(s, t) {
|
|
2185
|
+
const e = s.usedRange();
|
|
2186
|
+
return e.ok ? j(e.value, t) : t?.firstRowAsHeaders ? [] : [[]];
|
|
2187
|
+
}
|
|
2188
|
+
function K(s, t) {
|
|
2189
|
+
const e = s.sheets();
|
|
2190
|
+
if (t?.includeSheetNames !== !1) {
|
|
2191
|
+
const r = {};
|
|
2192
|
+
for (const n of e)
|
|
2193
|
+
r[n.name] = V(n, t);
|
|
2194
|
+
return r;
|
|
2195
|
+
}
|
|
2196
|
+
return e.map((r) => V(r, t));
|
|
2197
|
+
}
|
|
2198
|
+
function L(s, t) {
|
|
2199
|
+
const e = t?.delimiter ?? ",", r = t?.lineEnding ?? `
|
|
2200
|
+
`, n = t?.quoteStrings ?? !0, o = [];
|
|
2201
|
+
for (const i of s.rows()) {
|
|
2202
|
+
const a = [];
|
|
2203
|
+
for (const u of i) {
|
|
2204
|
+
const c = u.value();
|
|
2205
|
+
let f;
|
|
2206
|
+
!c.ok || c.value === null ? f = "" : c.value instanceof Date ? f = c.value.toISOString() : f = String(c.value), n && (f.includes(e) || f.includes(`
|
|
2207
|
+
`) || f.includes("\r") || f.includes('"')) && (f = '"' + f.replace(/"/g, '""') + '"'), a.push(f);
|
|
2208
|
+
}
|
|
2209
|
+
o.push(a.join(e));
|
|
2210
|
+
}
|
|
2211
|
+
return o.join(r);
|
|
2212
|
+
}
|
|
2213
|
+
function Q(s, t) {
|
|
2214
|
+
const e = s.usedRange();
|
|
2215
|
+
return e.ok ? L(e.value, t) : "";
|
|
2216
|
+
}
|
|
2217
|
+
function Y(s) {
|
|
2218
|
+
s.register(I);
|
|
2219
|
+
}
|
|
2220
|
+
export {
|
|
2221
|
+
w as XlsxCell,
|
|
2222
|
+
d as XlsxCursor,
|
|
2223
|
+
m as XlsxRange,
|
|
2224
|
+
k as XlsxSheet,
|
|
2225
|
+
v as XlsxWorkbook,
|
|
2226
|
+
J as cellToJson,
|
|
2227
|
+
D as cellValueToJson,
|
|
2228
|
+
T as columnLetterToNumber,
|
|
2229
|
+
N as columnNumberToLetter,
|
|
2230
|
+
h as fail,
|
|
2231
|
+
R as formatAddress,
|
|
2232
|
+
A as formatRange,
|
|
2233
|
+
F as formatXlsxPath,
|
|
2234
|
+
S as isError,
|
|
2235
|
+
b as isFormula,
|
|
2236
|
+
O as isInRange,
|
|
2237
|
+
l as ok,
|
|
2238
|
+
p as parseAddress,
|
|
2239
|
+
y as parseRange,
|
|
2240
|
+
H as parseXlsx,
|
|
2241
|
+
I as parseXlsxAsyncImpl,
|
|
2242
|
+
Z as parseXlsxBuffer,
|
|
2243
|
+
G as parseXlsxFile,
|
|
2244
|
+
P as parseXlsxImpl,
|
|
2245
|
+
q as predicates,
|
|
2246
|
+
W as rangeToArray,
|
|
2247
|
+
L as rangeToCsv,
|
|
2248
|
+
j as rangeToJson,
|
|
2249
|
+
B as rangeToObjects,
|
|
2250
|
+
Y as registerXlsxTransforms,
|
|
2251
|
+
Q as sheetToCsv,
|
|
2252
|
+
V as sheetToJson,
|
|
2253
|
+
M as streamToBuffer,
|
|
2254
|
+
U as toExcelLocation,
|
|
2255
|
+
K as workbookToJson
|
|
2256
|
+
};
|
|
2257
|
+
//# sourceMappingURL=index.es.js.map
|