read-excel-file 7.0.3 → 8.0.1
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/CHANGELOG.md +37 -0
- package/README.md +212 -205
- package/browser/index.cjs +8 -5
- package/browser/index.d.ts +58 -16
- package/browser/index.js +7 -5
- package/browser/input.d.ts +1 -0
- package/bundle/read-excel-file.min.js +1 -1
- package/bundle/read-excel-file.min.js.map +1 -1
- package/commonjs/export/parseSheet.js +20 -0
- package/commonjs/export/parseSheet.js.map +1 -0
- package/commonjs/export/readSheetBrowser.js +29 -0
- package/commonjs/export/readSheetBrowser.js.map +1 -0
- package/commonjs/export/readSheetNode.js +29 -0
- package/commonjs/export/readSheetNode.js.map +1 -0
- package/commonjs/export/readSheetUniversal.js +29 -0
- package/commonjs/export/readSheetUniversal.js.map +1 -0
- package/commonjs/export/readSheetWebWorker.js +29 -0
- package/commonjs/export/readSheetWebWorker.js.map +1 -0
- package/commonjs/export/readXlsxFileBrowser.js +6 -8
- package/commonjs/export/readXlsxFileBrowser.js.map +1 -1
- package/commonjs/export/readXlsxFileNode.js +7 -9
- package/commonjs/export/readXlsxFileNode.js.map +1 -1
- package/commonjs/export/readXlsxFileUniversal.js +7 -9
- package/commonjs/export/readXlsxFileUniversal.js.map +1 -1
- package/commonjs/export/readXlsxFileWebWorker.js +6 -8
- package/commonjs/export/readXlsxFileWebWorker.js.map +1 -1
- package/commonjs/export/unpackXlsxFileBrowser.js +2 -1
- package/commonjs/export/unpackXlsxFileBrowser.js.map +1 -1
- package/commonjs/export/unpackXlsxFileNode.js +4 -3
- package/commonjs/export/unpackXlsxFileNode.js.map +1 -1
- package/commonjs/export/unpackXlsxFileUniversal.js +13 -3
- package/commonjs/export/unpackXlsxFileUniversal.js.map +1 -1
- package/commonjs/parseData/InvalidError.js.map +1 -0
- package/commonjs/parseData/parseData.js +503 -0
- package/commonjs/parseData/parseData.js.map +1 -0
- package/commonjs/parseData/parseData.test.js.map +1 -0
- package/commonjs/{types → parseData/types}/Boolean.js +1 -1
- package/commonjs/parseData/types/Boolean.js.map +1 -0
- package/commonjs/parseData/types/Date.js +21 -0
- package/commonjs/parseData/types/Date.js.map +1 -0
- package/commonjs/{types → parseData/types}/Number.js +1 -1
- package/commonjs/parseData/types/Number.js.map +1 -0
- package/commonjs/{types → parseData/types}/String.js +1 -1
- package/commonjs/parseData/types/String.js.map +1 -0
- package/commonjs/{types → parseData/types/additional}/Email.js +3 -3
- package/commonjs/parseData/types/additional/Email.js.map +1 -0
- package/commonjs/parseData/types/additional/Email.test.js.map +1 -0
- package/commonjs/{types → parseData/types/additional}/Integer.js +2 -2
- package/commonjs/parseData/types/additional/Integer.js.map +1 -0
- package/commonjs/parseData/types/additional/Integer.test.js.map +1 -0
- package/commonjs/{types → parseData/types/additional}/URL.js +3 -3
- package/commonjs/parseData/types/additional/URL.js.map +1 -0
- package/commonjs/parseData/types/additional/URL.test.js.map +1 -0
- package/commonjs/xlsx/{getData.js → convertCellsToData2dArray.js} +16 -37
- package/commonjs/xlsx/convertCellsToData2dArray.js.map +1 -0
- package/commonjs/xlsx/{isDateTimestamp.js → isDateFormat.js} +58 -56
- package/commonjs/xlsx/isDateFormat.js.map +1 -0
- package/commonjs/xlsx/isDateFormat.test.js.map +1 -0
- package/commonjs/xlsx/isDateFormatStyle.js +193 -0
- package/commonjs/xlsx/isDateFormatStyle.js.map +1 -0
- package/commonjs/xlsx/parseCell.js +16 -18
- package/commonjs/xlsx/parseCell.js.map +1 -1
- package/commonjs/xlsx/parseCellCoordinates.js +44 -0
- package/commonjs/xlsx/parseCellCoordinates.js.map +1 -0
- package/commonjs/xlsx/parseCellValue.js +14 -11
- package/commonjs/xlsx/parseCellValue.js.map +1 -1
- package/commonjs/xlsx/parseCells.js +14 -6
- package/commonjs/xlsx/parseCells.js.map +1 -1
- package/commonjs/xlsx/parseExcelDate.js +139 -0
- package/commonjs/xlsx/parseExcelDate.js.map +1 -0
- package/commonjs/xlsx/parseExcelDate.test.js.map +1 -0
- package/commonjs/xlsx/parseSheet.js +9 -11
- package/commonjs/xlsx/parseSheet.js.map +1 -1
- package/commonjs/xlsx/{parseDimensions.js → parseSheetDimensions.js} +7 -6
- package/commonjs/xlsx/parseSheetDimensions.js.map +1 -0
- package/commonjs/xlsx/parseSpreadsheetContents.js +96 -0
- package/commonjs/xlsx/parseSpreadsheetContents.js.map +1 -0
- package/commonjs/xlsx/parseSpreadsheetInfo.js +47 -0
- package/commonjs/xlsx/parseSpreadsheetInfo.js.map +1 -0
- package/commonjs/xlsx/reconstructSheetDimensionsFromSheetCells.js +29 -0
- package/commonjs/xlsx/reconstructSheetDimensionsFromSheetCells.js.map +1 -0
- package/commonjs/xml/xlsx.js +9 -9
- package/commonjs/xml/xlsx.js.map +1 -1
- package/commonjs/xml/xpath/xlsx-xpath.js +8 -8
- package/commonjs/xml/xpath/xlsx-xpath.js.map +1 -1
- package/commonjs/xml/xpath/xpathBrowser.js +4 -4
- package/commonjs/xml/xpath/xpathBrowser.js.map +1 -1
- package/commonjs/xml/xpath/xpathNode.js +2 -2
- package/commonjs/xml/xpath/xpathNode.js.map +1 -1
- package/modules/export/parseSheet.js +13 -0
- package/modules/export/parseSheet.js.map +1 -0
- package/modules/export/readSheetBrowser.js +23 -0
- package/modules/export/readSheetBrowser.js.map +1 -0
- package/modules/export/readSheetNode.js +23 -0
- package/modules/export/readSheetNode.js.map +1 -0
- package/modules/export/readSheetUniversal.js +23 -0
- package/modules/export/readSheetUniversal.js.map +1 -0
- package/modules/export/readSheetWebWorker.js +23 -0
- package/modules/export/readSheetWebWorker.js.map +1 -0
- package/modules/export/readXlsxFileBrowser.js +6 -8
- package/modules/export/readXlsxFileBrowser.js.map +1 -1
- package/modules/export/readXlsxFileNode.js +7 -9
- package/modules/export/readXlsxFileNode.js.map +1 -1
- package/modules/export/readXlsxFileUniversal.js +7 -9
- package/modules/export/readXlsxFileUniversal.js.map +1 -1
- package/modules/export/readXlsxFileWebWorker.js +6 -8
- package/modules/export/readXlsxFileWebWorker.js.map +1 -1
- package/modules/export/unpackXlsxFileBrowser.js +3 -1
- package/modules/export/unpackXlsxFileBrowser.js.map +1 -1
- package/modules/export/unpackXlsxFileNode.js +4 -3
- package/modules/export/unpackXlsxFileNode.js.map +1 -1
- package/modules/export/unpackXlsxFileUniversal.js +13 -3
- package/modules/export/unpackXlsxFileUniversal.js.map +1 -1
- package/modules/parseData/InvalidError.js.map +1 -0
- package/modules/parseData/parseData.js +494 -0
- package/modules/parseData/parseData.js.map +1 -0
- package/modules/parseData/parseData.test.js.map +1 -0
- package/modules/{types → parseData/types}/Boolean.js +1 -1
- package/modules/parseData/types/Boolean.js.map +1 -0
- package/modules/parseData/types/Date.js +14 -0
- package/modules/parseData/types/Date.js.map +1 -0
- package/modules/{types → parseData/types}/Number.js +1 -1
- package/modules/parseData/types/Number.js.map +1 -0
- package/modules/{types → parseData/types}/String.js +1 -1
- package/modules/parseData/types/String.js.map +1 -0
- package/modules/{types → parseData/types/additional}/Email.js +3 -3
- package/modules/parseData/types/additional/Email.js.map +1 -0
- package/modules/parseData/types/additional/Email.test.js.map +1 -0
- package/modules/{types → parseData/types/additional}/Integer.js +2 -2
- package/modules/parseData/types/additional/Integer.js.map +1 -0
- package/modules/parseData/types/additional/Integer.test.js.map +1 -0
- package/modules/{types → parseData/types/additional}/URL.js +3 -3
- package/modules/parseData/types/additional/URL.js.map +1 -0
- package/modules/parseData/types/additional/URL.test.js.map +1 -0
- package/modules/xlsx/{getData.js → convertCellsToData2dArray.js} +15 -36
- package/modules/xlsx/convertCellsToData2dArray.js.map +1 -0
- package/modules/xlsx/{isDateTimestamp.js → isDateFormat.js} +57 -55
- package/modules/xlsx/isDateFormat.js.map +1 -0
- package/modules/xlsx/isDateFormat.test.js.map +1 -0
- package/modules/xlsx/isDateFormatStyle.js +186 -0
- package/modules/xlsx/isDateFormatStyle.js.map +1 -0
- package/modules/xlsx/parseCell.js +17 -19
- package/modules/xlsx/parseCell.js.map +1 -1
- package/modules/xlsx/parseCellCoordinates.js +38 -0
- package/modules/xlsx/parseCellCoordinates.js.map +1 -0
- package/modules/xlsx/parseCellValue.js +14 -11
- package/modules/xlsx/parseCellValue.js.map +1 -1
- package/modules/xlsx/parseCells.js +14 -6
- package/modules/xlsx/parseCells.js.map +1 -1
- package/modules/xlsx/parseExcelDate.js +133 -0
- package/modules/xlsx/parseExcelDate.js.map +1 -0
- package/modules/xlsx/parseExcelDate.test.js.map +1 -0
- package/modules/xlsx/parseSheet.js +9 -11
- package/modules/xlsx/parseSheet.js.map +1 -1
- package/modules/xlsx/{parseDimensions.js → parseSheetDimensions.js} +4 -4
- package/modules/xlsx/parseSheetDimensions.js.map +1 -0
- package/modules/xlsx/parseSpreadsheetContents.js +91 -0
- package/modules/xlsx/parseSpreadsheetContents.js.map +1 -0
- package/modules/xlsx/parseSpreadsheetInfo.js +42 -0
- package/modules/xlsx/parseSpreadsheetInfo.js.map +1 -0
- package/modules/xlsx/reconstructSheetDimensionsFromSheetCells.js +23 -0
- package/modules/xlsx/reconstructSheetDimensionsFromSheetCells.js.map +1 -0
- package/modules/xml/xlsx.js +6 -6
- package/modules/xml/xlsx.js.map +1 -1
- package/modules/xml/xpath/xlsx-xpath.js +6 -6
- package/modules/xml/xpath/xlsx-xpath.js.map +1 -1
- package/modules/xml/xpath/xpathBrowser.js +4 -4
- package/modules/xml/xpath/xpathBrowser.js.map +1 -1
- package/modules/xml/xpath/xpathNode.js +2 -2
- package/modules/xml/xpath/xpathNode.js.map +1 -1
- package/node/index.cjs +8 -5
- package/node/index.d.ts +56 -21
- package/node/index.js +7 -5
- package/node/input.d.ts +5 -0
- package/package.json +1 -1
- package/types/parseData/parseData.d.ts +38 -0
- package/types/parseData/parseDataError.d.ts +239 -0
- package/types/parseData/parseDataSchema.d.ts +48 -0
- package/types/parseData/parseDataValueType.d.ts +45 -0
- package/types/types.d.ts +20 -0
- package/universal/index.cjs +8 -5
- package/universal/index.d.ts +58 -16
- package/universal/index.js +7 -5
- package/universal/input.d.ts +1 -0
- package/web-worker/index.cjs +8 -5
- package/web-worker/index.d.ts +58 -16
- package/web-worker/index.js +7 -5
- package/web-worker/input.d.ts +1 -0
- package/commonjs/export/readSheetNamesBrowser.js +0 -23
- package/commonjs/export/readSheetNamesBrowser.js.map +0 -1
- package/commonjs/export/readSheetNamesNode.js +0 -23
- package/commonjs/export/readSheetNamesNode.js.map +0 -1
- package/commonjs/export/readSheetNamesUniversal.js +0 -23
- package/commonjs/export/readSheetNamesUniversal.js.map +0 -1
- package/commonjs/export/readSheetNamesWebWorker.js +0 -23
- package/commonjs/export/readSheetNamesWebWorker.js.map +0 -1
- package/commonjs/types/Boolean.js.map +0 -1
- package/commonjs/types/Date.js +0 -36
- package/commonjs/types/Date.js.map +0 -1
- package/commonjs/types/Email.js.map +0 -1
- package/commonjs/types/Email.test.js.map +0 -1
- package/commonjs/types/Integer.js.map +0 -1
- package/commonjs/types/Integer.test.js.map +0 -1
- package/commonjs/types/InvalidError.js.map +0 -1
- package/commonjs/types/Number.js.map +0 -1
- package/commonjs/types/String.js.map +0 -1
- package/commonjs/types/URL.js.map +0 -1
- package/commonjs/types/URL.test.js.map +0 -1
- package/commonjs/xlsx/coordinates.js +0 -55
- package/commonjs/xlsx/coordinates.js.map +0 -1
- package/commonjs/xlsx/getData.js.map +0 -1
- package/commonjs/xlsx/isDateTimestamp.js.map +0 -1
- package/commonjs/xlsx/parseDate.js +0 -73
- package/commonjs/xlsx/parseDate.js.map +0 -1
- package/commonjs/xlsx/parseDate.test.js.map +0 -1
- package/commonjs/xlsx/parseDimensions.js.map +0 -1
- package/commonjs/xlsx/parseProperties.js +0 -46
- package/commonjs/xlsx/parseProperties.js.map +0 -1
- package/commonjs/xlsx/parseXlsxFileContents.js +0 -119
- package/commonjs/xlsx/parseXlsxFileContents.js.map +0 -1
- package/commonjs/xlsx/parseXlsxFileContentsWithOptionalSchema.js +0 -45
- package/commonjs/xlsx/parseXlsxFileContentsWithOptionalSchema.js.map +0 -1
- package/commonjs/xlsx/schema/mapToObjects.js +0 -482
- package/commonjs/xlsx/schema/mapToObjects.js.map +0 -1
- package/commonjs/xlsx/schema/mapToObjects.test.js.map +0 -1
- package/modules/export/readSheetNamesBrowser.js +0 -17
- package/modules/export/readSheetNamesBrowser.js.map +0 -1
- package/modules/export/readSheetNamesNode.js +0 -17
- package/modules/export/readSheetNamesNode.js.map +0 -1
- package/modules/export/readSheetNamesUniversal.js +0 -17
- package/modules/export/readSheetNamesUniversal.js.map +0 -1
- package/modules/export/readSheetNamesWebWorker.js +0 -17
- package/modules/export/readSheetNamesWebWorker.js.map +0 -1
- package/modules/types/Boolean.js.map +0 -1
- package/modules/types/Date.js +0 -29
- package/modules/types/Date.js.map +0 -1
- package/modules/types/Email.js.map +0 -1
- package/modules/types/Email.test.js.map +0 -1
- package/modules/types/Integer.js.map +0 -1
- package/modules/types/Integer.test.js.map +0 -1
- package/modules/types/InvalidError.js.map +0 -1
- package/modules/types/Number.js.map +0 -1
- package/modules/types/String.js.map +0 -1
- package/modules/types/URL.js.map +0 -1
- package/modules/types/URL.test.js.map +0 -1
- package/modules/xlsx/coordinates.js +0 -48
- package/modules/xlsx/coordinates.js.map +0 -1
- package/modules/xlsx/getData.js.map +0 -1
- package/modules/xlsx/isDateTimestamp.js.map +0 -1
- package/modules/xlsx/parseDate.js +0 -67
- package/modules/xlsx/parseDate.js.map +0 -1
- package/modules/xlsx/parseDate.test.js.map +0 -1
- package/modules/xlsx/parseDimensions.js.map +0 -1
- package/modules/xlsx/parseProperties.js +0 -41
- package/modules/xlsx/parseProperties.js.map +0 -1
- package/modules/xlsx/parseXlsxFileContents.js +0 -114
- package/modules/xlsx/parseXlsxFileContents.js.map +0 -1
- package/modules/xlsx/parseXlsxFileContentsWithOptionalSchema.js +0 -39
- package/modules/xlsx/parseXlsxFileContentsWithOptionalSchema.js.map +0 -1
- package/modules/xlsx/schema/mapToObjects.js +0 -472
- package/modules/xlsx/schema/mapToObjects.js.map +0 -1
- package/modules/xlsx/schema/mapToObjects.test.js.map +0 -1
- package/types.d.ts +0 -121
- /package/commonjs/{types → parseData}/InvalidError.js +0 -0
- /package/modules/{types → parseData}/InvalidError.js +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# `read-excel-file`
|
|
2
2
|
|
|
3
|
-
Read `.xlsx` files in a
|
|
3
|
+
Read `.xlsx` files in a browser or in Node.js.
|
|
4
4
|
|
|
5
5
|
It also supports parsing spreadsheet rows into JSON objects using a [schema](#schema).
|
|
6
6
|
|
|
@@ -8,9 +8,60 @@ It also supports parsing spreadsheet rows into JSON objects using a [schema](#sc
|
|
|
8
8
|
|
|
9
9
|
Also check out [`write-excel-file`](https://www.npmjs.com/package/write-excel-file) for writing `.xlsx` files.
|
|
10
10
|
|
|
11
|
+
<details>
|
|
12
|
+
<summary>Migrating from <code>6.x</code> to <code>7.x</code></summary>
|
|
13
|
+
|
|
14
|
+
######
|
|
15
|
+
|
|
16
|
+
* Renamed the default export `"read-excel-file"` to `"read-excel-file/browser"`, and it uses [Web Workers](https://developer.mozilla.org/docs/Web/API/Web_Workers_API/Using_web_workers) now.
|
|
17
|
+
* Old: `import readExcelFile from "read-excel-file"`
|
|
18
|
+
* New: `import readExcelFile from "read-excel-file/browser"`
|
|
19
|
+
* The minimum required Node.js version is 18.
|
|
20
|
+
</details>
|
|
21
|
+
|
|
22
|
+
<details>
|
|
23
|
+
<summary>Migrating from <code>7.x</code> to <code>8.x</code></summary>
|
|
24
|
+
|
|
25
|
+
######
|
|
26
|
+
|
|
27
|
+
* Renamed the default exported function to a named exported function `readSheet`.
|
|
28
|
+
* Old: `import readExcelFile from "read-excel-file/browser"`
|
|
29
|
+
* New: `import { readSheet } from "read-excel-file/browser"`
|
|
30
|
+
* And same for other exports like `"read-excel-file/node"`, etc.
|
|
31
|
+
* The default exported function now returns all sheets in a form of an array of objects: `[{ sheet: "Sheet 1", data: [['a1','b1','c1'],['a2','b2','c2']] }, ...]`.
|
|
32
|
+
* Removed `getSheets: true` parameter. The default exported function now returns all sheets.
|
|
33
|
+
* Removed exported `readSheetNames()` function. The default exported function now returns all sheets.
|
|
34
|
+
* Removed `schema` parameter. Instead, use exported function `parseData(data, schema)` to map data to an array of objects.
|
|
35
|
+
* Old: `import readXlsxFile from "read-excel-file"` and then `const { rows, errors } = await readXlsxFile(..., { schema })`
|
|
36
|
+
* New: `import { readSheet, parseData } from "read-excel-file/browser"` and then `const result = parseData(await readSheet(...), schema)`
|
|
37
|
+
* The `result` of the function is an array where each element represents a "data row" and has shape `{ object, errors }`.
|
|
38
|
+
* Depending on whether there were any errors when parsing a given "data row", either `object` or `errors` property will be `undefined`.
|
|
39
|
+
* The `errors` don't have a `row` property anymore because it could be derived from "data row" number.
|
|
40
|
+
* Removed `transformData` parameter because `schema` parameter was removed. A developer could transform the `data` themself and then pass it to `parseData()` function.
|
|
41
|
+
* Removed `isColumnOriented` parameter.
|
|
42
|
+
* Removed `ignoreEmptyRows` parameter. Empty rows somewhere in the middle are not ignored now.
|
|
43
|
+
* Renamed some options that're used when parsing using a `schema`:
|
|
44
|
+
* `schemaPropertyValueForMissingColumn` → `propertyValueWhenColumnIsMissing`
|
|
45
|
+
* `schemaPropertyValueForMissingValue` → `propertyValueWhenCellIsEmpty`
|
|
46
|
+
* `schemaPropertyShouldSkipRequiredValidationForMissingColumn` → (removed)
|
|
47
|
+
* `getEmptyObjectValue` → `transformEmptyObject`
|
|
48
|
+
* The leading `.` character is now removed from the `path` parameter.
|
|
49
|
+
* `getEmptyArrayValue` → `transformEmptyArray`
|
|
50
|
+
* The leading `.` character is now removed from the `path` parameter.
|
|
51
|
+
* Previously, when parsing comma-separated values, it used to ignore any commas that're surrounded by quotes, similar to how it's done in `.csv` files. Now it no longer does that.
|
|
52
|
+
* Previously, when parsing using a schema, it used to force-convert all `type: Date` schema properties from any numeric cell value to a `Date` with a given timestamp. Now it demands the cell values for all such `type: Date` schema properties to already be correctly recognized as `Date`s when they're returned from `readSheet()` or `readExcelFile()` function. And I'd personally assume that in any sane (non-contrived) real-world usage scenario that would be the case, so it doesn't really seem like a "breaking change". And if, for some strange reason, that happens not to be the case, `parseData()` function will throw an error: `not_a_date`.
|
|
53
|
+
* Previously, when parsing using a schema, it used to skip `required` validation for completely-empty rows. It no longer does that.
|
|
54
|
+
* Removed exported function `parseExcelDate()` because there seems to be no need to have it exported.
|
|
55
|
+
* (TypeScript) Renamed exported types:
|
|
56
|
+
* `Type` → `ParseDataValueType`
|
|
57
|
+
* `Error` or `SchemaParseCellValueError` → `ParseDataError`
|
|
58
|
+
* `CellValueRequiredError` → `ParseDataValueRequiredError`
|
|
59
|
+
* `ParsedObjectsResult` → `ParseDataResult`
|
|
60
|
+
</details>
|
|
61
|
+
|
|
11
62
|
## Performance
|
|
12
63
|
|
|
13
|
-
Here're the results of reading [sample `.xlsx` files](https://examplefile.com/document/xlsx) of different
|
|
64
|
+
Here're the results of reading [sample `.xlsx` files](https://examplefile.com/document/xlsx) of different size:
|
|
14
65
|
|
|
15
66
|
|File Size| Browser | Node.js |
|
|
16
67
|
|---------|---------|-----------|
|
|
@@ -28,95 +79,84 @@ Alternatively, one could include it on a web page [directly](#cdn) via a `<scrip
|
|
|
28
79
|
|
|
29
80
|
## Use
|
|
30
81
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Example
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
<input type="file" id="input" />
|
|
37
|
-
```
|
|
82
|
+
The default exported function — let's call it `readExcelFile()` — reads an `.xslx` file and returns a `Promise` that resolves to an array of "sheets". At least one "sheet" always exists. Each "sheet" is an object with properties:
|
|
83
|
+
* `sheet` — Sheet name.
|
|
84
|
+
* Example: `"Sheet1"`
|
|
85
|
+
* `data` — Sheet data. An array of rows. Each row is an array of values — `string`, `number`, `boolean` or `Date`.
|
|
86
|
+
* Example: `[ ['John Smith',35,true,...], ['Kate Brown',28,false,...], ... ]`
|
|
38
87
|
|
|
39
88
|
```js
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
89
|
+
await readExcelFile(file)
|
|
90
|
+
|
|
91
|
+
// Returns
|
|
92
|
+
[{
|
|
93
|
+
sheet: 'Sheet1',
|
|
94
|
+
data: [
|
|
95
|
+
['John Smith',35,true,...],
|
|
96
|
+
['Kate Brown',28,false,...],
|
|
97
|
+
...
|
|
98
|
+
]
|
|
99
|
+
}, {
|
|
100
|
+
sheet: 'Sheet2',
|
|
101
|
+
data: ...
|
|
102
|
+
}]
|
|
51
103
|
```
|
|
52
104
|
|
|
53
|
-
|
|
105
|
+
In simple cases when there're no multiple sheets in an `.xlsx` file, or if only one sheet in an `.xlsx` file is of any interest, use a named exported function `readSheet()`. It's same as the default exported function shown above with the only difference that it returns just `data` instead of `[{ name: 'Sheet1', data }]`, so it's just a bit simpler to use. It has an optional second argument — `sheet` — which could be a sheet number (starting from `1`) or a sheet name. By default, it reads the first sheet.
|
|
54
106
|
|
|
55
107
|
```js
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
108
|
+
await readSheet(file)
|
|
109
|
+
|
|
110
|
+
// Returns
|
|
111
|
+
[
|
|
112
|
+
['John Smith',35,true,...],
|
|
113
|
+
['Kate Brown',28,false,...],
|
|
114
|
+
...
|
|
115
|
+
]
|
|
64
116
|
```
|
|
65
117
|
|
|
66
|
-
|
|
118
|
+
As for where to `import` those two functions from, the package provides a separate `import` path for each different environment, as described below.
|
|
67
119
|
|
|
68
|
-
|
|
120
|
+
### Browser
|
|
69
121
|
|
|
70
|
-
|
|
122
|
+
It can read a [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File), a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or an [`ArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer).
|
|
71
123
|
|
|
72
|
-
Example
|
|
124
|
+
Example: User chooses a file and the web application reads it.
|
|
73
125
|
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
import readXlsxFile from 'read-excel-file/node'
|
|
77
|
-
|
|
78
|
-
// Read data from a file by file path.
|
|
79
|
-
readXlsxFile('/path/to/file').then((rows) => {
|
|
80
|
-
// `rows` is an array of "rows".
|
|
81
|
-
// Each "row" is an array of "cells".
|
|
82
|
-
// Each "cell" is a value: string, number, Date, boolean.
|
|
83
|
-
})
|
|
126
|
+
```html
|
|
127
|
+
<input type="file" id="input" />
|
|
84
128
|
```
|
|
85
129
|
|
|
86
|
-
Example 2: Read data from a [`Stream`](https://nodejs.org/api/stream.html)
|
|
87
|
-
|
|
88
130
|
```js
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
131
|
+
import { readSheet } from 'read-excel-file/browser'
|
|
132
|
+
|
|
133
|
+
const input = document.getElementById('input')
|
|
134
|
+
|
|
135
|
+
input.addEventListener('change', () => {
|
|
136
|
+
const data = await readSheet(input.files[0])
|
|
94
137
|
})
|
|
95
138
|
```
|
|
96
139
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
In summary, it can read data from a file path, a [`Stream`](https://nodejs.org/api/stream.html), a [`Buffer`](https://nodejs.org/api/buffer.html) or a [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob).
|
|
140
|
+
Note: Internet Explorer 11 is an old browser that doesn't support [`Promise`](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Promise), and hence requires a [polyfill](https://www.npmjs.com/package/promise-polyfill).
|
|
100
141
|
|
|
101
|
-
|
|
142
|
+
<details>
|
|
143
|
+
<summary>Example 2: Reading from a URL</summary>
|
|
102
144
|
|
|
103
|
-
|
|
145
|
+
######
|
|
104
146
|
|
|
105
147
|
```js
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
// Read data from a `Blob` with `.xlsx` file contents.
|
|
110
|
-
readXlsxFile(blob).then((rows) => {
|
|
111
|
-
// `rows` is an array of "rows".
|
|
112
|
-
// Each "row" is an array of "cells".
|
|
113
|
-
// Each "cell" is a value: string, number, Date, boolean.
|
|
114
|
-
})
|
|
148
|
+
const response = await fetch('https://example.com/spreadsheet.xlsx')
|
|
149
|
+
const block = await response.blob()
|
|
150
|
+
const data = await readSheet(blob)
|
|
115
151
|
```
|
|
152
|
+
</details>
|
|
116
153
|
|
|
117
|
-
|
|
154
|
+
<details>
|
|
155
|
+
<summary>Example 3: Using <code>read-excel-file</code> in a Web Worker</summary>
|
|
156
|
+
|
|
157
|
+
######
|
|
118
158
|
|
|
119
|
-
|
|
159
|
+
All exports of `read-excel-file` already use a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) under the hood when reading `.xlsx` file contents. This is in order to avoid freezing the UI when reading large files. So using an additional Web Worker on top of that isn't really necessary. Still, for those who require it, this example shows how a user chooses a file and the web application reads it in a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers).
|
|
120
160
|
|
|
121
161
|
```js
|
|
122
162
|
// Step 1: Initialize Web Worker.
|
|
@@ -144,127 +184,125 @@ input.addEventListener('change', () => {
|
|
|
144
184
|
##### `web-worker.js`
|
|
145
185
|
|
|
146
186
|
```js
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// `rows` is an array of "rows".
|
|
153
|
-
// Each "row" is an array of "cells".
|
|
154
|
-
// Each "cell" is a value: string, number, Date, boolean.
|
|
155
|
-
postMessage(rows)
|
|
156
|
-
})
|
|
187
|
+
import { readSheet } from 'read-excel-file/web-worker'
|
|
188
|
+
|
|
189
|
+
onmessage = async function(event) {
|
|
190
|
+
const sheetData = await readSheet(event.data)
|
|
191
|
+
postMessage(sheetData)
|
|
157
192
|
}
|
|
158
193
|
```
|
|
194
|
+
</details>
|
|
159
195
|
|
|
160
|
-
|
|
196
|
+
### Node.js
|
|
161
197
|
|
|
162
|
-
|
|
198
|
+
It can read a file path, a [`Stream`](https://nodejs.org/api/stream.html), a [`Buffer`](https://nodejs.org/api/buffer.html) or a [`Blob`](https://developer.mozilla.org/docs/Web/API/Blob).
|
|
163
199
|
|
|
164
|
-
Example 1:
|
|
200
|
+
Example 1: Read from a file path.
|
|
165
201
|
|
|
166
202
|
```js
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
203
|
+
import { readSheet } from 'read-excel-file/node'
|
|
204
|
+
|
|
205
|
+
const data = await readSheet('/path/to/file')
|
|
170
206
|
```
|
|
171
207
|
|
|
172
|
-
Example 2:
|
|
208
|
+
Example 2: Read from a [`Stream`](https://nodejs.org/api/stream.html)
|
|
173
209
|
|
|
174
210
|
```js
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
211
|
+
import { readSheet } from 'read-excel-file/node'
|
|
212
|
+
|
|
213
|
+
const data = await readSheet(fs.createReadStream('/path/to/file'))
|
|
178
214
|
```
|
|
179
215
|
|
|
180
|
-
|
|
216
|
+
### Universal
|
|
217
|
+
|
|
218
|
+
This one works both in a web browser and Node.js. It can only read from a [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) or an [`ArrayBuffer`](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer), which could be a bit less convenient for general use.
|
|
181
219
|
|
|
182
220
|
```js
|
|
183
|
-
|
|
184
|
-
// 'read-excel-file/browser', 'read-exel-file/node', 'read-excel-file/web-worker', etc.
|
|
185
|
-
import { readSheetNames } from 'read-excel-file/browser'
|
|
221
|
+
import { readSheet } from 'read-excel-file/universal'
|
|
186
222
|
|
|
187
|
-
|
|
188
|
-
// sheetNames === ['Sheet1', 'Sheet2']
|
|
189
|
-
})
|
|
223
|
+
const data = await readSheet(blob)
|
|
190
224
|
```
|
|
191
225
|
|
|
192
|
-
##
|
|
226
|
+
## Strings
|
|
193
227
|
|
|
194
|
-
|
|
228
|
+
By default, it automatically trims all string values. To disable this behavior, pass `trim: false` option.
|
|
195
229
|
|
|
196
|
-
|
|
230
|
+
```js
|
|
231
|
+
readExcelFile(file, { trim: false })
|
|
232
|
+
```
|
|
197
233
|
|
|
198
|
-
|
|
234
|
+
## Dates
|
|
199
235
|
|
|
200
|
-
|
|
236
|
+
`.xlsx` file format originally had no dedicated "date" type, so dates are in almost all cases stored simply as numbers, equal to the count of days since `01/01/1900` (with a few [quirks](https://www.reddit.com/r/AskStatistics/comments/7uk40z/excel_calculates_dates_wrong_so_please_be_careful/)). To correctly interpret such numbers as dates, each date cell in an `.xlsx` file specifies a certain ["format"](https://xlsxwriter.readthedocs.io/format.html#format-set-num-format) — for example, `"d mmm yyyy"` — that instructs a spreadsheet viewer application to interpret the numeric value in the cell as a date rather than a number, and display it using the specified format.
|
|
201
237
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
238
|
+
Being no different from a generic spreadsheet viewer application, this package follows the same practice: it attempts to guess whether a given cell value is a date or a number by looking at the cell's "format" — if the "format" is one of the known [standard date formats](https://docs.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.numberingformat?view=openxml-2.8.1) then the cell value is interpreted as a date rather than a number. So usually there's no need to configure anything and it usually "just works" out-of-the-box.
|
|
239
|
+
|
|
240
|
+
Although there's still a possibility for an `.xlsx` file to specify a totally-custom non-standard date format. In such case, a developer could pass a `dateFormat` parameter to tell this package to parse cells having that specific "format" as date ones rather than numeric ones: `readExcelFile(file, { dateFormat: 'mm/dd/yyyy' })`.
|
|
205
241
|
|
|
206
242
|
## Numbers
|
|
207
243
|
|
|
208
|
-
|
|
244
|
+
When reading an `.xlsx` file, any numeric values are parsed from a string to a javascript `number`. But there's an inherent issue with javascript `number`s in general — their [floating-point precision](https://www.youtube.com/watch?v=2gIxbTn7GSc) is sometimes less than ideal. For example, `0.1 + 0.2 != 0.3`. Yet, applications in areas such as finance or banking usually require 100% floating-point precision, which is usually worked around by using a custom implementation of a "decimal" data type such as [`decimal.js`](https://www.npmjs.com/package/decimal.js).
|
|
245
|
+
|
|
246
|
+
This package supports passing a custom `parseNumber(string)` function as an option when reading an `.xlsx` file. By default, it parses a `string` to a javascript `number`, but one could pass any custom implementation.
|
|
209
247
|
|
|
210
|
-
Example: Use "
|
|
248
|
+
Example: Use "decimal" data type to perform further calculations on fractional numbers with 100% precision.
|
|
211
249
|
|
|
212
250
|
```js
|
|
213
251
|
import Decimal from 'decimal.js'
|
|
214
252
|
|
|
215
|
-
|
|
253
|
+
readExcelFile(file, {
|
|
216
254
|
parseNumber: (string) => new Decimal(string)
|
|
217
255
|
})
|
|
218
256
|
```
|
|
219
257
|
|
|
220
|
-
## Strings
|
|
221
|
-
|
|
222
|
-
By default, it automatically trims all string cell values. To disable this feature, pass `trim: false` option.
|
|
223
|
-
|
|
224
|
-
```js
|
|
225
|
-
readXlsxFile(file, { trim: false })
|
|
226
|
-
```
|
|
227
|
-
|
|
228
258
|
## Formulas
|
|
229
259
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
## Performance
|
|
233
|
-
|
|
234
|
-
There have been some reports about performance issues when reading extremely large `.xlsx` spreadsheets using this library. It's true that this library's main point have been usability and convenience, and not performance when handling huge datasets. For example, the time of parsing a file with 100,000 rows could be up to 10 seconds. If your application has to quickly read huge datasets, perhaps consider using something like [`xlsx`](https://github.com/catamphetamine/read-excel-file/issues/38#issuecomment-544286628) package instead. There're no comparative benchmarks between the two packages, so we don't know how much the difference would be. If you'll be making any benchmarks, share those in the "Issues" so that we could include them in this readme.
|
|
260
|
+
This package doesn't support reading cells that use formulas to calculate the value: `SUM`, `AVERAGE`, etc.
|
|
235
261
|
|
|
236
262
|
## Schema
|
|
237
263
|
|
|
238
|
-
|
|
264
|
+
Oftentimes, the task is not just to read the "raw" spreadsheet data but also to convert each row of that data to a JSON object having a certain structure. Because it's such a common task, this package exports a named function `parseData(data, schema)` which does exactly that. It parses sheet data into an array of JSON objects according to a pre-defined `schema` which describes how should a row of data be converted to a JSON object.
|
|
265
|
+
|
|
266
|
+
```js
|
|
267
|
+
import { readSheet, parseData } from "read-excel-file/browser"
|
|
268
|
+
|
|
269
|
+
const data = await readSheet(file)
|
|
270
|
+
const schema = { ... }
|
|
271
|
+
for (const { object, errors } of parseData(data, schema)) {
|
|
272
|
+
if (errors) {
|
|
273
|
+
console.error(errors)
|
|
274
|
+
} else {
|
|
275
|
+
console.log(object)
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
239
279
|
|
|
240
|
-
The
|
|
280
|
+
The `parseData()` function returns an array where each element represents a "data row" and has shape `{ object, errors }`. Depending on whether there were any errors when parsing a given "data row", either `object` or `errors` property will be `undefined`.
|
|
241
281
|
|
|
242
|
-
The
|
|
282
|
+
The sheet data that is being parsed should adhere to a simple structure: the first row should be a header row with just column titles, and each following row should specify the values for those columns.
|
|
243
283
|
|
|
244
|
-
|
|
245
|
-
* what column to read the value from
|
|
246
|
-
* how to validate the value
|
|
247
|
-
* how to parse the value
|
|
284
|
+
The `schema` argument should describe the structure of the resulting JSON objects. An example of a `schema` is provided at the end of this section.
|
|
248
285
|
|
|
249
|
-
|
|
286
|
+
Specifically, a `schema` should be an object having the same keys as a resulting JSON object, with values being nested objects having the following properties:
|
|
250
287
|
|
|
251
288
|
* `column` — The title of the column to read the value from.
|
|
252
289
|
* If the column is missing from the spreadsheet, the property value will be `undefined`.
|
|
253
|
-
* This can be overridden by passing `
|
|
290
|
+
* This can be overridden by passing `propertyValueWhenColumnIsMissing` option. Is `undefined` by default.
|
|
254
291
|
* If the column is present in the spreadsheet but is empty, the property value will be `null`.
|
|
255
|
-
* This can be overridden by passing `
|
|
292
|
+
* This can be overridden by passing `propertyValueWhenCellIsEmpty` option. Is `null` by default.
|
|
256
293
|
* `required` — (optional) Is the value required?
|
|
257
294
|
* Could be one of:
|
|
258
295
|
* `required: boolean`
|
|
259
296
|
* `true` — The column must not be missing from the spreadsheet and the cell value must not be empty.
|
|
260
|
-
* `false` — The column can be missing from the spreadsheet
|
|
297
|
+
* `false` — The column can be missing from the spreadsheet, or the cell value can be empty.
|
|
261
298
|
* `required: (object) => boolean` — A function returning `true` or `false` depending on the other properties of the object.
|
|
262
|
-
*
|
|
299
|
+
<!-- * To skip `required` validation for a column that is missing from a spreadsheet, one could pass `shouldSkipRequiredValidationWhenColumnIsMissing` option. It should be a function: `(columnTitle, { object }) => boolean`. By default it always returns `false` meaning that when `columnTitle` is missing from the spreadsheet, it will not skip performing the `required` validation for it. -->
|
|
263
300
|
* `validate(value)` — (optional) Validates the value. Is only called for non-empty cells. If the value is invalid, this function should throw an error.
|
|
264
|
-
* `schema` — (optional) If the value is going to be a nested object, `schema` should describe
|
|
265
|
-
* If all of its property values happen to be empty
|
|
266
|
-
* This can be overridden by passing `
|
|
267
|
-
*
|
|
301
|
+
* `schema` — (optional) If the value is going to be a nested object, `schema` should describe that nested object.
|
|
302
|
+
* If when parsing such nested object, all of its property values happen to be empty — `undefined` or `null` — then the nested object will be itself set to `null`.
|
|
303
|
+
* This can be overridden by passing `transformEmptyObject(object, { path? })` function as an option. By default, it returns `null`.
|
|
304
|
+
* This applies both to nested objects and to the top-level object itself.
|
|
305
|
+
* `type` — (optional) If the value is not going to be a nested object, `type` should describe the type of the value. It will determine how the cell value will be converted to a property value. If no `type` is specified then the property value will be same as the cell value.
|
|
268
306
|
* Valid `type`s:
|
|
269
307
|
* Standard types:
|
|
270
308
|
* `String`
|
|
@@ -276,25 +314,28 @@ A key of a `schema` entry represents the name of the property. The value of the
|
|
|
276
314
|
* `Email`
|
|
277
315
|
* `URL`
|
|
278
316
|
* Custom type:
|
|
279
|
-
* A function that receives a cell value and returns a parsed value. Returning `undefined` will have same effect as returning `null`. If the value is invalid, it should throw an error.
|
|
280
|
-
* If the cell value
|
|
281
|
-
*
|
|
282
|
-
|
|
283
|
-
|
|
317
|
+
* A function that receives a cell value and returns any kind of a parsed value. Returning `undefined` will have same effect as returning `null`. If the value is invalid, it should throw an error.
|
|
318
|
+
* If the cell value is comprised of comma-separated values (example: `"a, b, c"`) and if it should be parsed as an array of such values, then the property `type` could be specified as an array — `type: [elementType]` — where `elementType` could be any valid `type` described above. For example, if a property is defined as `{ type: [String] }` and the cell value is `"a, b, c"` then the property value will be parsed as `["a", "b", "c"]`.
|
|
319
|
+
* If the cell is empty, or if every element of the parsed array is `null` or `undefined`, then the property value itself will be set to `null`.
|
|
320
|
+
* This can be overridden by passing `transformEmptyArray(array, { path })` function as an option. By default, it returns `null`.
|
|
321
|
+
* The separator could be specified by passing `arrayValueSeparator` option. By default, it's `","`.
|
|
322
|
+
* The separated parts of a cell value will be trimmed.
|
|
284
323
|
|
|
285
|
-
If there're any errors during the conversion
|
|
324
|
+
If there're any errors during the conversion process, the `errors` property returned from the function will be a non-empty array (by default, it's an empty array). Each `error` object has properties:
|
|
286
325
|
|
|
287
326
|
* `error: string` — The error code. Examples: `"required"`, `"invalid"`.
|
|
288
|
-
* If a custom `validate()` function is defined and it throws a `new Error(message)` then the `error` property will be the same as the `message`
|
|
289
|
-
* If a custom `type()` function is defined and it throws a `new Error(message)` then the `error` property will be the same as the `message`
|
|
290
|
-
* `reason?: string` — An optional secondary error code providing more details about the error
|
|
291
|
-
* Example: `{ error: "invalid", reason: "not_a_number" }` for `type: Number` means that "the cell value is _invalid_ **because** it's _not a number_".
|
|
292
|
-
* `row: number` — The row number
|
|
327
|
+
* If a custom `validate()` function is defined and it throws a `new Error(message)` then the `error` property will be the same as the `message` argument.
|
|
328
|
+
* If a custom `type()` function is defined and it throws a `new Error(message)` then the `error` property will be the same as the `message` argument.
|
|
329
|
+
* `reason?: string` — An optional secondary error code providing more details about the error. I.e. "`error.error` happened specifically because of `error.reason`". Currently, it could only be returned for the standard `type`s.
|
|
330
|
+
* Example: `{ error: "invalid", reason: "not_a_number" }` for a `type: Number` property means that "the cell value is _invalid_ **because** it's _not a number_".
|
|
331
|
+
* `row: number` — The row number, starting from `1`.
|
|
332
|
+
* `row: 1` means "first row of data", etc.
|
|
333
|
+
* Don't mind the header row.
|
|
293
334
|
* `column: string` — The column title.
|
|
294
335
|
* `value?: any` — The cell value.
|
|
295
|
-
* `type?: any` — The `type` of the property, as defined
|
|
336
|
+
* `type?: any` — The `type` of the property, as defined by the `schema`.
|
|
296
337
|
|
|
297
|
-
|
|
338
|
+
Example:
|
|
298
339
|
|
|
299
340
|
```js
|
|
300
341
|
// An example .xlsx document:
|
|
@@ -352,35 +393,37 @@ const schema = {
|
|
|
352
393
|
}
|
|
353
394
|
}
|
|
354
395
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
}
|
|
369
|
-
|
|
396
|
+
const data = await readSheet(file)
|
|
397
|
+
|
|
398
|
+
const { rows, errors } = parseData(data, schema)
|
|
399
|
+
|
|
400
|
+
// `errors` list items have shape: `{ row, column, error, reason?, value?, type? }`.
|
|
401
|
+
errors.length === 0
|
|
402
|
+
|
|
403
|
+
rows === [{
|
|
404
|
+
date: new Date(2018, 3 - 1, 24),
|
|
405
|
+
numberOfStudents: 10,
|
|
406
|
+
course: {
|
|
407
|
+
isFree: true,
|
|
408
|
+
title: 'Chemistry'
|
|
409
|
+
},
|
|
410
|
+
contact: '+11234567890',
|
|
411
|
+
status: 'SCHEDULED'
|
|
412
|
+
}]
|
|
370
413
|
```
|
|
371
414
|
|
|
372
|
-
#### Schema: Tips and Features
|
|
415
|
+
<!-- #### Schema: Tips and Features -->
|
|
373
416
|
|
|
374
417
|
<!-- If no `type` is specified then the cell value is returned "as is": as a string, number, date or boolean. -->
|
|
375
418
|
|
|
376
419
|
<!-- There are also some additional exported `type`s available: -->
|
|
377
420
|
|
|
378
421
|
<details>
|
|
379
|
-
<summary>
|
|
422
|
+
<summary>An example of a <strong>custom <code>type</code></strong></summary>
|
|
380
423
|
|
|
381
424
|
#####
|
|
382
425
|
|
|
383
|
-
Here's an example of a custom `type
|
|
426
|
+
Here's an example of a basic custom `type`. It calls a custom `parseValue()` function to parse a cell value, and produces an `"invalid"` error if the value couldn't be parsed. If a cell is empty, it will not be parsed.
|
|
384
427
|
|
|
385
428
|
```js
|
|
386
429
|
{
|
|
@@ -401,44 +444,25 @@ Here's an example of a custom `type` parsing function. It will only be called fo
|
|
|
401
444
|
|
|
402
445
|
<!-- A schema entry for a column may also define an optional `validate(value)` function for validating the parsed value: in that case, it must `throw` an `Error` if the `value` is invalid. The `validate(value)` function is only called when `value` is not empty (not `null` / `undefined`). -->
|
|
403
446
|
|
|
404
|
-
<!--
|
|
405
447
|
<details>
|
|
406
|
-
<summary>
|
|
448
|
+
<summary>An example of a <strong>React component to output <code>errors</code></strong></summary>
|
|
407
449
|
|
|
408
450
|
#####
|
|
409
451
|
|
|
410
|
-
By default, it skips any empty rows. To disable that behavior, pass `ignoreEmptyRows: false` option.
|
|
411
|
-
|
|
412
452
|
```js
|
|
413
|
-
|
|
414
|
-
schema,
|
|
415
|
-
ignoreEmptyRows: false
|
|
416
|
-
})
|
|
417
|
-
```
|
|
418
|
-
</details>
|
|
419
|
-
-->
|
|
420
|
-
|
|
421
|
-
<details>
|
|
422
|
-
<summary>A <strong>React component for displaying errors</strong> that occured during schema parsing/validation.</summary>
|
|
423
|
-
|
|
424
|
-
#####
|
|
425
|
-
|
|
426
|
-
```js
|
|
427
|
-
import { parseExcelDate } from 'read-excel-file/browser'
|
|
428
|
-
|
|
429
|
-
function ParseExcelFileErrors({ errors }) {
|
|
453
|
+
function ErrorsList({ errors }) {
|
|
430
454
|
return (
|
|
431
455
|
<ul>
|
|
432
456
|
{errors.map((error, i) => (
|
|
433
457
|
<li key={i}>
|
|
434
|
-
<
|
|
458
|
+
<ErrorItem error={error}>
|
|
435
459
|
</li>
|
|
436
460
|
))}
|
|
437
461
|
</ul>
|
|
438
462
|
)
|
|
439
463
|
}
|
|
440
464
|
|
|
441
|
-
function
|
|
465
|
+
function ErrorItem({ error: errorDetails }) {
|
|
442
466
|
const { type, value, error, reason, row, column } = errorDetails
|
|
443
467
|
|
|
444
468
|
// Error summary.
|
|
@@ -468,26 +492,9 @@ function stringifyValue(value) {
|
|
|
468
492
|
```
|
|
469
493
|
</details>
|
|
470
494
|
|
|
471
|
-
## Fix Spreadsheet Structure When Using Schema
|
|
472
|
-
|
|
473
|
-
Sometimes, a spreadsheet doesn't have the required structure to read it using a `schema`. For example, header row might be missing, or there could be some purely presentational / empty / "garbage" rows that should be skipped. To fix that, pass a `transformData(data)` function as an option. It will transform spreadsheet content before it is parsed with `schema`. The `data` argument is an array of rows, each row being an array of cell values.
|
|
474
|
-
|
|
475
|
-
```js
|
|
476
|
-
readXlsxFile(file, {
|
|
477
|
-
schema,
|
|
478
|
-
transformData(data) {
|
|
479
|
-
// Example 1: Add a missing header row.
|
|
480
|
-
return [['ID', 'NAME', ...]].concat(data)
|
|
481
|
-
// Example 2: Remove empty rows.
|
|
482
|
-
return data.filter(row => row.some(cell => cell !== null))
|
|
483
|
-
}
|
|
484
|
-
})
|
|
485
|
-
```
|
|
486
|
-
</details>
|
|
487
|
-
|
|
488
495
|
## Browser Support
|
|
489
496
|
|
|
490
|
-
An `.xlsx` file is just a
|
|
497
|
+
An `.xlsx` file is just a `.zip` archive with an `.xslx` file extension. This package uses [`fflate`](https://www.npmjs.com/package/fflate) for `.zip` decompression. See `fflate`'s [browser support](https://www.npmjs.com/package/fflate#browser-support) for further details.
|
|
491
498
|
|
|
492
499
|
## CDN
|
|
493
500
|
|
package/browser/index.cjs
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
exports = module.exports = require('../commonjs/export/readXlsxFileBrowser.js').default
|
|
2
2
|
exports['default'] = require('../commonjs/export/readXlsxFileBrowser.js').default
|
|
3
|
-
|
|
4
|
-
exports.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
exports.
|
|
3
|
+
|
|
4
|
+
exports.readSheet = require('../commonjs/export/readSheetBrowser.js').default
|
|
5
|
+
|
|
6
|
+
// `parseData()`
|
|
7
|
+
exports.parseData = require('../commonjs/parseData/parseData.js').default
|
|
8
|
+
exports.Integer = require('../commonjs/parseData/types/additional/Integer.js').default
|
|
9
|
+
exports.Email = require('../commonjs/parseData/types/additional/Email.js').default
|
|
10
|
+
exports.URL = require('../commonjs/parseData/types/additional/URL.js').default
|