read-excel-file 5.2.8 → 5.2.9

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 (77) hide show
  1. package/bundle/read-excel-file.min.js +2 -2
  2. package/bundle/read-excel-file.min.js.map +1 -1
  3. package/commonjs/read/coordinates.js +56 -0
  4. package/commonjs/read/coordinates.js.map +1 -0
  5. package/commonjs/read/dropEmptyColumns.js +52 -0
  6. package/commonjs/read/dropEmptyColumns.js.map +1 -0
  7. package/commonjs/read/dropEmptyColumns.test.js.map +1 -0
  8. package/commonjs/read/dropEmptyRows.js +55 -0
  9. package/commonjs/read/dropEmptyRows.js.map +1 -0
  10. package/commonjs/read/dropEmptyRows.test.js.map +1 -0
  11. package/commonjs/read/getData.js +99 -0
  12. package/commonjs/read/getData.js.map +1 -0
  13. package/commonjs/read/parseCell.js +71 -0
  14. package/commonjs/read/parseCell.js.map +1 -0
  15. package/commonjs/read/parseCellValue.js +204 -0
  16. package/commonjs/read/parseCellValue.js.map +1 -0
  17. package/commonjs/read/parseCells.js +30 -0
  18. package/commonjs/read/parseCells.js.map +1 -0
  19. package/commonjs/read/parseDimensions.js +47 -0
  20. package/commonjs/read/parseDimensions.js.map +1 -0
  21. package/commonjs/read/parseFilePaths.js +83 -0
  22. package/commonjs/read/parseFilePaths.js.map +1 -0
  23. package/commonjs/read/parseProperties.js +48 -0
  24. package/commonjs/read/parseProperties.js.map +1 -0
  25. package/commonjs/read/parseSharedStrings.js +17 -0
  26. package/commonjs/read/parseSharedStrings.js.map +1 -0
  27. package/commonjs/read/parseSheet.js +25 -0
  28. package/commonjs/read/parseSheet.js.map +1 -0
  29. package/commonjs/read/parseStyles.js +72 -0
  30. package/commonjs/read/parseStyles.js.map +1 -0
  31. package/commonjs/read/readXlsx.js +25 -657
  32. package/commonjs/read/readXlsx.js.map +1 -1
  33. package/commonjs/xml/xlsx-xpath.js +10 -0
  34. package/commonjs/xml/xlsx-xpath.js.map +1 -1
  35. package/commonjs/xml/xlsx.js +18 -3
  36. package/commonjs/xml/xlsx.js.map +1 -1
  37. package/commonjs/xml/xmlNode.js +1 -1
  38. package/commonjs/xml/xmlNode.js.map +1 -1
  39. package/modules/read/coordinates.js +48 -0
  40. package/modules/read/coordinates.js.map +1 -0
  41. package/modules/read/dropEmptyColumns.js +45 -0
  42. package/modules/read/dropEmptyColumns.js.map +1 -0
  43. package/modules/read/dropEmptyColumns.test.js.map +1 -0
  44. package/modules/read/dropEmptyRows.js +48 -0
  45. package/modules/read/dropEmptyRows.js.map +1 -0
  46. package/modules/read/dropEmptyRows.test.js.map +1 -0
  47. package/modules/read/getData.js +88 -0
  48. package/modules/read/getData.js.map +1 -0
  49. package/modules/read/parseCell.js +59 -0
  50. package/modules/read/parseCell.js.map +1 -0
  51. package/modules/read/parseCellValue.js +192 -0
  52. package/modules/read/parseCellValue.js.map +1 -0
  53. package/modules/read/parseCells.js +19 -0
  54. package/modules/read/parseCells.js.map +1 -0
  55. package/modules/read/parseDimensions.js +38 -0
  56. package/modules/read/parseDimensions.js.map +1 -0
  57. package/modules/read/parseFilePaths.js +76 -0
  58. package/modules/read/parseFilePaths.js.map +1 -0
  59. package/modules/read/parseProperties.js +40 -0
  60. package/modules/read/parseProperties.js.map +1 -0
  61. package/modules/read/parseSharedStrings.js +9 -0
  62. package/modules/read/parseSharedStrings.js.map +1 -0
  63. package/modules/read/parseSheet.js +13 -0
  64. package/modules/read/parseSheet.js.map +1 -0
  65. package/modules/read/parseStyles.js +64 -0
  66. package/modules/read/parseStyles.js.map +1 -0
  67. package/modules/read/readXlsx.js +20 -653
  68. package/modules/read/readXlsx.js.map +1 -1
  69. package/modules/xml/xlsx-xpath.js +6 -0
  70. package/modules/xml/xlsx-xpath.js.map +1 -1
  71. package/modules/xml/xlsx.js +16 -3
  72. package/modules/xml/xlsx.js.map +1 -1
  73. package/modules/xml/xmlNode.js +1 -1
  74. package/modules/xml/xmlNode.js.map +1 -1
  75. package/package.json +6 -5
  76. package/commonjs/read/readXlsx.test.js.map +0 -1
  77. package/modules/read/readXlsx.test.js.map +0 -1
