@cj-tech-master/excelts 1.4.4 → 1.4.5-canary.20251212064440.3eb099f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/browser/excelts.iife.js +8726 -8664
  2. package/dist/browser/excelts.iife.js.map +1 -1
  3. package/dist/browser/excelts.iife.min.js +28 -28
  4. package/dist/cjs/doc/anchor.js +25 -11
  5. package/dist/cjs/doc/cell.js +75 -43
  6. package/dist/cjs/doc/column.js +39 -16
  7. package/dist/cjs/doc/defined-names.js +53 -7
  8. package/dist/cjs/doc/image.js +11 -8
  9. package/dist/cjs/doc/range.js +64 -28
  10. package/dist/cjs/doc/row.js +33 -17
  11. package/dist/cjs/doc/table.js +3 -5
  12. package/dist/cjs/doc/workbook.js +5 -4
  13. package/dist/cjs/doc/worksheet.js +15 -16
  14. package/dist/cjs/utils/sheet-utils.js +3 -1
  15. package/dist/esm/doc/anchor.js +25 -11
  16. package/dist/esm/doc/cell.js +75 -43
  17. package/dist/esm/doc/column.js +39 -16
  18. package/dist/esm/doc/defined-names.js +53 -7
  19. package/dist/esm/doc/image.js +11 -8
  20. package/dist/esm/doc/range.js +64 -28
  21. package/dist/esm/doc/row.js +33 -17
  22. package/dist/esm/doc/table.js +3 -5
  23. package/dist/esm/doc/workbook.js +5 -4
  24. package/dist/esm/doc/worksheet.js +15 -16
  25. package/dist/esm/utils/sheet-utils.js +3 -1
  26. package/dist/types/doc/anchor.d.ts +14 -7
  27. package/dist/types/doc/cell.d.ts +85 -40
  28. package/dist/types/doc/column.d.ts +39 -34
  29. package/dist/types/doc/defined-names.d.ts +11 -8
  30. package/dist/types/doc/image.d.ts +29 -12
  31. package/dist/types/doc/pivot-table.d.ts +1 -1
  32. package/dist/types/doc/range.d.ts +15 -4
  33. package/dist/types/doc/row.d.ts +34 -40
  34. package/dist/types/doc/table.d.ts +21 -36
  35. package/dist/types/doc/workbook.d.ts +30 -33
  36. package/dist/types/doc/worksheet.d.ts +98 -73
  37. package/dist/types/stream/xlsx/worksheet-reader.d.ts +3 -5
  38. package/dist/types/types.d.ts +86 -26
  39. package/dist/types/utils/col-cache.d.ts +11 -8
  40. package/package.json +8 -8
