@cj-tech-master/excelts 1.4.5 → 1.5.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.
Files changed (49) hide show
  1. package/dist/browser/excelts.iife.js +454 -159
  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 +74 -22
  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 +72 -31
  11. package/dist/cjs/doc/table.js +3 -5
  12. package/dist/cjs/doc/workbook.js +30 -6
  13. package/dist/cjs/doc/worksheet.js +165 -41
  14. package/dist/cjs/utils/sheet-utils.js +3 -1
  15. package/dist/cjs/utils/unzip/extract.js +30 -82
  16. package/dist/cjs/utils/unzip/index.js +18 -2
  17. package/dist/cjs/utils/unzip/zip-parser.js +458 -0
  18. package/dist/esm/doc/anchor.js +25 -11
  19. package/dist/esm/doc/cell.js +75 -43
  20. package/dist/esm/doc/column.js +74 -22
  21. package/dist/esm/doc/defined-names.js +53 -7
  22. package/dist/esm/doc/image.js +11 -8
  23. package/dist/esm/doc/range.js +64 -28
  24. package/dist/esm/doc/row.js +72 -31
  25. package/dist/esm/doc/table.js +3 -5
  26. package/dist/esm/doc/workbook.js +30 -6
  27. package/dist/esm/doc/worksheet.js +165 -41
  28. package/dist/esm/utils/sheet-utils.js +3 -1
  29. package/dist/esm/utils/unzip/extract.js +28 -82
  30. package/dist/esm/utils/unzip/index.js +17 -2
  31. package/dist/esm/utils/unzip/zip-parser.js +451 -0
  32. package/dist/types/doc/anchor.d.ts +14 -7
  33. package/dist/types/doc/cell.d.ts +78 -37
  34. package/dist/types/doc/column.d.ts +72 -36
  35. package/dist/types/doc/defined-names.d.ts +11 -8
  36. package/dist/types/doc/image.d.ts +29 -12
  37. package/dist/types/doc/pivot-table.d.ts +1 -1
  38. package/dist/types/doc/range.d.ts +15 -4
  39. package/dist/types/doc/row.d.ts +78 -40
  40. package/dist/types/doc/table.d.ts +21 -36
  41. package/dist/types/doc/workbook.d.ts +54 -34
  42. package/dist/types/doc/worksheet.d.ts +255 -83
  43. package/dist/types/stream/xlsx/worksheet-reader.d.ts +3 -5
  44. package/dist/types/types.d.ts +86 -26
  45. package/dist/types/utils/col-cache.d.ts +11 -8
  46. package/dist/types/utils/unzip/extract.d.ts +16 -14
  47. package/dist/types/utils/unzip/index.d.ts +15 -1
  48. package/dist/types/utils/unzip/zip-parser.d.ts +92 -0
  49. package/package.json +1 -1
@@ -2,6 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Anchor = void 0;
4
4
  const col_cache_js_1 = require("../utils/col-cache");