@@ -1,11 +1,3 @@
1
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
-
3
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
-
5
- function _iterableToArrayLimit(arr, i) { var _i = arr && (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]); if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
6
-
7
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
-
9
1
  function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
2
 
11
3
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -18,12 +10,12 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
18
10
 
19
11
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
20
12
 
21
- import parseDate from './parseDate';
22
- import { getSharedStrings, getCellValue, getCellInlineStringValue, getCells, getDimensions, getBaseStyles, getCellStyles, getNumberFormats, getWorkbookProperties, getRelationships, getSheets } from '../xml/xlsx'; // Maps "A1"-like coordinates to `{ row, column }` numeric coordinates.
23
-
24
- var letters = ["", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]; // https://hexdocs.pm/xlsxir/number_styles.html
25
-
26
- var BUILT_IN_DATE_NUMBER_FORMAT_IDS = [14, 15, 16, 17, 18, 19, 20, 21, 22, 27, 30, 36, 45, 46, 47, 50, 57]; // "The minimum viable XLSX reader"
13
+ import parseProperties from './parseProperties';
14
+ import parseFilePaths from './parseFilePaths';
15
+ import parseStyles from './parseStyles';
16
+ import parseSharedStrings from './parseSharedStrings';
17
+ import parseSheet from './parseSheet';
18
+ import getData from './getData'; // For an introduction in reading `*.xlsx` files see "The minimum viable XLSX reader":
27
19
  // https://www.brendanlong.com/the-minimum-viable-xlsx-reader.html
28
20
 