@@ -13,11 +13,15 @@ class DefinedNames {
13
13
  // add a name to a cell. locStr in the form SheetName!$col$row or SheetName!$c1$r1:$c2:$r2
14
14
  add(locStr, name) {
15
15
  const location = colCache.decodeEx(locStr);
16
+ if ("error" in location) {
17
+ return; // Invalid reference, skip
18
+ }
16
19
  this.addEx(location, name);
17
20
  }
18
21
  addEx(location, name) {
19
22
  const matrix = this.getMatrix(name);
20
- if (location.top) {
23
+ if ("top" in location) {
24
+ // It's a range (DecodedRange has top/left/bottom/right from Location)
21
25
  for (let col = location.left; col <= location.right; col++) {
22
26
  for (let row = location.top; row <= location.bottom; row++) {
23
27
  const address = {
@@ -31,20 +35,54 @@ class DefinedNames {
31
35
  }
32
36
  }
33
37
  else {
38
+ // It's a single cell address
34
39
  matrix.addCellEx(location);
35
40
  }
36
41
  }
37
42
  remove(locStr, name) {
38
43
  const location = colCache.decodeEx(locStr);
44
+ if ("error" in location) {
45
+ return; // Invalid reference, skip
46
+ }
39
47
  this.removeEx(location, name);
40
48
  }
41
49
  removeEx(location, name) {
42
50
  const matrix = this.getMatrix(name);
43
- matrix.removeCellEx(location);
51
+ if ("top" in location) {
52
+ // Range - remove each cell
53
+ for (let col = location.left; col <= location.right; col++) {
54
+ for (let row = location.top; row <= location.bottom; row++) {
55
+ matrix.removeCellEx({
56
+ sheetName: location.sheetName,
57
+ address: colCache.n2l(col) + row,
58
+ row,
59
+ col
60
+ });
61
+ }
62
+ }
63
+ }
64
+ else {
65
+ matrix.removeCellEx(location);
66
+ }
44
67
  }
45
68
  removeAllNames(location) {
46
69
  Object.values(this.matrixMap).forEach((matrix) => {
47
- matrix.removeCellEx(location);
70
+ if ("top" in location) {
71
+ // Range - remove each cell
72
+ for (let col = location.left; col <= location.right; col++) {
73
+ for (let row = location.top; row <= location.bottom; row++) {
74
+ matrix.removeCellEx({
75
+ sheetName: location.sheetName,
76
+ address: colCache.n2l(col) + row,
77
+ row,
78
+ col
79
+ });
80
+ }
81
+ }
82
+ }
83
+ else {
84
+ matrix.removeCellEx(location);
85
+ }
48
86
  });
49
87
  }
50
88
  forEach(callback) {
@@ -56,12 +94,16 @@ class DefinedNames {
56
94
  }
57
95
  // get all the names of a cell
58
96
  getNames(addressStr) {
59
- return this.getNamesEx(colCache.decodeEx(addressStr));
97
+ const location = colCache.decodeEx(addressStr);
98
+ if ("error" in location || "top" in location) {
99
+ return []; // Invalid reference or range not supported
100
+ }
101
+ return this.getNamesEx(location);
60
102
  }
61
103
  getNamesEx(address) {
62
104
  return Object.entries(this.matrixMap)
63
105
  .map(([name, matrix]) => matrix.findCellEx(address, false) && name)
64
- .filter(Boolean);
106
+ .filter((name) => Boolean(name));
65
107
  }
66
108
  _explore(matrix, cell) {
67
109
  cell.mark = false;
@@ -69,9 +111,13 @@ class DefinedNames {
69
111
  const range = new Range(cell.row, cell.col, cell.row, cell.col, sheetName);
70
112
  let x;
71
113
  let y;
114
+ // Helper to get cell with proper type
115
+ const getCell = (row, col) => {
116
+ return matrix.findCellAt(sheetName, row, col);
117
+ };
72
118
  // grow vertical - only one col to worry about
73
119
  function vGrow(yy, edge) {
74
- const c = matrix.findCellAt(sheetName, yy, cell.col);
120
+ const c = getCell(yy, cell.col);
75
121
  if (!c || !c.mark) {
76
122
  return false;
77
123
  }
@@ -85,7 +131,7 @@ class DefinedNames {
85
131
  function hGrow(xx, edge) {
86
132
  const cells = [];
87
133
  for (y = range.top; y <= range.bottom; y++) {
88
- const c = matrix.findCellAt(sheetName, y, xx);
134
+ const c = getCell(y, xx);
89
135
  if (c && c.mark) {
90
136
  cells.push(c);
91
137
  }
@@ -36,19 +36,22 @@ class Image {
36
36
  if (type === "image") {
37
37
  if (typeof range === "string") {
38
38
  const decoded = colCache.decode(range);
39
- this.range = {
40
- tl: new Anchor(this.worksheet, { col: decoded.left, row: decoded.top }, -1),
41
- br: new Anchor(this.worksheet, { col: decoded.right, row: decoded.bottom }, 0),
42
- editAs: "oneCell"
43
- };
39
+ if ("top" in decoded) {
40
+ // It's a Location (range like "A1:C3")
41
+ this.range = {
42
+ tl: new Anchor(this.worksheet, { col: decoded.left, row: decoded.top }, -1),
43
+ br: new Anchor(this.worksheet, { col: decoded.right, row: decoded.bottom }, 0),
44
+ editAs: "oneCell"
45
+ };
46
+ }
44
47
  }
45
- else {
48
+ else if (range) {
46
49
  this.range = {
47
50
  tl: new Anchor(this.worksheet, range.tl, 0),
48
- br: range.br && new Anchor(this.worksheet, range.br, 0),
51
+ br: range.br ? new Anchor(this.worksheet, range.br, 0) : undefined,
49
52
  ext: range.ext,
50
53
  editAs: range.editAs,
51
- hyperlinks: hyperlinks || range.hyperlinks
54
+ hyperlinks: hyperlinks || ("hyperlinks" in range ? range.hyperlinks : undefined)
52
55
  };
53
56
  }
54
57
  }
@@ -2,11 +2,17 @@ import { colCache } from "../utils/col-cache.js";
2
2
  // used by worksheet to calculate sheet dimensions
3
3
  class Range {
4
4
  constructor(...args) {
5
+ this.model = {
6
+ top: 0,
7
+ left: 0,
8
+ bottom: 0,
9
+ right: 0
10
+ };
5
11
  this.decode(args);
6
12
  }
7
13
  setTLBR(t, l, b, r, s) {
8
- if (arguments.length < 4) {
9
- // setTLBR(tl, br, s)
14
+ if (typeof t === "string" && typeof l === "string") {
15
+ // setTLBR(tl, br, s) - t and l are address strings
10
16
  const tl = colCache.decodeAddress(t);
11
17
  const br = colCache.decodeAddress(l);
12
18
  this.model = {
@@ -14,12 +20,14 @@ class Range {
14
20
  left: Math.min(tl.col, br.col),
15
21
  bottom: Math.max(tl.row, br.row),
16
22
  right: Math.max(tl.col, br.col),
17
- sheetName: b
23
+ sheetName: typeof b === "string" ? b : undefined
18
24
  };
19
- this.setTLBR(tl.row, tl.col, br.row, br.col, s);
20
25
  }
21
- else {
22
- // setTLBR(t, l, b, r, s)
26
+ else if (typeof t === "number" &&
27
+ typeof l === "number" &&
28
+ typeof b === "number" &&
29
+ typeof r === "number") {
30
+ // setTLBR(t, l, b, r, s) - all numbers
23
31
  this.model = {
24
32
  top: Math.min(t, b),
25
33
  left: Math.min(l, r),
@@ -32,16 +40,33 @@ class Range {
32
40
  decode(argv) {
33
41
  switch (argv.length) {
34
42
  case 5: // [t,l,b,r,s]
35
- this.setTLBR(argv[0], argv[1], argv[2], argv[3], argv[4]);
43
+ if (typeof argv[0] === "number" &&
44
+ typeof argv[1] === "number" &&
45
+ typeof argv[2] === "number" &&
46
+ typeof argv[3] === "number" &&
47
+ typeof argv[4] === "string") {
48
+ this.setTLBR(argv[0], argv[1], argv[2], argv[3], argv[4]);
49
+ }
36
50
  break;
37
51
  case 4: // [t,l,b,r]
38
- this.setTLBR(argv[0], argv[1], argv[2], argv[3]);
52
+ if (typeof argv[0] === "number" &&
53
+ typeof argv[1] === "number" &&
54
+ typeof argv[2] === "number" &&
55
+ typeof argv[3] === "number") {
56
+ this.setTLBR(argv[0], argv[1], argv[2], argv[3]);
57
+ }
39
58
  break;
40
59
  case 3: // [tl,br,s]
41
- this.setTLBR(argv[0], argv[1], argv[2]);
60
+ if (typeof argv[0] === "string" &&
61
+ typeof argv[1] === "string" &&
62
+ typeof argv[2] === "string") {
63
+ this.setTLBR(argv[0], argv[1], argv[2]);
64
+ }
42
65
  break;
43
66
  case 2: // [tl,br]
44
- this.setTLBR(argv[0], argv[1]);
67
+ if (typeof argv[0] === "string" && typeof argv[1] === "string") {
68
+ this.setTLBR(argv[0], argv[1]);
69
+ }
45
70
  break;
46
71
  case 1: {
47
72
  const value = argv[0];
@@ -55,11 +80,15 @@ class Range {
55
80
  sheetName: value.sheetName
56
81
  };
57
82
  }
58
- else if (value instanceof Array) {
83
+ else if (Array.isArray(value)) {
59
84
  // an arguments array
60
85
  this.decode(value);
61
86
  }
62
- else if (value.top && value.left && value.bottom && value.right) {
87
+ else if (typeof value === "object" &&
88
+ "top" in value &&
89
+ "left" in value &&
90
+ "bottom" in value &&
91
+ "right" in value) {
63
92
  // a model
64
93
  this.model = {
65
94
  top: value.top,
@@ -69,25 +98,27 @@ class Range {
69
98
  sheetName: value.sheetName
70
99
  };
71
100
  }
72
- else {
101
+ else if (typeof value === "string") {
73
102
  // [sheetName!]tl:br
74
- const tlbr = colCache.decodeEx(value);
75
- if (tlbr.top) {
103
+ const decoded = colCache.decodeEx(value);
104
+ if ("top" in decoded) {
105
+ // It's a DecodedRange
76
106
  this.model = {
77
- top: tlbr.top,
78
- left: tlbr.left,
79
- bottom: tlbr.bottom,
80
- right: tlbr.right,
81
- sheetName: tlbr.sheetName
107
+ top: decoded.top,
108
+ left: decoded.left,
109
+ bottom: decoded.bottom,
110
+ right: decoded.right,
111
+ sheetName: decoded.sheetName
82
112
  };
83
113
  }
84
- else {
114
+ else if ("row" in decoded) {
115
+ // It's an Address
85
116
  this.model = {
86
- top: tlbr.row,
87
- left: tlbr.col,
88
- bottom: tlbr.row,
89
- right: tlbr.col,
90
- sheetName: tlbr.sheetName
117
+ top: decoded.row,
118
+ left: decoded.col,
119
+ bottom: decoded.row,
120
+ right: decoded.col,
121
+ sheetName: decoded.sheetName
91
122
  };
92
123
  }
93
124
  }
@@ -169,7 +200,9 @@ class Range {
169
200
  }
170
201
  expandToAddress(addressStr) {
171
202
  const address = colCache.decodeEx(addressStr);
172
- this.expand(address.row, address.col, address.row, address.col);
203
+ if ("row" in address && "col" in address) {
204
+ this.expand(address.row, address.col, address.row, address.col);
205
+ }
173
206
  }
174
207
  get tl() {
175
208
  return colCache.n2l(this.left) + this.top;
@@ -221,7 +254,10 @@ class Range {
221
254
  }
222
255
  contains(addressStr) {
223
256
  const address = colCache.decodeEx(addressStr);
224
- return this.containsEx(address);
257
+ if ("row" in address && "col" in address) {
258
+ return this.containsEx(address);
259
+ }
260
+ return false;
225
261
  }
226
262
  containsEx(address) {
227
263
  if (address.sheetName && this.sheetName && address.sheetName !== this.sheetName) {
@@ -80,12 +80,12 @@ class Row {
80
80
  cDst = this.getCell(i);
81
81
  cDst.value = cSrc.value;
82
82
  cDst.style = cSrc.style;
83
- cDst._comment = cSrc._comment;
83
+ cDst.comment = cSrc.comment;
84
84
  }
85
85
  else if (cDst) {
86
86
  cDst.value = null;
87
87
  cDst.style = {};
88
- cDst._comment = undefined;
88
+ cDst.comment = undefined;
89
89
  }
90
90
  }
91
91
  }
@@ -97,7 +97,7 @@ class Row {
97
97
  cDst = this.getCell(i + nExpand);
98
98
  cDst.value = cSrc.value;
99
99
  cDst.style = cSrc.style;
100
- cDst._comment = cSrc._comment;
100
+ cDst.comment = cSrc.comment;
101
101
  }
102
102
  else {
103
103
  this._cells[i + nExpand - 1] = undefined;
@@ -109,13 +109,18 @@ class Row {
109
109
  cDst = this.getCell(start + i);
110
110
  cDst.value = inserts[i];
111
111
  cDst.style = {};
112
- cDst._comment = undefined;
112
+ cDst.comment = undefined;
113
113
  }
114
114
  }
115
- eachCell(options, iteratee) {
116
- if (!iteratee) {
117
- iteratee = options;
118
- options = null;
115
+ eachCell(optionsOrIteratee, maybeIteratee) {
116
+ let options = null;
117
+ let iteratee;
118
+ if (typeof optionsOrIteratee === "function") {
119
+ iteratee = optionsOrIteratee;
120
+ }
121
+ else {
122
+ options = optionsOrIteratee;
123
+ iteratee = maybeIteratee;
119
124
  }
120
125
  if (options && options.includeEmpty) {
121
126
  const n = this._cells.length;
@@ -195,7 +200,7 @@ class Row {
195
200
  }
196
201
  // returns true if the row includes at least one cell with a value
197
202
  get hasValues() {
198
- return this._cells.some((cell) => cell && cell.type !== Enums.ValueType.Null);
203
+ return this._cells.some(cell => cell && cell.type !== Enums.ValueType.Null);
199
204
  }
200
205
  get cellCount() {
201
206
  return this._cells.length;
@@ -234,46 +239,57 @@ class Row {
234
239
  this.style[name] = value;
235
240
  this._cells.forEach(cell => {
236
241
  if (cell) {
237
- cell[name] = value;
242
+ cell.style[name] = value;
238
243
  }
239
244
  });
240
- return value;
241
245
  }
242
246
  get numFmt() {
243
247
  return this.style.numFmt;
244
248
  }
245
249
  set numFmt(value) {
246
- this._applyStyle("numFmt", value);
250
+ if (value !== undefined) {
251
+ this._applyStyle("numFmt", value);
252
+ }
247
253
  }
248
254
  get font() {
249
255
  return this.style.font;
250
256
  }
251
257
  set font(value) {
252
- this._applyStyle("font", value);
258
+ if (value !== undefined) {
259
+ this._applyStyle("font", value);
260
+ }
253
261
  }
254
262
  get alignment() {
255
263
  return this.style.alignment;
256
264
  }
257
265
  set alignment(value) {
258
- this._applyStyle("alignment", value);
266
+ if (value !== undefined) {
267
+ this._applyStyle("alignment", value);
268
+ }
259
269
  }
260
270
  get protection() {
261
271
  return this.style.protection;
262
272
  }
263
273
  set protection(value) {
264
- this._applyStyle("protection", value);
274
+ if (value !== undefined) {
275
+ this._applyStyle("protection", value);
276
+ }
265
277
  }
266
278
  get border() {
267
279
  return this.style.border;
268
280
  }
269
281
  set border(value) {
270
- this._applyStyle("border", value);
282
+ if (value !== undefined) {
283
+ this._applyStyle("border", value);
284
+ }
271
285
  }
272
286
  get fill() {
273
287
  return this.style.fill;
274
288
  }
275
289
  set fill(value) {
276
- this._applyStyle("fill", value);
290
+ if (value !== undefined) {
291
+ this._applyStyle("fill", value);
292
+ }
277
293
  }
278
294
  get hidden() {
279
295
  return !!this._hidden;
@@ -154,9 +154,7 @@ class Table {
154
154
  // the sheet...
155
155
  const assignStyle = (cell, style) => {
156
156
  if (style) {
157
- Object.keys(style).forEach(key => {
158
- cell.style[key] = style[key];
159
- });
157
+ Object.assign(cell.style, style);
160
158
  }
161
159
  };
162
160
  const { worksheet, table } = this;
@@ -374,10 +372,10 @@ class Table {
374
372
  this._assign(this.table, "totalsRow", value);
375
373
  }
376
374
  get theme() {
377
- return this.table.style.name;
375
+ return this.table.style.theme;
378
376
  }
379
377
  set theme(value) {
380
- this.table.style.name = value;
378
+ this.table.style.theme = value;
381
379
  }
382
380
  get showFirstColumn() {
383
381
  return this.table.style.showFirstColumn;
@@ -50,12 +50,13 @@ class Workbook {
50
50
  addWorksheet(name, options) {
51
51
  const id = this.nextId;
52
52
  const lastOrderNo = this._worksheets.reduce((acc, ws) => ((ws && ws.orderNo) > acc ? ws.orderNo : acc), 0);
53
- const worksheetOptions = Object.assign({}, options, {
53
+ const worksheetOptions = {
54
+ ...options,
54
55
  id,
55
56
  name,
56
57
  orderNo: lastOrderNo + 1,
57
58
  workbook: this
58
- });
59
+ };
59
60
  const worksheet = new Worksheet(worksheetOptions);
60
61
  this._worksheets[id] = worksheet;
61
62
  return worksheet;
@@ -103,11 +104,11 @@ class Workbook {
103
104
  addImage(image) {
104
105
  // TODO: validation?
105
106
  const id = this.media.length;
106
- this.media.push(Object.assign({}, image, { type: "image" }));
107
+ this.media.push({ ...image, type: "image" });
107
108
  return id;
108
109
  }
109
110
  getImage(id) {
110
- return this.media[id];
111
+ return this.media[Number(id)];
111
112
  }
112
113
  get model() {
113
114
  return {
@@ -125,7 +125,7 @@ class Worksheet {
125
125
  }
126
126
  name = name.substring(0, 31);
127
127
  }
128
- if (this._workbook._worksheets.find((ws) => ws && ws.name.toLowerCase() === name.toLowerCase())) {
128
+ if (this._workbook.worksheets.find(ws => ws && ws.name.toLowerCase() === name.toLowerCase())) {
129
129
  throw new Error(`Worksheet name already exists: ${name}`);
130
130
  }
131
131
  this._name = name;
@@ -161,7 +161,7 @@ class Worksheet {
161
161
  set columns(value) {
162
162
  // calculate max header row count
163
163
  this._headerRowCount = value.reduce((pv, cv) => {
164
- const headerCount = (cv.header && 1) || (cv.headers && cv.headers.length) || 0;
164
+ const headerCount = Array.isArray(cv.header) ? cv.header.length : cv.header ? 1 : 0;
165
165
  return Math.max(pv, headerCount);
166
166
  }, 0);
167
167
  // construct Column objects
@@ -217,12 +217,9 @@ class Worksheet {
217
217
  if (inserts.length > 0) {
218
218
  // must iterate over all rows whether they exist yet or not
219
219
  for (let i = 0; i < nRows; i++) {
220
- const rowArguments = [start, count];
221
- inserts.forEach(insert => {
222
- rowArguments.push(insert[i] || null);
223
- });
220
+ const insertValues = inserts.map(insert => insert[i] || null);
224
221
  const row = this.getRow(i + 1);
225
- row.splice(...rowArguments);
222
+ row.splice(start, count, ...insertValues);
226
223
  }
227
224
  }
228
225
  else {
@@ -248,7 +245,7 @@ class Worksheet {
248
245
  }
249
246
  }
250
247
  for (let i = start; i < start + inserts.length; i++) {
251
- this.getColumn(i).defn = null;
248
+ this.getColumn(i).defn = undefined;
252
249
  }
253
250
  // account for defined names
254
251
  this.workbook.definedNames.spliceColumns(this.name, start, count, inserts.length);
@@ -258,7 +255,7 @@ class Worksheet {
258
255
  }
259
256
  get columnCount() {
260
257
  let maxCount = 0;
261
- this.eachRow((row) => {
258
+ this.eachRow(row => {
262
259
  maxCount = Math.max(maxCount, row.cellCount);
263
260
  });
264
261
  return maxCount;
@@ -267,7 +264,7 @@ class Worksheet {
267
264
  // performance nightmare - for each row, counts all the columns used
268
265
  const counts = [];
269
266
  let count = 0;
270
- this.eachRow((row) => {
267
+ this.eachRow(row => {
271
268
  row.eachCell(({ col }) => {
272
269
  if (!counts[col]) {
273
270
  counts[col] = true;
@@ -448,10 +445,10 @@ class Worksheet {
448
445
  rSrc.eachCell({ includeEmpty: true }, (cell, colNumber) => {
449
446
  rDst.getCell(colNumber).style = cell.style;
450
447
  // remerge cells accounting for insert offset
451
- if (cell._value.constructor.name === "MergeValue") {
452
- const cellToBeMerged = this.getRow(cell._row._number + nInserts).getCell(colNumber);
453
- const prevMaster = cell._value._master;
454
- const newMaster = this.getRow(prevMaster._row._number + nInserts).getCell(prevMaster._column._number);
448
+ if (cell.type === Enums.ValueType.Merge) {
449
+ const cellToBeMerged = this.getRow(cell.row + nInserts).getCell(colNumber);
450
+ const prevMaster = cell.master;
451
+ const newMaster = this.getRow(prevMaster.row + nInserts).getCell(prevMaster.col);
455
452
  cellToBeMerged.merge(newMaster);
456
453
  }
457
454
  });
@@ -611,12 +608,14 @@ class Worksheet {
611
608
  for (let r = top; r <= bottom; r++) {
612
609
  for (let c = left; c <= right; c++) {
613
610
  if (first) {
614
- this.getCell(r, c).value = {
611
+ const cell = this.getCell(r, c);
612
+ const formulaValue = {
615
613
  shareType,
616
614
  formula,
617
615
  ref: range,
618
616
  result: getResult(r, c)
619
617
  };
618
+ cell.value = formulaValue;
620
619
  first = false;
621
620
  }
622
621
  else {
@@ -752,7 +751,7 @@ Please leave feedback at https://github.com/excelts/excelts/discussions/2575`);
752
751
  };
753
752
  // =================================================
754
753
  // columns
755
- model.cols = Column.toModel(this.columns);
754
+ model.cols = Column.toModel(this.columns || []);
756
755
  // ==========================================================
757
756
  // Rows
758
757
  const rows = (model.rows = []);
@@ -112,7 +112,9 @@ function formatValue(value, fmt, dateFormat) {
112
112
  */
113
113
  function getCellDisplayText(cell, dateFormat) {
114
114
  const value = cell.value;
115
- const fmt = cell.numFmt || "General";
115
+ const numFmt = cell.numFmt;
116
+ // Extract format code string from numFmt (which can be string or NumFmt object)
117
+ const fmt = typeof numFmt === "string" ? numFmt : (numFmt?.formatCode ?? "General");
116
118
  // Null/undefined
117
119
  if (value == null) {
118
120
  return "";
@@ -1,26 +1,33 @@
1
1
  import type { Worksheet } from "./worksheet.js";
2
+ interface AnchorModel {
3
+ nativeCol: number;
4
+ nativeRow: number;
5
+ nativeColOff: number;
6
+ nativeRowOff: number;
7
+ }
2
8
  interface SimpleAddress {
3
- col?: number;
4
- row?: number;
9
+ col: number;
10
+ row: number;
5
11
  }
6
- type AddressInput = string | Anchor | SimpleAddress | null | undefined;
12
+ type AddressInput = string | AnchorModel | SimpleAddress;
7
13
  declare class Anchor {
8
14
  nativeCol: number;
9
15
  nativeRow: number;
10
16
  nativeColOff: number;
11
17
  nativeRowOff: number;
12
18
  worksheet?: Worksheet;
13
- constructor(worksheet?: Worksheet, address?: AddressInput, offset?: number);
14
- static asInstance(model: any): Anchor | null;
19
+ constructor(worksheet?: Worksheet, address?: AddressInput | null, offset?: number);
20
+ static asInstance(model: AddressInput | Anchor | null | undefined): Anchor | null;
15
21
  get col(): number;
16
22
  set col(v: number);
17
23
  get row(): number;
18
24
  set row(v: number);
19
25
  get colWidth(): number;
20
26
  get rowHeight(): number;
21
- get model(): Pick<Anchor, "nativeCol" | "nativeRow" | "nativeColOff" | "nativeRowOff">;
22
- set model(value: Pick<Anchor, "nativeCol" | "nativeRow" | "nativeColOff" | "nativeRowOff">);
27
+ get model(): AnchorModel;
28
+ set model(value: AnchorModel);
23
29
  }
24
30
  export { Anchor };
31
+ export type { AnchorModel };
25
32
  type IAnchor = Pick<InstanceType<typeof Anchor>, "col" | "row" | "nativeCol" | "nativeRow" | "nativeColOff" | "nativeRowOff">;
26
33
  export type { IAnchor };