5
+ function isAnchorModel(value) {
6
+ return (typeof value === "object" &&
7
+ "nativeCol" in value &&
8
+ "nativeRow" in value &&
9
+ "nativeColOff" in value &&
10
+ "nativeRowOff" in value);
11
+ }
12
+ function isSimpleAddress(value) {
13
+ return typeof value === "object" && "col" in value && "row" in value;
14
+ }
5
15
  class Anchor {
6
16
  constructor(worksheet, address, offset = 0) {
7
17
  this.worksheet = worksheet;
@@ -18,17 +28,15 @@ class Anchor {
18
28
  this.nativeRow = decoded.row + offset;
19
29
  this.nativeRowOff = 0;
20
30
  }
21
- else if (address.nativeCol !== undefined) {
22
- const anchor = address;
23
- this.nativeCol = anchor.nativeCol || 0;
24
- this.nativeColOff = anchor.nativeColOff || 0;
25
- this.nativeRow = anchor.nativeRow || 0;
26
- this.nativeRowOff = anchor.nativeRowOff || 0;
31
+ else if (isAnchorModel(address)) {
32
+ this.nativeCol = address.nativeCol || 0;
33
+ this.nativeColOff = address.nativeColOff || 0;
34
+ this.nativeRow = address.nativeRow || 0;
35
+ this.nativeRowOff = address.nativeRowOff || 0;
27
36
  }
28
- else if (address.col !== undefined) {
29
- const simple = address;
30
- this.col = simple.col + offset;
31
- this.row = simple.row + offset;
37
+ else if (isSimpleAddress(address)) {
38
+ this.col = address.col + offset;
39
+ this.row = address.row + offset;
32
40
  }
33
41
  else {
34
42
  this.nativeCol = 0;
@@ -38,7 +46,13 @@ class Anchor {
38
46
  }
39
47
  }
40
48
  static asInstance(model) {
41
- return model instanceof Anchor || model == null ? model : new Anchor(undefined, model);
49
+ if (model == null) {
50
+ return null;
51
+ }
52
+ if (model instanceof Anchor) {
53
+ return model;
54
+ }
55
+ return new Anchor(undefined, model);
42
56
  }
43
57
  get col() {
44
58
  return this.nativeCol + Math.min(this.colWidth - 1, this.nativeColOff) / this.colWidth;
@@ -187,11 +187,30 @@ class Cell {
187
187
  this._value = Value.create(Value.getType(v), this, v);
188
188
  }
189
189
  get note() {
190
- return this._comment && this._comment.note;
190
+ if (!this._comment) {
191
+ return undefined;
192
+ }
193
+ const noteValue = this._comment.note;
194
+ return noteValue;
191
195
  }
192
196
  set note(note) {
193
197
  this._comment = new note_js_1.Note(note);
194
198
  }
199
+ // Internal comment accessor for row operations
200
+ get comment() {
201
+ return this._comment;
202
+ }
203
+ set comment(comment) {
204
+ if (comment === undefined) {
205
+ this._comment = undefined;
206
+ }
207
+ else if (comment instanceof note_js_1.Note) {
208
+ this._comment = comment;
209
+ }
210
+ else {
211
+ this._comment = new note_js_1.Note(comment);
212
+ }
213
+ }
195
214
  get text() {
196
215
  return this._value.toString();
197
216
  }
@@ -205,7 +224,7 @@ class Cell {
205
224
  // if this cell is a string, turn it into a Hyperlink
206
225
  if (this.type === Cell.Types.String) {
207
226
  this._value = Value.create(Cell.Types.Hyperlink, this, {
208
- text: this._value.value,
227
+ text: String(this._value.value),
209
228
  hyperlink
210
229
  });
211
230
  }
@@ -299,8 +318,6 @@ class Cell {
299
318
  }
300
319
  exports.Cell = Cell;
301
320
  Cell.Types = enums_js_1.Enums.ValueType;
302
- // =============================================================================
303
- // Internal Value Types
304
321
  class NullValue {
305
322
  constructor(cell) {
306
323
  this.model = {
@@ -417,7 +434,7 @@ class RichTextValue {
417
434
  this.model.value = value;
418
435
  }
419
436
  toString() {
420
- return this.model.value.richText.map((t) => t.text).join("");
437
+ return this.model.value.richText.map(t => t.text).join("");
421
438
  }
422
439
  get type() {
423
440
  return Cell.Types.RichText;
@@ -486,14 +503,11 @@ class HyperlinkValue {
486
503
  }
487
504
  }
488
505
  get value() {
489
- const v = {
490
- text: this.model.text,
491
- hyperlink: this.model.hyperlink
506
+ return {
507
+ text: this.model.text || "",
508
+ hyperlink: this.model.hyperlink || "",
509
+ tooltip: this.model.tooltip
492
510
  };
493
- if (this.model.tooltip) {
494
- v.tooltip = this.model.tooltip;
495
- }
496
- return v;
497
511
  }
498
512
  set value(value) {
499
513
  this.model.text = value.text;
@@ -604,24 +618,42 @@ class FormulaValue {
604
618
  }
605
619
  _copyModel(model) {
606
620
  const copy = {};
607
- const cp = (name) => {
608
- const value = model[name];
609
- if (value) {
610
- copy[name] = value;
611
- }
612
- };
613
- cp("formula");
614
- cp("result");
615
- cp("ref");
616
- cp("shareType");
617
- cp("sharedFormula");
621
+ if (model.formula) {
622
+ copy.formula = model.formula;
623
+ }
624
+ if (model.result !== undefined) {
625
+ copy.result = model.result;
626
+ }
627
+ if (model.ref) {
628
+ copy.ref = model.ref;
629
+ }
630
+ if (model.shareType) {
631
+ copy.shareType = model.shareType;
632
+ }
633
+ if (model.sharedFormula) {
634
+ copy.sharedFormula = model.sharedFormula;
635
+ }
618
636
  return copy;
619
637
  }
620
638
  get value() {
621
639
  return this._copyModel(this.model);
622
640
  }
623
641
  set value(value) {
624
- this.model = this._copyModel(value);
642
+ if (value.formula) {
643
+ this.model.formula = value.formula;
644
+ }
645
+ if (value.result !== undefined) {
646
+ this.model.result = value.result;
647
+ }
648
+ if (value.ref) {
649
+ this.model.ref = value.ref;
650
+ }
651
+ if (value.shareType) {
652
+ this.model.shareType = value.shareType;
653
+ }
654
+ if (value.sharedFormula) {
655
+ this.model.sharedFormula = value.sharedFormula;
656
+ }
625
657
  }
626
658
  validate(value) {
627
659
  switch (Value.getType(value)) {
@@ -685,11 +717,8 @@ class FormulaValue {
685
717
  if (v instanceof Date) {
686
718
  return enums_js_1.Enums.ValueType.Date;
687
719
  }
688
- if (v.text && v.hyperlink) {
689
- return enums_js_1.Enums.ValueType.Hyperlink;
690
- }
691
- if (v.formula) {
692
- return enums_js_1.Enums.ValueType.Formula;
720
+ if (typeof v === "object" && "error" in v) {
721
+ return enums_js_1.Enums.ValueType.Error;
693
722
  }
694
723
  return enums_js_1.Enums.ValueType.Null;
695
724
  }
@@ -872,20 +901,23 @@ const Value = {
872
901
  if (value instanceof Date) {
873
902
  return Cell.Types.Date;
874
903
  }
875
- if (value.text && value.hyperlink) {
876
- return Cell.Types.Hyperlink;
877
- }
878
- if (value.formula || value.sharedFormula) {
879
- return Cell.Types.Formula;
880
- }
881
- if (value.richText) {
882
- return Cell.Types.RichText;
883
- }
884
- if (value.sharedString) {
885
- return Cell.Types.SharedString;
886
- }
887
- if (value.error) {
888
- return Cell.Types.Error;
904
+ if (typeof value === "object") {
905
+ if ("text" in value && value.text && "hyperlink" in value && value.hyperlink) {
906
+ return Cell.Types.Hyperlink;
907
+ }
908
+ if (("formula" in value && value.formula) ||
909
+ ("sharedFormula" in value && value.sharedFormula)) {
910
+ return Cell.Types.Formula;
911
+ }
912
+ if ("richText" in value && value.richText) {
913
+ return Cell.Types.RichText;
914
+ }
915
+ if ("sharedString" in value && value.sharedString) {
916
+ return Cell.Types.SharedString;
917
+ }
918
+ if ("error" in value && value.error) {
919
+ return Cell.Types.Error;
920
+ }
889
921
  }
890
922
  return Cell.Types.JSON;
891
923
  },
@@ -5,9 +5,11 @@ const col_cache_js_1 = require("../utils/col-cache");
5
5
  const under_dash_js_1 = require("../utils/under-dash");
6
6
  const enums_js_1 = require("./enums");
7
7
  const DEFAULT_COLUMN_WIDTH = 9;
8
- // Column defines the column properties for 1 column.
9
- // This includes header rows, widths, key, (style), etc.
10
- // Worksheet will condense the columns as appropriate during serialization
8
+ /**
9
+ * Column defines the column properties for 1 column.
10
+ * This includes header rows, widths, key, (style), etc.
11
+ * Worksheet will condense the columns as appropriate during serialization
12
+ */
11
13
  class Column {
12
14
  constructor(worksheet, number, defn) {
13
15
  this._worksheet = worksheet;
@@ -23,6 +25,9 @@ class Column {
23
25
  get worksheet() {
24
26
  return this._worksheet;
25
27
  }
28
+ /**
29
+ * Column letter key
30
+ */
26
31
  get letter() {
27
32
  return col_cache_js_1.colCache.n2l(this._number);
28
33
  }
@@ -63,8 +68,17 @@ class Column {
63
68
  }
64
69
  }
65
70
  get headers() {
66
- return this._header && this._header instanceof Array ? this._header : [this._header];
71
+ if (Array.isArray(this._header)) {
72
+ return this._header;
73
+ }
74
+ if (this._header !== undefined) {
75
+ return [this._header];
76
+ }
77
+ return [];
67
78
  }
79
+ /**
80
+ * Can be a string to set one row high header or an array to set multi-row high header
81
+ */
68
82
  get header() {
69
83
  return this._header;
70
84
  }
@@ -79,6 +93,9 @@ class Column {
79
93
  this._header = undefined;
80
94
  }
81
95
  }
96
+ /**
97
+ * The name of the properties associated with this column in each row
98
+ */
82
99
  get key() {
83
100
  return this._key;
84
101
  }
@@ -92,18 +109,27 @@ class Column {
92
109
  this._worksheet.setColumnKey(this._key, this);
93
110
  }
94
111
  }
112
+ /**
113
+ * Hides the column
114
+ */
95
115
  get hidden() {
96
116
  return !!this._hidden;
97
117
  }
98
118
  set hidden(value) {
99
119
  this._hidden = value;
100
120
  }
121
+ /**
122
+ * Set an outline level for columns
123
+ */
101
124
  get outlineLevel() {
102
125
  return this._outlineLevel || 0;
103
126
  }
104
127
  set outlineLevel(value) {
105
128
  this._outlineLevel = value;
106
129
  }
130
+ /**
131
+ * Indicate the collapsed state based on outlineLevel
132
+ */
107
133
  get collapsed() {
108
134
  return !!(this._outlineLevel && this._outlineLevel >= this._worksheet.properties.outlineLevelCol);
109
135
  }
@@ -120,6 +146,12 @@ class Column {
120
146
  this.outlineLevel === other.outlineLevel &&
121
147
  (0, under_dash_js_1.isEqual)(this.style, other.style));
122
148
  }
149
+ equivalentToModel(model) {
150
+ return (this.width === model.width &&
151
+ this.hidden === model.hidden &&
152
+ this.outlineLevel === model.outlineLevel &&
153
+ (0, under_dash_js_1.isEqual)(this.style, model.style));
154
+ }
123
155
  get isDefault() {
124
156
  if (this.isCustomWidth) {
125
157
  return false;
@@ -139,16 +171,25 @@ class Column {
139
171
  get headerCount() {
140
172
  return this.headers.length;
141
173
  }
142
- eachCell(options, iteratee) {
174
+ eachCell(optionsOrCallback, maybeCallback) {
143
175
  const colNumber = this.number;
144
- if (!iteratee) {
145
- iteratee = options;
176
+ let options;
177
+ let callback;
178
+ if (typeof optionsOrCallback === "function") {
146
179
  options = {};
180
+ callback = optionsOrCallback;
181
+ }
182
+ else {
183
+ options = optionsOrCallback;
184
+ callback = maybeCallback;
147
185
  }
148
186
  this._worksheet.eachRow(options, (row, rowNumber) => {
149
- iteratee(row.getCell(colNumber), rowNumber);
187
+ callback(row.getCell(colNumber), rowNumber);
150
188
  });
151
189
  }
190
+ /**
191
+ * The cell values in the column
192
+ */
152
193
  get values() {
153
194
  const v = [];
154
195
  this.eachCell((cell, rowNumber) => {
@@ -174,48 +215,59 @@ class Column {
174
215
  }
175
216
  // =========================================================================
176
217
  // styles
177
- _applyStyle(name, value) {
178
- this.style[name] = value;
179
- this.eachCell((cell) => {
180
- cell[name] = value;
181
- });
182
- return value;
183
- }
184
218
  get numFmt() {
185
219
  return this.style.numFmt;
186
220
  }
187
221
  set numFmt(value) {
188
- this._applyStyle("numFmt", value);
222
+ this.style.numFmt = value;
223
+ this.eachCell(cell => {
224
+ cell.numFmt = value;
225
+ });
189
226
  }
190
227
  get font() {
191
228
  return this.style.font;
192
229
  }
193
230
  set font(value) {
194
- this._applyStyle("font", value);
231
+ this.style.font = value;
232
+ this.eachCell(cell => {
233
+ cell.font = value;
234
+ });
195
235
  }
196
236
  get alignment() {
197
237
  return this.style.alignment;
198
238
  }
199
239
  set alignment(value) {
200
- this._applyStyle("alignment", value);
240
+ this.style.alignment = value;
241
+ this.eachCell(cell => {
242
+ cell.alignment = value;
243
+ });
201
244
  }
202
245
  get protection() {
203
246
  return this.style.protection;
204
247
  }
205
248
  set protection(value) {
206
- this._applyStyle("protection", value);
249
+ this.style.protection = value;
250
+ this.eachCell(cell => {
251
+ cell.protection = value;
252
+ });
207
253
  }
208
254
  get border() {
209
255
  return this.style.border;
210
256
  }
211
257
  set border(value) {
212
- this._applyStyle("border", value);
258
+ this.style.border = value;
259
+ this.eachCell(cell => {
260
+ cell.border = value;
261
+ });
213
262
  }
214
263
  get fill() {
215
264
  return this.style.fill;
216
265
  }
217
266
  set fill(value) {
218
- this._applyStyle("fill", value);
267
+ this.style.fill = value;
268
+ this.eachCell(cell => {
269
+ cell.fill = value;
270
+ });
219
271
  }
220
272
  // =============================================================================
221
273
  // static functions
@@ -230,7 +282,7 @@ class Column {
230
282
  col = null;
231
283
  }
232
284
  }
233
- else if (!col || !column.equivalentTo(col)) {
285
+ else if (!col || !column.equivalentToModel(col)) {
234
286
  col = {
235
287
  min: index + 1,
236
288
  max: index + 1,
@@ -16,11 +16,15 @@ class DefinedNames {
16
16
  // add a name to a cell. locStr in the form SheetName!$col$row or SheetName!$c1$r1:$c2:$r2
17
17
  add(locStr, name) {
18
18
  const location = col_cache_js_1.colCache.decodeEx(locStr);
19
+ if ("error" in location) {
20
+ return; // Invalid reference, skip
21
+ }
19
22
  this.addEx(location, name);
20
23
  }
21
24
  addEx(location, name) {
22
25
  const matrix = this.getMatrix(name);
23
- if (location.top) {
26
+ if ("top" in location) {
27
+ // It's a range (DecodedRange has top/left/bottom/right from Location)
24
28
  for (let col = location.left; col <= location.right; col++) {
25
29
  for (let row = location.top; row <= location.bottom; row++) {
26
30
  const address = {
@@ -34,20 +38,54 @@ class DefinedNames {
34
38
  }
35
39
  }
36
40
  else {
41
+ // It's a single cell address
37
42
  matrix.addCellEx(location);
38
43
  }
39
44
  }
40
45
  remove(locStr, name) {
41
46
  const location = col_cache_js_1.colCache.decodeEx(locStr);
47
+ if ("error" in location) {
48
+ return; // Invalid reference, skip
49
+ }
42
50
  this.removeEx(location, name);
43
51
  }
44
52
  removeEx(location, name) {
45
53
  const matrix = this.getMatrix(name);
46
- matrix.removeCellEx(location);
54
+ if ("top" in location) {
55
+ // Range - remove each cell
56
+ for (let col = location.left; col <= location.right; col++) {
57
+ for (let row = location.top; row <= location.bottom; row++) {
58
+ matrix.removeCellEx({
59
+ sheetName: location.sheetName,
60
+ address: col_cache_js_1.colCache.n2l(col) + row,
61
+ row,
62
+ col
63
+ });
64
+ }
65
+ }
66
+ }
67
+ else {
68
+ matrix.removeCellEx(location);
69
+ }
47
70
  }
48
71
  removeAllNames(location) {
49
72
  Object.values(this.matrixMap).forEach((matrix) => {
50
- matrix.removeCellEx(location);
73
+ if ("top" in location) {
74
+ // Range - remove each cell
75
+ for (let col = location.left; col <= location.right; col++) {
76
+ for (let row = location.top; row <= location.bottom; row++) {
77
+ matrix.removeCellEx({
78
+ sheetName: location.sheetName,
79
+ address: col_cache_js_1.colCache.n2l(col) + row,
80
+ row,
81
+ col
82
+ });
83
+ }
84
+ }
85
+ }
86
+ else {
87
+ matrix.removeCellEx(location);
88
+ }
51
89
  });
52
90
  }
53
91
  forEach(callback) {
@@ -59,12 +97,16 @@ class DefinedNames {
59
97
  }
60
98
  // get all the names of a cell
61
99
  getNames(addressStr) {
62
- return this.getNamesEx(col_cache_js_1.colCache.decodeEx(addressStr));
100
+ const location = col_cache_js_1.colCache.decodeEx(addressStr);
101
+ if ("error" in location || "top" in location) {
102
+ return []; // Invalid reference or range not supported
103
+ }
104
+ return this.getNamesEx(location);
63
105
  }
64
106
  getNamesEx(address) {
65
107
  return Object.entries(this.matrixMap)
66
108
  .map(([name, matrix]) => matrix.findCellEx(address, false) && name)
67
- .filter(Boolean);
109
+ .filter((name) => Boolean(name));
68
110
  }
69
111
  _explore(matrix, cell) {
70
112
  cell.mark = false;
@@ -72,9 +114,13 @@ class DefinedNames {
72
114
  const range = new range_js_1.Range(cell.row, cell.col, cell.row, cell.col, sheetName);
73
115
  let x;
74
116
  let y;
117
+ // Helper to get cell with proper type
118
+ const getCell = (row, col) => {
119
+ return matrix.findCellAt(sheetName, row, col);
120
+ };
75
121
  // grow vertical - only one col to worry about
76
122
  function vGrow(yy, edge) {
77
- const c = matrix.findCellAt(sheetName, yy, cell.col);
123
+ const c = getCell(yy, cell.col);
78
124
  if (!c || !c.mark) {
79
125
  return false;
80
126
  }
@@ -88,7 +134,7 @@ class DefinedNames {
88
134
  function hGrow(xx, edge) {
89
135
  const cells = [];
90
136
  for (y = range.top; y <= range.bottom; y++) {
91
- const c = matrix.findCellAt(sheetName, y, xx);
137
+ const c = getCell(y, xx);
92
138
  if (c && c.mark) {
93
139
  cells.push(c);
94
140
  }
@@ -39,19 +39,22 @@ class Image {
39
39
  if (type === "image") {
40
40
  if (typeof range === "string") {
41
41
  const decoded = col_cache_js_1.colCache.decode(range);
42
- this.range = {
43
- tl: new anchor_js_1.Anchor(this.worksheet, { col: decoded.left, row: decoded.top }, -1),
44
- br: new anchor_js_1.Anchor(this.worksheet, { col: decoded.right, row: decoded.bottom }, 0),
45
- editAs: "oneCell"
46
- };
42
+ if ("top" in decoded) {
43
+ // It's a Location (range like "A1:C3")
44
+ this.range = {
45
+ tl: new anchor_js_1.Anchor(this.worksheet, { col: decoded.left, row: decoded.top }, -1),
46
+ br: new anchor_js_1.Anchor(this.worksheet, { col: decoded.right, row: decoded.bottom }, 0),
47
+ editAs: "oneCell"
48
+ };
49
+ }
47
50
  }
48
- else {
51
+ else if (range) {
49
52
  this.range = {
50
53
  tl: new anchor_js_1.Anchor(this.worksheet, range.tl, 0),
51
- br: range.br && new anchor_js_1.Anchor(this.worksheet, range.br, 0),
54
+ br: range.br ? new anchor_js_1.Anchor(this.worksheet, range.br, 0) : undefined,
52
55
  ext: range.ext,
53
56
  editAs: range.editAs,
54
- hyperlinks: hyperlinks || range.hyperlinks
57
+ hyperlinks: hyperlinks || ("hyperlinks" in range ? range.hyperlinks : undefined)
55
58
  };
56
59
  }
57
60
  }