29
21
  /**
@@ -48,7 +40,7 @@ export default function readXlsx(contents, xml) {
48
40
 
49
41
  var filePaths = parseFilePaths(contents['xl/_rels/workbook.xml.rels'], xml); // Default file path for "shared strings": "xl/sharedStrings.xml".
50
42
 
51
- var values = filePaths.sharedStrings ? parseValues(contents[filePaths.sharedStrings], xml) : []; // Default file path for "styles": "xl/styles.xml".
43
+ var values = filePaths.sharedStrings ? parseSharedStrings(contents[filePaths.sharedStrings], xml) : []; // Default file path for "styles": "xl/styles.xml".
52
44
 
53
45
  var styles = filePaths.styles ? parseStyles(contents[filePaths.styles], xml) : {};
54
46
  var properties = parseProperties(contents['xl/workbook.xml'], xml); // A feature for getting the list of sheets in an Excel file.
@@ -64,631 +56,42 @@ export default function readXlsx(contents, xml) {
64
56
  } // Find the sheet by name, or take the first one.
65
57
 
66
58
 
67
- var sheetRelationId;
68
-
69
- if (typeof options.sheet === 'number') {
70
- var _sheet = properties.sheets[options.sheet - 1];
71
- sheetRelationId = _sheet && _sheet.relationId;
72
- } else {
73
- for (var _iterator = _createForOfIteratorHelperLoose(properties.sheets), _step; !(_step = _iterator()).done;) {
74
- var _sheet2 = _step.value;
75
-
76
- if (_sheet2.name === options.sheet) {
77
- sheetRelationId = _sheet2.relationId;
78
- break;
79
- }
80
- }
81
- } // If the sheet wasn't found then throw an error.
59
+ var sheetId = getSheetId(options.sheet, properties.sheets); // If the sheet wasn't found then throw an error.
82
60
  // Example: "xl/worksheets/sheet1.xml".
83
61
 
84
-
85
- if (!sheetRelationId || !filePaths.sheets[sheetRelationId]) {
62
+ if (!sheetId || !filePaths.sheets[sheetId]) {
86
63
  throw createSheetNotFoundError(options.sheet, properties.sheets);
87
64
  } // Parse sheet data.
88
65
 
89
66
 
90
- var sheet = parseSheet(contents[filePaths.sheets[sheetRelationId]], xml, values, styles, properties, options); // If the sheet is empty.
91
-
92
- if (sheet.cells.length === 0) {
93
- if (options.properties) {
94
- return {
95
- data: [],
96
- properties: properties
97
- };
98
- }
99
-
100
- return [];
101
- }
102
-
103
- var _sheet$dimensions = _slicedToArray(sheet.dimensions, 2),
104
- leftTop = _sheet$dimensions[0],
105
- rightBottom = _sheet$dimensions[1];
106
-
107
- var colsCount = rightBottom.column - leftTop.column + 1;
108
- var rowsCount = rightBottom.row - leftTop.row + 1; // `sheet.cells` seem to not necessarily be sorted by row and column.
109
-
110
- var data = new Array(rowsCount);
111
- var i = 0;
112
-
113
- while (i < rowsCount) {
114
- data[i] = new Array(colsCount);
115
- var j = 0;
116
-
117
- while (j < colsCount) {
118
- data[i][j] = null;
119
- j++;
120
- }
121
-
122
- i++;
123
- }
124
-
125
- for (var _iterator2 = _createForOfIteratorHelperLoose(sheet.cells), _step2; !(_step2 = _iterator2()).done;) {
126
- var cell = _step2.value;
127
- var row = cell.row - leftTop.row;
128
- var column = cell.column - leftTop.column;
129
- data[row][column] = cell.value;
130
- } // Fill in the row map.
131
-
132
-
133
- var _options = options,
134
- rowMap = _options.rowMap;
135
-
136
- if (rowMap) {
137
- var _i2 = 0;
67
+ var sheet = parseSheet(contents[filePaths.sheets[sheetId]], xml, values, styles, properties, options); // Get spreadsheet data.
138
68
 
139
- while (_i2 < data.length) {
140
- rowMap[_i2] = _i2;
141
- _i2++;
142
- }
143
- }
144
-
145
- data = dropEmptyRows(dropEmptyColumns(data, {
146
- onlyTrimAtTheEnd: true
147
- }), {
148
- onlyTrimAtTheEnd: true,
149
- rowMap: rowMap
150
- });
151
-
152
- if (options.transformData) {
153
- data = options.transformData(data); // data = options.transformData(data, {
154
- // dropEmptyRowsAndColumns(data) {
155
- // return dropEmptyRows(dropEmptyColumns(data), { rowMap })
156
- // }
157
- // })
158
- }
69
+ var data = getData(sheet, options); // Can return properties, if required.
159
70
 
160
71
  if (options.properties) {
161
72
  return {
162
73
  data: data,
163
74
  properties: properties
164
75
  };
165
- }
166
-
167
- return data;
168
- }
169
-
170
- function calculateDimensions(cells) {
171
- var comparator = function comparator(a, b) {
172
- return a - b;
173
- };
174
-
175
- var allRows = cells.map(function (cell) {
176
- return cell.row;
177
- }).sort(comparator);
178
- var allCols = cells.map(function (cell) {
179
- return cell.column;
180
- }).sort(comparator);
181
- var minRow = allRows[0];
182
- var maxRow = allRows[allRows.length - 1];
183
- var minCol = allCols[0];
184
- var maxCol = allCols[allCols.length - 1];
185
- return [{
186
- row: minRow,
187
- column: minCol
188
- }, {
189
- row: maxRow,
190
- column: maxCol
191
- }];
192
- }
193
-
194
- function colToInt(col) {
195
- // `for ... of ...` would require Babel polyfill for iterating a string.
196
- var n = 0;
197
- var i = 0;
198
-
199
- while (i < col.length) {
200
- n *= 26;
201
- n += letters.indexOf(col[i]);
202
- i++;
203
- }
204
-
205
- return n;
206
- }
207
-
208
- function CellCoords(coords) {
209
- // Examples: "AA2091", "R988", "B1"
210
- coords = coords.split(/(\d+)/);
211
- return [// Row.
212
- parseInt(coords[1]), // Column.
213
- colToInt(coords[0].trim())];
214
- } // Example of a `<c/>`ell element:
215
- //
216
- // <c>
217
- // <f>string</f> — formula.
218
- // <v>string</v> — formula pre-computed value.
219
- // <is>
220
- // <t>string</t> — an `inlineStr` string (rather than a "common string" from a dictionary).
221
- // <r>
222
- // <rPr>
223
- // ...
224
- // </rPr>
225
- // <t>string</t>
226
- // </r>
227
- // <rPh sb="1" eb="1">
228
- // <t>string</t>
229
- // </rPh>
230
- // <phoneticPr fontId="1"/>
231
- // </is>
232
- // <extLst>
233
- // <ext>
234
- // <!--any element-->
235
- // </ext>
236
- // </extLst>
237
- // </c>
238
- //
239
-
240
-
241
- function Cell(cellNode, sheet, xml, values, styles, properties, options) {
242
- var coords = CellCoords(cellNode.getAttribute('r'));
243
- var valueElement = getCellValue(sheet, cellNode); // For `xpath`, `value` can be `undefined` while for native `DOMParser` it's `null`.
244
- // So using `value && ...` instead of `if (value !== undefined) { ... }` here
245
- // for uniform compatibility with both `xpath` and native `DOMParser`.
246
-
247
- var value = valueElement && valueElement.textContent;
248
- var type;
249
-
250
- if (cellNode.hasAttribute('t')) {
251
- type = cellNode.getAttribute('t');
252
- } else {
253
- // Default cell type is "n" (numeric).
254
- // http://www.datypic.com/sc/ooxml/t-ssml_CT_Cell.html
255
- type = 'n';
256
- } // Available Excel cell types:
257
- // https://github.com/SheetJS/sheetjs/blob/19620da30be2a7d7b9801938a0b9b1fd3c4c4b00/docbits/52_datatype.md
258
- //
259
- // Some other document (seems to be old):
260
- // http://webapp.docx4java.org/OnlineDemo/ecma376/SpreadsheetML/ST_CellType.html
261
- //
262
-
263
-
264
- switch (type) {
265
- // If the cell contains formula string.
266
- case 'str':
267
- value = value.trim();
268
-
269
- if (value === '') {
270
- value = undefined;
271
- }
272
-
273
- break;
274
- // If the cell contains an "inline" (not "shared") string.
275
-
276
- case 'inlineStr':
277
- value = getCellInlineStringValue(cellNode);
278
-
279
- if (value === undefined) {
280
- throw new Error("Unsupported \"inline string\" cell value structure: ".concat(cellNode.textContent));
281
- }
282
-
283
- value = value.trim();
284
-
285
- if (value === '') {
286
- value = undefined;
287
- }
288
-
289
- break;
290
- // If the cell contains a "shared" string.
291
- // "Shared" strings is a way for an Excel editor to reduce
292
- // the file size by storing "commonly used" strings in a dictionary
293
- // and then referring to such strings by their index in that dictionary.
294
-
295
- case 's':
296
- // If a cell has no value then there's no `<c/>` element for it.
297
- // If a `<c/>` element exists then it's not empty.
298
- // The `<v/>`alue is a key in the "shared strings" dictionary of the
299
- // XLSX file, so look it up in the `values` dictionary by the numeric key.
300
- value = values[parseInt(value)];
301
- value = value.trim();
302
-
303
- if (value === '') {
304
- value = undefined;
305
- }
306
-
307
- break;
308
-
309
- case 'b':
310
- value = value === '1' ? true : false;
311
- break;
312
- // Stub: blank stub cell that is ignored by data processing utilities.
313
-
314
- case 'z':
315
- value = undefined;
316
- break;
317
- // Error: `value` is a numeric code.
318
- // They also wrote: "and `w` property stores its common name".
319
- // It's unclear what they meant by that.
320
-
321
- case 'e':
322
- value = decodeError(value);
323
- break;
324
- // Date: a string to be parsed as a date.
325
- // (usually a string in "ISO 8601" format)
326
-
327
- case 'd':
328
- if (value === undefined) {
329
- break;
330
- }
76
+ } // Return spreadsheet data.
331
77
 
332
- value = new Date(value);
333
- break;
334
-
335
- case 'n':
336
- if (value === undefined) {
337
- break;
338
- }
339
-
340
- value = parseFloat(value); // XLSX does have "d" type for dates, but it's not commonly used.
341
- // specific format for dates.
342
- // Sometimes a date can be heuristically detected.
343
- // https://github.com/catamphetamine/read-excel-file/issues/3#issuecomment-395770777
344
- //
345
- // Format IDs:
346
- // https://xlsxwriter.readthedocs.io/format.html#format-set-num-format
347
- //
348
-
349
- if (cellNode.hasAttribute('s')) {
350
- var styleId = parseInt(cellNode.getAttribute('s'));
351
- var style = styles[styleId];
352
-
353
- if (!style) {
354
- throw new Error("Cell style not found: ".concat(styleId));
355
- }
356
-
357
- if (BUILT_IN_DATE_NUMBER_FORMAT_IDS.indexOf(parseInt(style.numberFormat.id)) >= 0 || options.dateFormat && style.numberFormat.template === options.dateFormat || options.smartDateParser !== false && style.numberFormat.template && isDateTemplate(style.numberFormat.template)) {
358
- value = parseDate(value, properties);
359
- }
360
- }
361
-
362
- break;
363
-
364
- default:
365
- throw new TypeError("Cell type not supported: ".concat(type));
366
- } // Convert empty values to `null`.
367
-
368
-
369
- if (value === undefined) {
370
- value = null;
371
- }
372
-
373
- return {
374
- row: coords[0],
375
- column: coords[1],
376
- value: value
377
- };
378
- }
379
-
380
- export function dropEmptyRows(data) {
381
- var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
382
- rowMap = _ref2.rowMap,
383
- _ref2$accessor = _ref2.accessor,
384
- accessor = _ref2$accessor === void 0 ? function (_) {
385
- return _;
386
- } : _ref2$accessor,
387
- onlyTrimAtTheEnd = _ref2.onlyTrimAtTheEnd;
388
-
389
- // Drop empty rows.
390
- var i = data.length - 1;
391
-
392
- while (i >= 0) {
393
- // Check if the row is empty.
394
- var empty = true;
395
-
396
- for (var _iterator3 = _createForOfIteratorHelperLoose(data[i]), _step3; !(_step3 = _iterator3()).done;) {
397
- var cell = _step3.value;
398
-
399
- if (accessor(cell) !== null) {
400
- empty = false;
401
- break;
402
- }
403
- } // Remove the empty row.
404
-
405
-
406
- if (empty) {
407
- data.splice(i, 1);
408
-
409
- if (rowMap) {
410
- rowMap.splice(i, 1);
411
- }
412
- } else if (onlyTrimAtTheEnd) {
413
- break;
414
- }
415
-
416
- i--;
417
- }
418
-
419
- return data;
420
- }
421
- export function dropEmptyColumns(data) {
422
- var _ref3 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
423
- _ref3$accessor = _ref3.accessor,
424
- accessor = _ref3$accessor === void 0 ? function (_) {
425
- return _;
426
- } : _ref3$accessor,
427
- onlyTrimAtTheEnd = _ref3.onlyTrimAtTheEnd;
428
-
429
- var i = data[0].length - 1;
430
-
431
- while (i >= 0) {
432
- var empty = true;
433
-
434
- for (var _iterator4 = _createForOfIteratorHelperLoose(data), _step4; !(_step4 = _iterator4()).done;) {
435
- var row = _step4.value;
436
-
437
- if (accessor(row[i]) !== null) {
438
- empty = false;
439
- break;
440
- }
441
- }
442
-
443
- if (empty) {
444
- var j = 0;
445
-
446
- while (j < data.length) {
447
- data[j].splice(i, 1);
448
- j++;
449
- }
450
- } else if (onlyTrimAtTheEnd) {
451
- break;
452
- }
453
-
454
- i--;
455
- }
456
78
 
457
79
  return data;
458
80
  }
459
81
 
460
- function parseSheet(content, xml, values, styles, properties, options) {
461
- var sheet = xml.createDocument(content);
462
- var cells = getCells(sheet);
463
-
464
- if (cells.length === 0) {
465
- return {
466
- cells: []
467
- };
82
+ function getSheetId(sheet, sheets) {
83
+ if (typeof sheet === 'number') {
84
+ var _sheet = sheets[sheet - 1];
85
+ return _sheet && _sheet.relationId;
468
86
  }
469
87
 
470
- cells = cells.map(function (node) {
471
- return Cell(node, sheet, xml, values, styles, properties, options);
472
- });
473
- var dimensions = getDimensions(sheet);
88
+ for (var _iterator = _createForOfIteratorHelperLoose(sheets), _step; !(_step = _iterator()).done;) {
89
+ var _sheet2 = _step.value;
474
90
 
475
- if (dimensions) {
476
- dimensions = dimensions.split(':').map(CellCoords).map(function (_ref4) {
477
- var _ref5 = _slicedToArray(_ref4, 2),
478
- row = _ref5[0],
479
- column = _ref5[1];
480
-
481
- return {
482
- row: row,
483
- column: column
484
- };
485
- }); // When there's only a single cell on a sheet
486
- // there can sometimes be just "A1" for the dimensions string.
487
-
488
- if (dimensions.length === 1) {
489
- dimensions = [dimensions[0], dimensions[0]];
91
+ if (_sheet2.name === sheet) {
92
+ return _sheet2.relationId;
490
93
  }
491
- } else {
492
- dimensions = calculateDimensions(cells);
493
- }
494
-
495
- return {
496
- cells: cells,
497
- dimensions: dimensions
498
- };
499
- }
500
-
501
- function parseValues(content, xml) {
502
- if (!content) {
503
- return [];
504
94
  }
505
-
506
- return getSharedStrings(xml.createDocument(content));
507
- } // http://officeopenxml.com/SSstyles.php
508
- // Returns an array of cell styles.
509
- // A cell style index is its ID.
510
-
511
-
512
- function parseStyles(content, xml) {
513
- if (!content) {
514
- return {};
515
- } // https://social.msdn.microsoft.com/Forums/sqlserver/en-US/708978af-b598-45c4-a598-d3518a5a09f0/howwhen-is-cellstylexfs-vs-cellxfs-applied-to-a-cell?forum=os_binaryfile
516
- // https://www.office-forums.com/threads/cellxfs-cellstylexfs.2163519/
517
-
518
-
519
- var doc = xml.createDocument(content);
520
- var baseStyles = getBaseStyles(doc).map(parseCellStyle);
521
- var numberFormats = getNumberFormats(doc).map(parseNumberFormatStyle).reduce(function (formats, format) {
522
- // Format ID is a numeric index.
523
- // There're some standard "built-in" formats (in Excel) up to about `100`.
524
- formats[format.id] = format;
525
- return formats;
526
- }, []);
527
-
528
- var getCellStyle = function getCellStyle(xf) {
529
- if (xf.hasAttribute('xfId')) {
530
- return _objectSpread(_objectSpread({}, baseStyles[xf.xfId]), parseCellStyle(xf, numberFormats));
531
- }
532
-
533
- return parseCellStyle(xf, numberFormats);
534
- };
535
-
536
- return getCellStyles(doc).map(getCellStyle);
537
- }
538
-
539
- function parseNumberFormatStyle(numFmt) {
540
- return {
541
- id: numFmt.getAttribute('numFmtId'),
542
- template: numFmt.getAttribute('formatCode')
543
- };
544
- } // http://www.datypic.com/sc/ooxml/e-ssml_xf-2.html
545
-
546
-
547
- function parseCellStyle(xf, numFmts) {
548
- var style = {};
549
-
550
- if (xf.hasAttribute('numFmtId')) {
551
- var numberFormatId = xf.getAttribute('numFmtId'); // Built-in number formats don't have a `<numFmt/>` element in `styles.xml`.
552
- // https://hexdocs.pm/xlsxir/number_styles.html
553
-
554
- if (numFmts[numberFormatId]) {
555
- style.numberFormat = numFmts[numberFormatId];
556
- } else {
557
- style.numberFormat = {
558
- id: numberFormatId
559
- };
560
- }
561
- }
562
-
563
- return style;
564
- } // I guess `xl/workbook.xml` file should always be present inside the *.xlsx archive.
565
-
566
-
567
- function parseProperties(content, xml) {
568
- var book = xml.createDocument(content);
569
- var properties = {}; // Read `<workbookPr/>` element to detect whether dates are 1900-based or 1904-based.
570
- // https://support.microsoft.com/en-gb/help/214330/differences-between-the-1900-and-the-1904-date-system-in-excel
571
- // http://webapp.docx4java.org/OnlineDemo/ecma376/SpreadsheetML/workbookPr.html
572
-
573
- var workbookProperties = getWorkbookProperties(book);
574
-
575
- if (workbookProperties && workbookProperties.getAttribute('date1904') === '1') {
576
- properties.epoch1904 = true;
577
- } // Get sheets info (indexes, names, if they're available).
578
- // Example:
579
- // <sheets>
580
- // <sheet
581
- // xmlns:ns="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
582
- // name="Sheet1"
583
- // sheetId="1"
584
- // ns:id="rId3"/>
585
- // </sheets>
586
- // http://www.datypic.com/sc/ooxml/e-ssml_sheet-1.html
587
-
588
-
589
- properties.sheets = [];
590
-
591
- var addSheetInfo = function addSheetInfo(sheet) {
592
- if (sheet.getAttribute('name')) {
593
- properties.sheets.push({
594
- id: sheet.getAttribute('sheetId'),
595
- name: sheet.getAttribute('name'),
596
- relationId: sheet.getAttribute('r:id')
597
- });
598
- }
599
- };
600
-
601
- getSheets(book).forEach(addSheetInfo);
602
- return properties;
603
- }
604
- /**
605
- * Returns sheet file paths.
606
- * Seems that the correct place to look for the `sheetId` -> `filename` mapping
607
- * is `xl/_rels/workbook.xml.rels` file.
608
- * https://github.com/tidyverse/readxl/issues/104
609
- * @param {string} content — `xl/_rels/workbook.xml.rels` file contents.
610
- * @param {object} xml
611
- * @return {object}
612
- */
613
-
614
-
615
- function parseFilePaths(content, xml) {
616
- // Example:
617
- // <Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
618
- // ...
619
- // <Relationship
620
- // Id="rId3"
621
- // Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"
622
- // Target="worksheets/sheet1.xml"/>
623
- // </Relationships>
624
- var document = xml.createDocument(content);
625
- var filePaths = {
626
- sheets: {},
627
- sharedStrings: undefined,
628
- styles: undefined
629
- };
630
-
631
- var addFilePathInfo = function addFilePathInfo(relationship) {
632
- var filePath = relationship.getAttribute('Target');
633
- var fileType = relationship.getAttribute('Type');
634
-
635
- switch (fileType) {
636
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles':
637
- filePaths.styles = getFilePath(filePath);
638
- break;
639
-
640
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings':
641
- filePaths.sharedStrings = getFilePath(filePath);
642
- break;
643
-
644
- case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet':
645
- filePaths.sheets[relationship.getAttribute('Id')] = getFilePath(filePath);
646
- break;
647
- }
648
- };
649
-
650
- getRelationships(document).forEach(addFilePathInfo); // Seems like "sharedStrings.xml" is not required to exist.
651
- // For example, when the spreadsheet doesn't contain any strings.
652
- // https://github.com/catamphetamine/read-excel-file/issues/85
653
- // if (!filePaths.sharedStrings) {
654
- // throw new Error('"sharedStrings.xml" file not found in the *.xlsx file')
655
- // }
656
-
657
- return filePaths;
658
- }
659
-
660
- function getFilePath(path) {
661
- // Normally, `path` is a relative path inside the ZIP archive,
662
- // like "worksheets/sheet1.xml", or "sharedStrings.xml", or "styles.xml".
663
- // There has been one weird case when file path was an absolute path,
664
- // like "/xl/worksheets/sheet1.xml" (specifically for sheets):
665
- // https://github.com/catamphetamine/read-excel-file/pull/95
666
- // Other libraries (like `xlsx`) and software (like Google Docs)
667
- // seem to support such absolute file paths, so this library does too.
668
- if (path[0] === '/') {
669
- return path.slice('/'.length);
670
- } // // Seems like a path could also be a URL.
671
- // // http://officeopenxml.com/anatomyofOOXML-xlsx.php
672
- // if (/^[a-z]+\:\/\//.test(path)) {
673
- // return path
674
- // }
675
-
676
-
677
- return 'xl/' + path;
678
- }
679
-
680
- function isDateTemplate(template) {
681
- var tokens = template.split(/\W+/);
682
-
683
- for (var _iterator5 = _createForOfIteratorHelperLoose(tokens), _step5; !(_step5 = _iterator5()).done;) {
684
- var token = _step5.value;
685
-
686
- if (['MM', 'DD', 'YY', 'YYYY'].indexOf(token) < 0) {
687
- return false;
688
- }
689
- }
690
-
691
- return true;
692
95
  }
693
96
 
694
97
  function createSheetNotFoundError(sheet, sheets) {
@@ -696,41 +99,5 @@ function createSheetNotFoundError(sheet, sheets) {
696
99
  return "\"".concat(sheet.name, "\" (#").concat(i + 1, ")");
697
100
  }).join(', ');
698
101
  return new Error("Sheet ".concat(typeof sheet === 'number' ? '#' + sheet : '"' + sheet + '"', " not found in the *.xlsx file.").concat(sheets ? ' Available sheets: ' + sheetsList + '.' : ''));
699
- } // Decodes numeric error code to a string code.
700
- // https://github.com/SheetJS/sheetjs/blob/19620da30be2a7d7b9801938a0b9b1fd3c4c4b00/docbits/52_datatype.md
701
-
702
-
703
- function decodeError(errorCode) {
704
- // While the error values are determined by the application,
705
- // the following are some example error values that could be used:
706
- switch (errorCode) {
707
- case 0x00:
708
- return '#NULL!';
709
-
710
- case 0x07:
711
- return '#DIV/0!';
712
-
713
- case 0x0F:
714
- return '#VALUE!';
715
-
716
- case 0x17:
717
- return '#REF!';
718
-
719
- case 0x1D:
720
- return '#NAME?';
721
-
722
- case 0x24:
723
- return '#NUM!';
724
-
725
- case 0x2A:
726
- return '#N/A';
727
-
728
- case 0x2B:
729
- return '#GETTING_DATA';
730
-
731
- default:
732
- // Such error code doesn't exist. I made it up.
733
- return "#ERROR_".concat(errorCode);
734
- }
735
102
  }
736
103
  //# sourceMappingURL=readXlsx.js.map