read-excel-file 9.3.4 → 9.3.5
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 +6 -2
- package/README.md +32 -2
- package/browser/index.cjs +3 -0
- package/browser/index.d.ts +16 -0
- package/browser/index.js +4 -1
- package/bundle/read-excel-file.min.js +1 -1
- package/bundle/read-excel-file.min.js.map +1 -1
- package/commonjs/export/convertInputToNodeStream.js +0 -12
- package/commonjs/export/convertInputToNodeStream.js.map +1 -1
- package/commonjs/export/parseSheet.js +14 -7
- package/commonjs/export/parseSheet.js.map +1 -1
- package/commonjs/export/readSheetBrowser.js +3 -6
- package/commonjs/export/readSheetBrowser.js.map +1 -1
- package/commonjs/export/readSheetNode.js +3 -6
- package/commonjs/export/readSheetNode.js.map +1 -1
- package/commonjs/export/readSheetUniversal.js +2 -2
- package/commonjs/export/readSheetUniversal.js.map +1 -1
- package/commonjs/export/readSheetWebWorker.js +5 -5
- package/commonjs/export/readSheetWebWorker.js.map +1 -1
- package/commonjs/export/readXlsxFileBrowser.js +3 -6
- package/commonjs/export/readXlsxFileBrowser.js.map +1 -1
- package/commonjs/export/readXlsxFileNode.js +3 -6
- package/commonjs/export/readXlsxFileNode.js.map +1 -1
- package/commonjs/export/readXlsxFileUniversal.js +2 -2
- package/commonjs/export/readXlsxFileUniversal.js.map +1 -1
- package/commonjs/export/readXlsxFileWebWorker.js +5 -5
- package/commonjs/export/readXlsxFileWebWorker.js.map +1 -1
- package/commonjs/export/unpackXlsxFileBrowser.js +15 -4
- package/commonjs/export/unpackXlsxFileBrowser.js.map +1 -1
- package/commonjs/export/unpackXlsxFileBrowser.test.js.map +1 -0
- package/commonjs/export/unpackXlsxFileNode.js +32 -5
- package/commonjs/export/unpackXlsxFileNode.js.map +1 -1
- package/commonjs/export/unpackXlsxFileNode.test.js.map +1 -0
- package/commonjs/export/unpackXlsxFileUniversal.js +14 -3
- package/commonjs/export/unpackXlsxFileUniversal.js.map +1 -1
- package/commonjs/export/unpackXlsxFileUniversal.test.js.map +1 -0
- package/commonjs/parseSheetData/parseSheetData.js +9 -6
- package/commonjs/parseSheetData/parseSheetData.js.map +1 -1
- package/commonjs/utility/convertValuesFromUint8ArraysToStrings.js +100 -0
- package/commonjs/utility/convertValuesFromUint8ArraysToStrings.js.map +1 -0
- package/commonjs/xlsx/InvalidSpreadsheetError.js +55 -0
- package/commonjs/xlsx/InvalidSpreadsheetError.js.map +1 -0
- package/commonjs/xlsx/SheetNotFoundError.js +55 -0
- package/commonjs/xlsx/SheetNotFoundError.js.map +1 -0
- package/commonjs/xlsx/file/InputValidationStream.js +101 -0
- package/commonjs/xlsx/file/InputValidationStream.js.map +1 -0
- package/commonjs/xlsx/file/InputValidationStream.test.js.map +1 -0
- package/commonjs/xlsx/file/InvalidInputError.js +105 -0
- package/commonjs/xlsx/file/InvalidInputError.js.map +1 -0
- package/commonjs/xlsx/file/createFileTypeDetector.js +70 -0
- package/commonjs/xlsx/file/createFileTypeDetector.js.map +1 -0
- package/commonjs/xlsx/file/createFileTypeDetector.test.js.map +1 -0
- package/commonjs/xlsx/file/validateLeadingBytes.js +47 -0
- package/commonjs/xlsx/file/validateLeadingBytes.js.map +1 -0
- package/commonjs/xlsx/file/validateLeadingBytes.test.js.map +1 -0
- package/commonjs/xlsx/isDateFormat.js +32 -27
- package/commonjs/xlsx/isDateFormat.js.map +1 -1
- package/commonjs/xlsx/isDateFormatStyle.js +19 -21
- package/commonjs/xlsx/isDateFormatStyle.js.map +1 -1
- package/commonjs/xlsx/parseCell.js +252 -115
- package/commonjs/xlsx/parseCell.js.map +1 -1
- package/commonjs/xlsx/parseCellAddress.js +22 -18
- package/commonjs/xlsx/parseCellAddress.js.map +1 -1
- package/commonjs/xlsx/parseExcelDate.js +4 -124
- package/commonjs/xlsx/parseExcelDate.js.map +1 -1
- package/commonjs/xlsx/parseExcelDate.test.js.map +1 -1
- package/commonjs/xlsx/parseExcelTimestamp.js +139 -0
- package/commonjs/xlsx/parseExcelTimestamp.js.map +1 -0
- package/commonjs/xlsx/parseFilePaths.js +48 -47
- package/commonjs/xlsx/parseFilePaths.js.map +1 -1
- package/commonjs/xlsx/parseSharedStrings.js +91 -36
- package/commonjs/xlsx/parseSharedStrings.js.map +1 -1
- package/commonjs/xlsx/parseSheet.js +527 -69
- package/commonjs/xlsx/parseSheet.js.map +1 -1
- package/commonjs/xlsx/parseSpreadsheetContents.js +154 -83
- package/commonjs/xlsx/parseSpreadsheetContents.js.map +1 -1
- package/commonjs/xlsx/parseSpreadsheetInfo.js +60 -59
- package/commonjs/xlsx/parseSpreadsheetInfo.js.map +1 -1
- package/commonjs/xlsx/parseStyles.js +75 -75
- package/commonjs/xlsx/parseStyles.js.map +1 -1
- package/commonjs/xml/parseXml.js +112 -0
- package/commonjs/xml/parseXml.js.map +1 -0
- package/commonjs/xml/parseXml.test.js.map +1 -0
- package/commonjs/xml/parseXmlStream.js.map +1 -1
- package/commonjs/xml/parseXmlStream.sax.js +69 -28
- package/commonjs/xml/parseXmlStream.sax.js.map +1 -1
- package/commonjs/xml/parseXmlStream.saxen.js +66 -40
- package/commonjs/xml/parseXmlStream.saxen.js.map +1 -1
- package/commonjs/zip/UnzipError.js +55 -0
- package/commonjs/zip/UnzipError.js.map +1 -0
- package/commonjs/zip/unzipFromArrayBuffer.js +21 -1
- package/commonjs/zip/unzipFromArrayBuffer.js.map +1 -1
- package/commonjs/zip/unzipFromArrayBuffer.test.js.map +1 -0
- package/commonjs/zip/unzipFromStream.fflate.js +43 -35
- package/commonjs/zip/unzipFromStream.fflate.js.map +1 -1
- package/commonjs/zip/unzipFromStream.js +188 -6
- package/commonjs/zip/unzipFromStream.js.map +1 -1
- package/commonjs/zip/unzipFromStream.unzipper.js +19 -34
- package/commonjs/zip/unzipFromStream.unzipper.js.map +1 -1
- package/modules/export/convertInputToNodeStream.js +0 -12
- package/modules/export/convertInputToNodeStream.js.map +1 -1
- package/modules/export/parseSheet.js +13 -6
- package/modules/export/parseSheet.js.map +1 -1
- package/modules/export/readSheetBrowser.js +3 -5
- package/modules/export/readSheetBrowser.js.map +1 -1
- package/modules/export/readSheetNode.js +3 -5
- package/modules/export/readSheetNode.js.map +1 -1
- package/modules/export/readSheetUniversal.js +2 -2
- package/modules/export/readSheetUniversal.js.map +1 -1
- package/modules/export/readSheetWebWorker.js +7 -8
- package/modules/export/readSheetWebWorker.js.map +1 -1
- package/modules/export/readXlsxFileBrowser.js +3 -5
- package/modules/export/readXlsxFileBrowser.js.map +1 -1
- package/modules/export/readXlsxFileNode.js +3 -5
- package/modules/export/readXlsxFileNode.js.map +1 -1
- package/modules/export/readXlsxFileUniversal.js +2 -2
- package/modules/export/readXlsxFileUniversal.js.map +1 -1
- package/modules/export/readXlsxFileWebWorker.js +7 -8
- package/modules/export/readXlsxFileWebWorker.js.map +1 -1
- package/modules/export/unpackXlsxFileBrowser.js +15 -4
- package/modules/export/unpackXlsxFileBrowser.js.map +1 -1
- package/modules/export/unpackXlsxFileBrowser.test.js.map +1 -0
- package/modules/export/unpackXlsxFileNode.js +32 -5
- package/modules/export/unpackXlsxFileNode.js.map +1 -1
- package/modules/export/unpackXlsxFileNode.test.js.map +1 -0
- package/modules/export/unpackXlsxFileUniversal.js +14 -3
- package/modules/export/unpackXlsxFileUniversal.js.map +1 -1
- package/modules/export/unpackXlsxFileUniversal.test.js.map +1 -0
- package/modules/parseSheetData/parseSheetData.js +9 -6
- package/modules/parseSheetData/parseSheetData.js.map +1 -1
- package/modules/utility/convertValuesFromUint8ArraysToStrings.js +92 -0
- package/modules/utility/convertValuesFromUint8ArraysToStrings.js.map +1 -0
- package/modules/xlsx/InvalidSpreadsheetError.js +50 -0
- package/modules/xlsx/InvalidSpreadsheetError.js.map +1 -0
- package/modules/xlsx/SheetNotFoundError.js +50 -0
- package/modules/xlsx/SheetNotFoundError.js.map +1 -0
- package/modules/xlsx/file/InputValidationStream.js +96 -0
- package/modules/xlsx/file/InputValidationStream.js.map +1 -0
- package/modules/xlsx/file/InputValidationStream.test.js.map +1 -0
- package/modules/xlsx/file/InvalidInputError.js +100 -0
- package/modules/xlsx/file/InvalidInputError.js.map +1 -0
- package/modules/xlsx/file/createFileTypeDetector.js +63 -0
- package/modules/xlsx/file/createFileTypeDetector.js.map +1 -0
- package/modules/xlsx/file/createFileTypeDetector.test.js.map +1 -0
- package/modules/xlsx/file/validateLeadingBytes.js +37 -0
- package/modules/xlsx/file/validateLeadingBytes.js.map +1 -0
- package/modules/xlsx/file/validateLeadingBytes.test.js.map +1 -0
- package/modules/xlsx/isDateFormat.js +31 -27
- package/modules/xlsx/isDateFormat.js.map +1 -1
- package/modules/xlsx/isDateFormatStyle.js +18 -21
- package/modules/xlsx/isDateFormatStyle.js.map +1 -1
- package/modules/xlsx/parseCell.js +251 -111
- package/modules/xlsx/parseCell.js.map +1 -1
- package/modules/xlsx/parseCellAddress.js +21 -18
- package/modules/xlsx/parseCellAddress.js.map +1 -1
- package/modules/xlsx/parseExcelDate.js +4 -124
- package/modules/xlsx/parseExcelDate.js.map +1 -1
- package/modules/xlsx/parseExcelDate.test.js.map +1 -1
- package/modules/xlsx/parseExcelTimestamp.js +133 -0
- package/modules/xlsx/parseExcelTimestamp.js.map +1 -0
- package/modules/xlsx/parseFilePaths.js +48 -47
- package/modules/xlsx/parseFilePaths.js.map +1 -1
- package/modules/xlsx/parseSharedStrings.js +91 -37
- package/modules/xlsx/parseSharedStrings.js.map +1 -1
- package/modules/xlsx/parseSheet.js +526 -68
- package/modules/xlsx/parseSheet.js.map +1 -1
- package/modules/xlsx/parseSpreadsheetContents.js +153 -81
- package/modules/xlsx/parseSpreadsheetContents.js.map +1 -1
- package/modules/xlsx/parseSpreadsheetInfo.js +60 -59
- package/modules/xlsx/parseSpreadsheetInfo.js.map +1 -1
- package/modules/xlsx/parseStyles.js +75 -75
- package/modules/xlsx/parseStyles.js.map +1 -1
- package/modules/xml/parseXml.js +106 -0
- package/modules/xml/parseXml.js.map +1 -0
- package/modules/xml/parseXml.test.js.map +1 -0
- package/modules/xml/parseXmlStream.js +2 -0
- package/modules/xml/parseXmlStream.js.map +1 -1
- package/modules/xml/parseXmlStream.sax.js +69 -28
- package/modules/xml/parseXmlStream.sax.js.map +1 -1
- package/modules/xml/parseXmlStream.saxen.js +67 -40
- package/modules/xml/parseXmlStream.saxen.js.map +1 -1
- package/modules/zip/UnzipError.js +49 -0
- package/modules/zip/UnzipError.js.map +1 -0
- package/modules/zip/unzipFromArrayBuffer.js +21 -1
- package/modules/zip/unzipFromArrayBuffer.js.map +1 -1
- package/modules/zip/unzipFromArrayBuffer.test.js.map +1 -0
- package/modules/zip/unzipFromStream.fflate.js +41 -35
- package/modules/zip/unzipFromStream.fflate.js.map +1 -1
- package/modules/zip/unzipFromStream.js +124 -1
- package/modules/zip/unzipFromStream.js.map +1 -1
- package/modules/zip/unzipFromStream.unzipper.js +19 -35
- package/modules/zip/unzipFromStream.unzipper.js.map +1 -1
- package/node/index.cjs +3 -0
- package/node/index.d.ts +16 -0
- package/node/index.js +3 -0
- package/package.json +5 -3
- package/types/InvalidInputError.d.ts +16 -0
- package/types/InvalidSpreadsheetError.d.ts +4 -0
- package/types/SheetNotFoundError.d.ts +4 -0
- package/universal/index.cjs +3 -0
- package/universal/index.d.ts +16 -0
- package/universal/index.js +3 -0
- package/web-worker/index.cjs +3 -0
- package/web-worker/index.d.ts +16 -0
- package/web-worker/index.js +3 -0
- package/commonjs/export/convertValuesFromUint8ArraysToStrings.js +0 -23
- package/commonjs/export/convertValuesFromUint8ArraysToStrings.js.map +0 -1
- package/commonjs/xlsx/convertCellsToData2dArray.js +0 -84
- package/commonjs/xlsx/convertCellsToData2dArray.js.map +0 -1
- package/commonjs/xlsx/dropEmptyColumns.js +0 -40
- package/commonjs/xlsx/dropEmptyColumns.js.map +0 -1
- package/commonjs/xlsx/dropEmptyColumns.test.js.map +0 -1
- package/commonjs/xlsx/dropEmptyRows.js +0 -43
- package/commonjs/xlsx/dropEmptyRows.js.map +0 -1
- package/commonjs/xlsx/dropEmptyRows.test.js.map +0 -1
- package/commonjs/xlsx/parseCellValue.js +0 -189
- package/commonjs/xlsx/parseCellValue.js.map +0 -1
- package/commonjs/xlsx/parseNumber.js +0 -20
- package/commonjs/xlsx/parseNumber.js.map +0 -1
- package/commonjs/xlsx/parseSharedString.js +0 -64
- package/commonjs/xlsx/parseSharedString.js.map +0 -1
- package/commonjs/xlsx/parseSheetData.js +0 -68
- package/commonjs/xlsx/parseSheetData.js.map +0 -1
- package/commonjs/xlsx/reconstructSheetDimensionsFromSheetCells.js +0 -29
- package/commonjs/xlsx/reconstructSheetDimensionsFromSheetCells.js.map +0 -1
- package/commonjs/xml/parseXmlStream.saxen.code.js +0 -953
- package/commonjs/xml/parseXmlStream.saxen.code.js.map +0 -1
- package/commonjs/xml/parseXmlStream.test.js.map +0 -1
- package/modules/export/convertValuesFromUint8ArraysToStrings.js +0 -17
- package/modules/export/convertValuesFromUint8ArraysToStrings.js.map +0 -1
- package/modules/xlsx/convertCellsToData2dArray.js +0 -77
- package/modules/xlsx/convertCellsToData2dArray.js.map +0 -1
- package/modules/xlsx/dropEmptyColumns.js +0 -34
- package/modules/xlsx/dropEmptyColumns.js.map +0 -1
- package/modules/xlsx/dropEmptyColumns.test.js.map +0 -1
- package/modules/xlsx/dropEmptyRows.js +0 -37
- package/modules/xlsx/dropEmptyRows.js.map +0 -1
- package/modules/xlsx/dropEmptyRows.test.js.map +0 -1
- package/modules/xlsx/parseCellValue.js +0 -183
- package/modules/xlsx/parseCellValue.js.map +0 -1
- package/modules/xlsx/parseNumber.js +0 -14
- package/modules/xlsx/parseNumber.js.map +0 -1
- package/modules/xlsx/parseSharedString.js +0 -55
- package/modules/xlsx/parseSharedString.js.map +0 -1
- package/modules/xlsx/parseSheetData.js +0 -55
- package/modules/xlsx/parseSheetData.js.map +0 -1
- package/modules/xlsx/reconstructSheetDimensionsFromSheetCells.js +0 -23
- package/modules/xlsx/reconstructSheetDimensionsFromSheetCells.js.map +0 -1
- package/modules/xml/parseXmlStream.saxen.code.js +0 -947
- package/modules/xml/parseXmlStream.saxen.code.js.map +0 -1
- package/modules/xml/parseXmlStream.test.js.map +0 -1
|
@@ -1,71 +1,72 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Parses spreadsheet info.
|
|
3
3
|
* @param {string} content
|
|
4
|
-
* @param {function}
|
|
4
|
+
* @param {function} parseXml — SAX XML parser.
|
|
5
5
|
* @returns {object} An object of shape `{ epoch1904: boolean, sheets: Sheet[] }`.
|
|
6
6
|
*/
|
|
7
|
-
export default function parseSpreadsheetInfo(content,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
})
|
|
7
|
+
export default function parseSpreadsheetInfo(content, parseXml) {
|
|
8
|
+
var state = createInitialState();
|
|
9
|
+
return parseXml(content, state, onOpenTag, null, null).then(function () {
|
|
10
|
+
return getResultFromState(state);
|
|
11
|
+
});
|
|
12
|
+
function createInitialState() {
|
|
13
|
+
return {
|
|
14
|
+
workbookPr: undefined,
|
|
15
|
+
sheets: []
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function getResultFromState(state) {
|
|
12
19
|
return {
|
|
13
20
|
epoch1904: state.workbookPr ? state.workbookPr.epoch1904 : false,
|
|
14
21
|
sheets: state.sheets
|
|
15
22
|
};
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// Deleting and adding new sheets might cause the sheetId values to become non-sequential.
|
|
64
|
-
// For example, `sheetId`s could be `1`, `2`, `4`, if sheet `3` was deleted.
|
|
65
|
-
id: Number(attributes.sheetId),
|
|
66
|
-
name: attributes.name,
|
|
67
|
-
relationId: attributes['r:id']
|
|
68
|
-
});
|
|
23
|
+
}
|
|
24
|
+
function onOpenTag(tagName, attributes, state) {
|
|
25
|
+
if (tagName === 'workbookPr') {
|
|
26
|
+
// The official Open XML specification dictates that the top-level `<workbook/>` element
|
|
27
|
+
// should only contain exactly one `<workbookPr/>` element. In case of multiple ones,
|
|
28
|
+
// only the first one is being read and the rest are simply ignored.
|
|
29
|
+
//
|
|
30
|
+
// There's a `1904-based-dates.xlsx` test case that happens to include multiple `<workbookPr/>`
|
|
31
|
+
// elements by accident, most likely because I edited its `.xml` files by hand and didn't notice
|
|
32
|
+
// the already-existing `<workbookPr/>` tag.
|
|
33
|
+
//
|
|
34
|
+
// At first I thought about just fixing that one `.xlsx` test file but later
|
|
35
|
+
// I saw that another library called `SheetJS` specifically handles such cases
|
|
36
|
+
// by only reading the first `<workbookPr/>` element and ignoring the rest,
|
|
37
|
+
// so I though that perhaps it would make some sense to do same thing here.
|
|
38
|
+
// https://github.com/SheetJS/sheetjs/issues/1619
|
|
39
|
+
//
|
|
40
|
+
if (!state.workbookPr) {
|
|
41
|
+
// Read `<workbookPr/>` element attributes to detect whether dates are 1900-based or 1904-based.
|
|
42
|
+
// https://support.microsoft.com/en-gb/help/214330/differences-between-the-1900-and-the-1904-date-system-in-excel
|
|
43
|
+
// http://webapp.docx4java.org/OnlineDemo/ecma376/SpreadsheetML/workbookPr.html
|
|
44
|
+
state.workbookPr = {
|
|
45
|
+
epoch1904: attributes.date1904 === '1'
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
} else if (tagName === 'sheet') {
|
|
49
|
+
// Example of `<sheets/>` element:
|
|
50
|
+
// ```
|
|
51
|
+
// <sheets>
|
|
52
|
+
// <sheet
|
|
53
|
+
// xmlns:ns="http://schemas.openxmlformats.org/officeDocument/2006/relationships"
|
|
54
|
+
// name="Sheet1"
|
|
55
|
+
// sheetId="1"
|
|
56
|
+
// ns:id="rId3"/>
|
|
57
|
+
// </sheets>
|
|
58
|
+
// ```
|
|
59
|
+
if (attributes.name) {
|
|
60
|
+
state.sheets.push({
|
|
61
|
+
// `sheetId` attribute value is an arbitrary, `1`-based unique positive integer
|
|
62
|
+
// assigned to a worksheet, typically starting at `1` for the first sheet.
|
|
63
|
+
// Deleting and adding new sheets might cause the sheetId values to become non-sequential.
|
|
64
|
+
// For example, `sheetId`s could be `1`, `2`, `4`, if sheet `3` was deleted.
|
|
65
|
+
id: Number(attributes.sheetId),
|
|
66
|
+
name: attributes.name,
|
|
67
|
+
relationId: attributes['r:id']
|
|
68
|
+
});
|
|
69
|
+
}
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseSpreadsheetInfo.js","names":["parseSpreadsheetInfo","content","
|
|
1
|
+
{"version":3,"file":"parseSpreadsheetInfo.js","names":["parseSpreadsheetInfo","content","parseXml","state","createInitialState","onOpenTag","then","getResultFromState","workbookPr","undefined","sheets","epoch1904","tagName","attributes","date1904","name","push","id","Number","sheetId","relationId"],"sources":["../../source/xlsx/parseSpreadsheetInfo.js"],"sourcesContent":["/**\r\n * Parses spreadsheet info.\r\n * @param {string} content\r\n * @param {function} parseXml — SAX XML parser.\r\n * @returns {object} An object of shape `{ epoch1904: boolean, sheets: Sheet[] }`.\r\n */\r\nexport default function parseSpreadsheetInfo(content, parseXml) {\r\n const state = createInitialState()\r\n return parseXml(\r\n content,\r\n state,\r\n onOpenTag,\r\n null,\r\n null\r\n ).then(() => getResultFromState(state))\r\n\r\n function createInitialState() {\r\n return {\r\n workbookPr: undefined,\r\n sheets: []\r\n }\r\n }\r\n\r\n function getResultFromState(state) {\r\n return {\r\n epoch1904: state.workbookPr ? state.workbookPr.epoch1904 : false,\r\n sheets: state.sheets\r\n }\r\n }\r\n\r\n function onOpenTag(tagName, attributes, state) {\r\n if (tagName === 'workbookPr') {\r\n // The official Open XML specification dictates that the top-level `<workbook/>` element\r\n // should only contain exactly one `<workbookPr/>` element. In case of multiple ones,\r\n // only the first one is being read and the rest are simply ignored.\r\n //\r\n // There's a `1904-based-dates.xlsx` test case that happens to include multiple `<workbookPr/>`\r\n // elements by accident, most likely because I edited its `.xml` files by hand and didn't notice\r\n // the already-existing `<workbookPr/>` tag.\r\n //\r\n // At first I thought about just fixing that one `.xlsx` test file but later\r\n // I saw that another library called `SheetJS` specifically handles such cases\r\n // by only reading the first `<workbookPr/>` element and ignoring the rest,\r\n // so I though that perhaps it would make some sense to do same thing here.\r\n // https://github.com/SheetJS/sheetjs/issues/1619\r\n //\r\n if (!state.workbookPr) {\r\n // Read `<workbookPr/>` element attributes to detect whether dates are 1900-based or 1904-based.\r\n // https://support.microsoft.com/en-gb/help/214330/differences-between-the-1900-and-the-1904-date-system-in-excel\r\n // http://webapp.docx4java.org/OnlineDemo/ecma376/SpreadsheetML/workbookPr.html\r\n state.workbookPr = {\r\n epoch1904: attributes.date1904 === '1'\r\n }\r\n }\r\n } else if (tagName === 'sheet') {\r\n // Example of `<sheets/>` element:\r\n // ```\r\n // <sheets>\r\n // <sheet\r\n // xmlns:ns=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"\r\n // name=\"Sheet1\"\r\n // sheetId=\"1\"\r\n // ns:id=\"rId3\"/>\r\n // </sheets>\r\n // ```\r\n if (attributes.name) {\r\n state.sheets.push({\r\n // `sheetId` attribute value is an arbitrary, `1`-based unique positive integer\r\n // assigned to a worksheet, typically starting at `1` for the first sheet.\r\n // Deleting and adding new sheets might cause the sheetId values to become non-sequential.\r\n // For example, `sheetId`s could be `1`, `2`, `4`, if sheet `3` was deleted.\r\n id: Number(attributes.sheetId),\r\n name: attributes.name,\r\n relationId: attributes['r:id']\r\n })\r\n }\r\n }\r\n }\r\n}"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAASA,oBAAoBA,CAACC,OAAO,EAAEC,QAAQ,EAAE;EAC9D,IAAMC,KAAK,GAAGC,kBAAkB,CAAC,CAAC;EAClC,OAAOF,QAAQ,CACbD,OAAO,EACPE,KAAK,EACLE,SAAS,EACT,IAAI,EACJ,IACF,CAAC,CAACC,IAAI,CAAC;IAAA,OAAMC,kBAAkB,CAACJ,KAAK,CAAC;EAAA,EAAC;EAEvC,SAASC,kBAAkBA,CAAA,EAAG;IAC5B,OAAO;MACLI,UAAU,EAAEC,SAAS;MACrBC,MAAM,EAAE;IACV,CAAC;EACH;EAEA,SAASH,kBAAkBA,CAACJ,KAAK,EAAE;IACjC,OAAO;MACLQ,SAAS,EAAER,KAAK,CAACK,UAAU,GAAGL,KAAK,CAACK,UAAU,CAACG,SAAS,GAAG,KAAK;MAChED,MAAM,EAAEP,KAAK,CAACO;IAChB,CAAC;EACH;EAEA,SAASL,SAASA,CAACO,OAAO,EAAEC,UAAU,EAAEV,KAAK,EAAE;IAC7C,IAAIS,OAAO,KAAK,YAAY,EAAE;MAC5B;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA,IAAI,CAACT,KAAK,CAACK,UAAU,EAAE;QACrB;QACA;QACA;QACAL,KAAK,CAACK,UAAU,GAAG;UACjBG,SAAS,EAAEE,UAAU,CAACC,QAAQ,KAAK;QACrC,CAAC;MACH;IACF,CAAC,MAAM,IAAIF,OAAO,KAAK,OAAO,EAAE;MAC9B;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA;MACA,IAAIC,UAAU,CAACE,IAAI,EAAE;QACnBZ,KAAK,CAACO,MAAM,CAACM,IAAI,CAAC;UAChB;UACA;UACA;UACA;UACAC,EAAE,EAAEC,MAAM,CAACL,UAAU,CAACM,OAAO,CAAC;UAC9BJ,IAAI,EAAEF,UAAU,CAACE,IAAI;UACrBK,UAAU,EAAEP,UAAU,CAAC,MAAM;QAC/B,CAAC,CAAC;MACJ;IACF;EACF;AACF"}
|
|
@@ -13,17 +13,29 @@ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) r
|
|
|
13
13
|
* Returns an array of cell styles.
|
|
14
14
|
* A cell style index is the cell style ID.
|
|
15
15
|
* @param {string} content
|
|
16
|
-
* @param {function}
|
|
16
|
+
* @param {function} parseXml — SAX XML parser.
|
|
17
17
|
* @returns {object} styles
|
|
18
18
|
*/
|
|
19
|
-
export default function parseStyles(content,
|
|
19
|
+
export default function parseStyles(content, parseXml) {
|
|
20
20
|
// 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
|
|
21
21
|
// https://www.office-forums.com/threads/cellxfs-cellstylexfs.2163519/
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
var state = createInitialState();
|
|
23
|
+
return parseXml(content, state, onOpenTag, onCloseTag, null).then(function () {
|
|
24
|
+
return getResultFromState(state);
|
|
25
|
+
});
|
|
26
|
+
function createInitialState() {
|
|
27
|
+
return {
|
|
28
|
+
numberFormats: {},
|
|
29
|
+
baseStyles: [],
|
|
30
|
+
// The first `164` elements of the `styles` array are going to be `undefined`
|
|
31
|
+
// because those represent the built-in "default" styles in `.xlsx` specification.
|
|
32
|
+
// These "default" styles have IDs from `0` to `163`, i.e. according to their index.
|
|
33
|
+
styles: [],
|
|
34
|
+
cellStyleXfs: false,
|
|
35
|
+
cellXfs: false
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
function getResultFromState(state) {
|
|
27
39
|
return state.styles.map(function (style) {
|
|
28
40
|
if (style.xfId) {
|
|
29
41
|
var xfId = style.xfId,
|
|
@@ -33,79 +45,67 @@ export default function parseStyles(content, parseXmlStream) {
|
|
|
33
45
|
return style;
|
|
34
46
|
}
|
|
35
47
|
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
cellStyleXfs
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (state.cellStyleXfs) {
|
|
68
|
-
// The index of a `<xf/>` element is by definition its numeric ID.
|
|
69
|
-
// Therefore, even empty `style` elements still must be put into the array.
|
|
70
|
-
state.baseStyles.push(parseCellStyle(attributes));
|
|
71
|
-
} else if (state.cellXfs) {
|
|
72
|
-
var style = parseCellStyle(attributes, state.numberFormats);
|
|
73
|
-
// A style might extend a "base style" by its numeric ID.
|
|
74
|
-
if (attributes.xfId) {
|
|
75
|
-
style.xfId = Number(attributes.xfId);
|
|
48
|
+
}
|
|
49
|
+
function onOpenTag(tagName, attributes, state) {
|
|
50
|
+
if (tagName === 'numFmt') {
|
|
51
|
+
// `<numFmts/>` element contains `<numFmt/>` elements.
|
|
52
|
+
// `<numFmt/>` defines a "number format" template.
|
|
53
|
+
// The value of `numFmtId` attribute is a (numeric) ID of this "number format".
|
|
54
|
+
state.numberFormats[attributes.numFmtId] = {
|
|
55
|
+
id: Number(attributes.numFmtId),
|
|
56
|
+
template: attributes.formatCode
|
|
57
|
+
};
|
|
58
|
+
} else if (tagName === 'cellStyleXfs') {
|
|
59
|
+
// `<cellStyleXfs/>` contains "base styles" that could be extended by `<cellXfs/>`.
|
|
60
|
+
// These styles don't apply to individual cells directly. They can only be extended.
|
|
61
|
+
state.cellStyleXfs = true;
|
|
62
|
+
} else if (tagName === 'cellXfs') {
|
|
63
|
+
// `<cellXfs/>` contains individual cell styles. They can extend "base styles".
|
|
64
|
+
state.cellXfs = true;
|
|
65
|
+
} else if (tagName === 'xf') {
|
|
66
|
+
if (state.cellStyleXfs) {
|
|
67
|
+
// The index of a `<xf/>` element is by definition its numeric ID.
|
|
68
|
+
// Therefore, even empty `style` elements still must be put into the array.
|
|
69
|
+
state.baseStyles.push(parseCellStyle(attributes));
|
|
70
|
+
} else if (state.cellXfs) {
|
|
71
|
+
var style = parseCellStyle(attributes, state.numberFormats);
|
|
72
|
+
// A style might extend a "base style" by its numeric ID.
|
|
73
|
+
if (attributes.xfId) {
|
|
74
|
+
style.xfId = Number(attributes.xfId);
|
|
75
|
+
}
|
|
76
|
+
// The index of a `<xf/>` element is by definition its numeric ID.
|
|
77
|
+
// Therefore, even empty `style` elements still must be put into the array.
|
|
78
|
+
state.styles.push(style);
|
|
76
79
|
}
|
|
77
|
-
// The index of a `<xf/>` element is by definition its numeric ID.
|
|
78
|
-
// Therefore, even empty `style` elements still must be put into the array.
|
|
79
|
-
state.styles.push(style);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
82
|
+
function onCloseTag(tagName, state) {
|
|
83
|
+
if (tagName === 'cellStyleXfs') {
|
|
84
|
+
state.cellStyleXfs = false;
|
|
85
|
+
} else if (tagName === 'cellXfs') {
|
|
86
|
+
state.cellXfs = false;
|
|
87
|
+
}
|
|
88
88
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
}
|
|
89
|
+
function parseCellStyle(attributes, numberFormats) {
|
|
90
|
+
var style = {};
|
|
91
|
+
// `numFmtId` in `<cellStyleXfs/>` and `<cellXfs/>` is a numerical ID
|
|
92
|
+
// referencing the cell's "number format". Values from `0` to `163` are built-in formats,
|
|
93
|
+
// while values `164` and above are custom formats defined in the `<numFmts/>` element.
|
|
94
|
+
var numFmtId = attributes.numFmtId;
|
|
95
|
+
if (numFmtId) {
|
|
96
|
+
// Built-in number formats don't have a `<numFmt/>` element in `styles.xml`.
|
|
97
|
+
// https://hexdocs.pm/xlsxir/number_styles.html
|
|
98
|
+
if (numberFormats && numberFormats[numFmtId]) {
|
|
99
|
+
// Non-built-in number format.
|
|
100
|
+
style.numberFormat = numberFormats[numFmtId];
|
|
101
|
+
} else {
|
|
102
|
+
// Built-in number format.
|
|
103
|
+
style.numberFormat = {
|
|
104
|
+
id: Number(numFmtId)
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
107
|
}
|
|
108
|
+
return style;
|
|
108
109
|
}
|
|
109
|
-
return style;
|
|
110
110
|
}
|
|
111
111
|
//# sourceMappingURL=parseStyles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseStyles.js","names":["parseStyles","content","
|
|
1
|
+
{"version":3,"file":"parseStyles.js","names":["parseStyles","content","parseXml","state","createInitialState","onOpenTag","onCloseTag","then","getResultFromState","numberFormats","baseStyles","styles","cellStyleXfs","cellXfs","map","style","xfId","styleProperties","_objectWithoutProperties","_excluded","_objectSpread","tagName","attributes","numFmtId","id","Number","template","formatCode","push","parseCellStyle","numberFormat"],"sources":["../../source/xlsx/parseStyles.js"],"sourcesContent":["/**\r\n * Parses `.xlsx` file styles.\r\n * http://officeopenxml.com/SSstyles.php\r\n * Returns an array of cell styles.\r\n * A cell style index is the cell style ID.\r\n * @param {string} content\r\n * @param {function} parseXml — SAX XML parser.\r\n * @returns {object} styles\r\n */\r\nexport default function parseStyles(content, parseXml) {\r\n // 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\r\n // https://www.office-forums.com/threads/cellxfs-cellstylexfs.2163519/\r\n const state = createInitialState()\r\n return parseXml(\r\n content,\r\n state,\r\n onOpenTag,\r\n onCloseTag,\r\n null\r\n ).then(() => getResultFromState(state))\r\n\r\n function createInitialState() {\r\n return {\r\n numberFormats: {},\r\n baseStyles: [],\r\n // The first `164` elements of the `styles` array are going to be `undefined`\r\n // because those represent the built-in \"default\" styles in `.xlsx` specification.\r\n // These \"default\" styles have IDs from `0` to `163`, i.e. according to their index.\r\n styles: [],\r\n cellStyleXfs: false,\r\n cellXfs: false\r\n }\r\n }\r\n\r\n function getResultFromState(state) {\r\n return state.styles.map((style) => {\r\n if (style.xfId) {\r\n const { xfId, ...styleProperties } = style\r\n return {\r\n ...state.baseStyles[xfId],\r\n ...styleProperties\r\n }\r\n } else {\r\n return style\r\n }\r\n })\r\n }\r\n\r\n function onOpenTag(tagName, attributes, state) {\r\n if (tagName === 'numFmt') {\r\n // `<numFmts/>` element contains `<numFmt/>` elements.\r\n // `<numFmt/>` defines a \"number format\" template.\r\n // The value of `numFmtId` attribute is a (numeric) ID of this \"number format\".\r\n state.numberFormats[attributes.numFmtId] = {\r\n id: Number(attributes.numFmtId),\r\n template: attributes.formatCode\r\n }\r\n } else if (tagName === 'cellStyleXfs') {\r\n // `<cellStyleXfs/>` contains \"base styles\" that could be extended by `<cellXfs/>`.\r\n // These styles don't apply to individual cells directly. They can only be extended.\r\n state.cellStyleXfs = true\r\n } else if (tagName === 'cellXfs') {\r\n // `<cellXfs/>` contains individual cell styles. They can extend \"base styles\".\r\n state.cellXfs = true\r\n } else if (tagName === 'xf') {\r\n if (state.cellStyleXfs) {\r\n // The index of a `<xf/>` element is by definition its numeric ID.\r\n // Therefore, even empty `style` elements still must be put into the array.\r\n state.baseStyles.push(parseCellStyle(attributes))\r\n } else if (state.cellXfs) {\r\n const style = parseCellStyle(attributes, state.numberFormats)\r\n // A style might extend a \"base style\" by its numeric ID.\r\n if (attributes.xfId) {\r\n style.xfId = Number(attributes.xfId)\r\n }\r\n // The index of a `<xf/>` element is by definition its numeric ID.\r\n // Therefore, even empty `style` elements still must be put into the array.\r\n state.styles.push(style)\r\n }\r\n }\r\n }\r\n\r\n function onCloseTag(tagName, state) {\r\n if (tagName === 'cellStyleXfs') {\r\n state.cellStyleXfs = false\r\n } else if (tagName === 'cellXfs') {\r\n state.cellXfs = false\r\n }\r\n }\r\n\r\n function parseCellStyle(attributes, numberFormats) {\r\n const style = {}\r\n // `numFmtId` in `<cellStyleXfs/>` and `<cellXfs/>` is a numerical ID\r\n // referencing the cell's \"number format\". Values from `0` to `163` are built-in formats,\r\n // while values `164` and above are custom formats defined in the `<numFmts/>` element.\r\n const { numFmtId } = attributes\r\n if (numFmtId) {\r\n // Built-in number formats don't have a `<numFmt/>` element in `styles.xml`.\r\n // https://hexdocs.pm/xlsxir/number_styles.html\r\n if (numberFormats && numberFormats[numFmtId]) {\r\n // Non-built-in number format.\r\n style.numberFormat = numberFormats[numFmtId]\r\n } else {\r\n // Built-in number format.\r\n style.numberFormat = { id: Number(numFmtId) }\r\n }\r\n }\r\n return style\r\n }\r\n}"],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import parseXmlStream from './parseXmlStream.js';
|
|
2
|
+
import InvalidSpreadsheetError from '../xlsx/InvalidSpreadsheetError.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Parses XML markup by calling the supplied callback functions.
|
|
6
|
+
* @param {string} xml
|
|
7
|
+
* @param {any} state — The initial `state`. This `state` will supposedly be modified by the callback functions as the XML is being parsed.
|
|
8
|
+
* @param {function} [onOpenTag]
|
|
9
|
+
* @param {function} [onCloseTag]
|
|
10
|
+
* @param {function} [onText]
|
|
11
|
+
* @param {function} [onProgress] — If defined, will be called every time it finishes parsing yet another chunk of XML.
|
|
12
|
+
* @returns {Promise<void>} Returns a `Promise` that resolves to nothing. Inspect the passed `state` argument for changes.
|
|
13
|
+
*/
|
|
14
|
+
export default function parseXml(xml, state, onOpenTag, onCloseTag, onText, onProgress) {
|
|
15
|
+
var parser = parseXmlStream(state, onOpenTag, onCloseTag, onText);
|
|
16
|
+
if (onProgress) {
|
|
17
|
+
parseXmlInChunks(parser, xml, onProgress);
|
|
18
|
+
} else {
|
|
19
|
+
// Parse XML "all at once"
|
|
20
|
+
parser.write(xml);
|
|
21
|
+
parser.end();
|
|
22
|
+
}
|
|
23
|
+
return parser.promise.then(function (result) {
|
|
24
|
+
return result;
|
|
25
|
+
}, function (error) {
|
|
26
|
+
// If the error is not re-thrown here, the parser will simply keep parsing,
|
|
27
|
+
// i.e. it doesn't halt after encountering an error and doesn't require manual resuming.
|
|
28
|
+
// So it must re-throw the error here in order for the parser to stop.
|
|
29
|
+
// Because the error is thrown inside a `new Promise()` constructor,
|
|
30
|
+
// the promise will reject automatically.
|
|
31
|
+
var spreadsheetError = new InvalidSpreadsheetError(error.message);
|
|
32
|
+
spreadsheetError.stack = error.stack;
|
|
33
|
+
spreadsheetError.cause = error;
|
|
34
|
+
throw spreadsheetError;
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// This function is placed here inside the wrapper function body
|
|
38
|
+
// in order to not to hav `worker-f`
|
|
39
|
+
/**
|
|
40
|
+
* Parses XML in chunks.
|
|
41
|
+
* @param {object} parser — An object returned from `parseXmlStream()` function.
|
|
42
|
+
* @param {string} xml
|
|
43
|
+
* @param {function} [onProgress] — Will be called after yet another chunk of XML has been parsed.
|
|
44
|
+
* @param {boolean} [nonBlocking] — If `true` is passed then it won't block the current thread while parsing. Otherwise, it will block the current thread until all the XML is parsed.
|
|
45
|
+
*/
|
|
46
|
+
function parseXmlInChunks(parser, xml, onProgress, nonBlocking) {
|
|
47
|
+
var MAX_CHUNK_PROCESSING_TIME = 7; // 16 ms — 60 fps, 7 ms — 144 fps
|
|
48
|
+
var INITIAL_CHUNK_SIZE = 64 * 1024; // 64 KB
|
|
49
|
+
|
|
50
|
+
var chunksCount = 0;
|
|
51
|
+
var chunkSize = INITIAL_CHUNK_SIZE;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Parses next chunk of XML.
|
|
55
|
+
* @returns {boolean} Returns `true` if there're more chunks to write.
|
|
56
|
+
*/
|
|
57
|
+
var parseNextChunk = function parseNextChunk() {
|
|
58
|
+
chunksCount++;
|
|
59
|
+
var startedAt = Date.now();
|
|
60
|
+
if (xml.length > chunkSize) {
|
|
61
|
+
parser.write(xml.slice(0, chunkSize));
|
|
62
|
+
if (onProgress) {
|
|
63
|
+
onProgress(false);
|
|
64
|
+
}
|
|
65
|
+
xml = xml.slice(chunkSize);
|
|
66
|
+
var chunkProcessingTime = Date.now() - startedAt;
|
|
67
|
+
if (chunkProcessingTime < MAX_CHUNK_PROCESSING_TIME * 0.5) {
|
|
68
|
+
chunkSize *= 2;
|
|
69
|
+
} else if (chunkProcessingTime > MAX_CHUNK_PROCESSING_TIME) {
|
|
70
|
+
chunkSize /= 2;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
} else {
|
|
74
|
+
parser.write(xml);
|
|
75
|
+
parser.end();
|
|
76
|
+
if (onProgress) {
|
|
77
|
+
onProgress(true);
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Parses next chunk of XML and then repeats.
|
|
85
|
+
*/
|
|
86
|
+
var loop = function loop() {
|
|
87
|
+
if (parseNextChunk()) {
|
|
88
|
+
if (nonBlocking) {
|
|
89
|
+
if (typeof setImmediate !== 'undefined') {
|
|
90
|
+
setImmediate(loop);
|
|
91
|
+
} else {
|
|
92
|
+
setTimeout(loop, 0);
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
loop();
|
|
96
|
+
}
|
|
97
|
+
} else {
|
|
98
|
+
// Finished
|
|
99
|
+
// console.log('* chunk size', chunkSize)
|
|
100
|
+
// console.log('* chunks count', chunksCount)
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
loop();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=parseXml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseXml.js","names":["parseXmlStream","InvalidSpreadsheetError","parseXml","xml","state","onOpenTag","onCloseTag","onText","onProgress","parser","parseXmlInChunks","write","end","promise","then","result","error","spreadsheetError","message","stack","cause","nonBlocking","MAX_CHUNK_PROCESSING_TIME","INITIAL_CHUNK_SIZE","chunksCount","chunkSize","parseNextChunk","startedAt","Date","now","length","slice","chunkProcessingTime","loop","setImmediate","setTimeout"],"sources":["../../source/xml/parseXml.js"],"sourcesContent":["import parseXmlStream from './parseXmlStream.js'\r\n\r\nimport InvalidSpreadsheetError from '../xlsx/InvalidSpreadsheetError.js'\r\n\r\n/**\r\n * Parses XML markup by calling the supplied callback functions.\r\n * @param {string} xml\r\n * @param {any} state — The initial `state`. This `state` will supposedly be modified by the callback functions as the XML is being parsed.\r\n * @param {function} [onOpenTag]\r\n * @param {function} [onCloseTag]\r\n * @param {function} [onText]\r\n * @param {function} [onProgress] — If defined, will be called every time it finishes parsing yet another chunk of XML.\r\n * @returns {Promise<void>} Returns a `Promise` that resolves to nothing. Inspect the passed `state` argument for changes.\r\n */\r\nexport default function parseXml(xml, state, onOpenTag, onCloseTag, onText, onProgress) {\r\n\tconst parser = parseXmlStream(state, onOpenTag, onCloseTag, onText)\r\n\r\n\tif (onProgress) {\r\n\t\tparseXmlInChunks(parser, xml, onProgress)\r\n\t} else {\r\n\t\t// Parse XML \"all at once\"\r\n\t\tparser.write(xml)\r\n\t\tparser.end()\r\n\t}\r\n\r\n\treturn parser.promise.then(\r\n\t\tresult => result,\r\n\t\t(error) => {\r\n\t\t\t// If the error is not re-thrown here, the parser will simply keep parsing,\r\n\t\t\t// i.e. it doesn't halt after encountering an error and doesn't require manual resuming.\r\n\t\t\t// So it must re-throw the error here in order for the parser to stop.\r\n\t\t\t// Because the error is thrown inside a `new Promise()` constructor,\r\n\t\t\t// the promise will reject automatically.\r\n\t\t\tconst spreadsheetError = new InvalidSpreadsheetError(error.message)\r\n\t\t\tspreadsheetError.stack = error.stack\r\n\t\t\tspreadsheetError.cause = error\r\n\t\t\tthrow spreadsheetError\r\n\t\t}\r\n\t)\r\n\r\n\t// This function is placed here inside the wrapper function body\r\n\t// in order to not to hav `worker-f`\r\n\t/**\r\n\t * Parses XML in chunks.\r\n\t * @param {object} parser — An object returned from `parseXmlStream()` function.\r\n\t * @param {string} xml\r\n\t * @param {function} [onProgress] — Will be called after yet another chunk of XML has been parsed.\r\n\t * @param {boolean} [nonBlocking] — If `true` is passed then it won't block the current thread while parsing. Otherwise, it will block the current thread until all the XML is parsed.\r\n\t */\r\n\tfunction parseXmlInChunks(parser, xml, onProgress, nonBlocking) {\r\n\t\tconst MAX_CHUNK_PROCESSING_TIME = 7 // 16 ms — 60 fps, 7 ms — 144 fps\r\n\t\tconst INITIAL_CHUNK_SIZE = 64 * 1024 // 64 KB\r\n\r\n\t\tlet chunksCount = 0\r\n\t\tlet chunkSize = INITIAL_CHUNK_SIZE\r\n\r\n\t\t/**\r\n\t\t * Parses next chunk of XML.\r\n\t\t * @returns {boolean} Returns `true` if there're more chunks to write.\r\n\t\t */\r\n\t\tconst parseNextChunk = () => {\r\n\t\t\tchunksCount++\r\n\t\t\tconst startedAt = Date.now()\r\n\t\t\tif (xml.length > chunkSize) {\r\n\t\t\t\tparser.write(xml.slice(0, chunkSize))\r\n\t\t\t\tif (onProgress) {\r\n\t\t\t\t\tonProgress(false)\r\n\t\t\t\t}\r\n\t\t\t\txml = xml.slice(chunkSize)\r\n\t\t\t\tconst chunkProcessingTime = Date.now() - startedAt\r\n\t\t\t\tif (chunkProcessingTime < MAX_CHUNK_PROCESSING_TIME * 0.5) {\r\n\t\t\t\t\tchunkSize *= 2\r\n\t\t\t\t} else if (chunkProcessingTime > MAX_CHUNK_PROCESSING_TIME) {\r\n\t\t\t\t\tchunkSize /= 2\r\n\t\t\t\t}\r\n\t\t\t\treturn true\r\n\t\t\t} else {\r\n\t\t\t\tparser.write(xml)\r\n\t\t\t\tparser.end()\r\n\t\t\t\tif (onProgress) {\r\n\t\t\t\t\tonProgress(true)\r\n\t\t\t\t}\r\n\t\t\t\treturn false\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t/**\r\n\t\t * Parses next chunk of XML and then repeats.\r\n\t\t */\r\n\t\tconst loop = () => {\r\n\t\t\tif (parseNextChunk()) {\r\n\t\t\t\tif (nonBlocking) {\r\n\t\t\t\t\tif (typeof setImmediate !== 'undefined') {\r\n\t\t\t\t\t\tsetImmediate(loop)\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\tsetTimeout(loop, 0)\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\tloop()\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// Finished\r\n\t\t\t\t// console.log('* chunk size', chunkSize)\r\n\t\t\t\t// console.log('* chunks count', chunksCount)\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tloop()\r\n\t}\r\n}"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseXml.test.js","names":["_regeneratorRuntime","e","t","r","Object","prototype","n","hasOwnProperty","o","defineProperty","value","i","Symbol","a","iterator","c","asyncIterator","u","toStringTag","define","enumerable","configurable","writable","wrap","Generator","create","Context","makeInvokeMethod","tryCatch","type","arg","call","h","l","f","s","y","GeneratorFunction","GeneratorFunctionPrototype","p","d","getPrototypeOf","v","values","g","defineIteratorMethods","forEach","_invoke","AsyncIterator","invoke","_typeof","resolve","__await","then","callInvokeWithMethodAndArg","Error","done","method","delegate","maybeInvokeDelegate","sent","_sent","dispatchException","abrupt","TypeError","resultName","next","nextLoc","pushTryEntry","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","push","resetTryEntry","completion","reset","isNaN","length","displayName","isGeneratorFunction","constructor","name","mark","setPrototypeOf","__proto__","awrap","async","Promise","keys","reverse","pop","prev","charAt","slice","stop","rval","handle","complete","finish","_catch","delegateYield","asyncGeneratorStep","gen","reject","_next","_throw","key","info","error","_asyncToGenerator","fn","self","args","arguments","apply","err","undefined","describe","it","expect","parseXml","_callee","_callee$","_context","t0","parseXmlTextContent","t1","to","equal","_callee2","_callee2$","_context2","_callee3","_callee3$","_context3","_callee4","state","onOpenTag","_callee4$","_context4","names","tagName","attributes","deep","xml","text","onText"],"sources":["../../source/xml/parseXml.test.js"],"sourcesContent":["import { describe, it } from 'mocha'\r\nimport { expect } from 'chai'\r\n\r\nimport parseXml from './parseXml.js'\r\n\r\ndescribe('parseXmlStream', () => {\r\n\tit('should decode numeric character references in text', async () => {\r\n\t\t// Some tools (e.g. `openpyxl`) escape non-ASCII characters when writing XML.\r\n\t\texpect(await parseXmlTextContent('<r><t>Café été</t></r>')).to.equal('Café été')\r\n\t})\r\n\r\n\tit('should decode predefined XML entities in text', async () => {\r\n\t\texpect(await parseXmlTextContent('<r><t><a> & "b" 'c'</t></r>')).to.equal('<a> & \"b\" \\'c\\'')\r\n\t})\r\n\r\n\tit('should pass text without character references through unchanged', async () => {\r\n\t\texpect(await parseXmlTextContent('<r><t>abc</t></r>')).to.equal('abc')\r\n\t})\r\n\r\n\tit('should decode character references in attribute values', async () => {\r\n\t\t// Sheet names are read from the `name` attribute\r\n\t\t// in `xl/workbook.xml` file: `<sheet name=\"P&L\"/>`.\r\n\t\tconst state = { names: [] }\r\n\t\tconst onOpenTag = (tagName, attributes, state) => {\r\n\t\t\tif (tagName === 'sheet') {\r\n\t\t\t\tstate.names.push(attributes.name)\r\n\t\t\t}\r\n\t\t}\r\n\t\tawait parseXml(\r\n\t\t\t'<sheets><sheet name=\"P&L été\"/></sheets>',\r\n\t\t\tstate,\r\n\t\t\tonOpenTag,\r\n\t\t\tnull,\r\n\t\t\tnull\r\n\t\t)\r\n\t\texpect(state.names).to.deep.equal(['P&L été'])\r\n\t})\r\n})\r\n\r\nfunction parseXmlTextContent(xml) {\r\n\tconst state = { text: '' }\r\n\tconst onText = (text, state) => {\r\n\t\tstate.text += text\r\n\t}\r\n\treturn parseXml(\r\n\t\txml,\r\n\t\tstate,\r\n\t\tnull,\r\n\t\tnull,\r\n\t\tonText\r\n\t).then(() => state.text)\r\n}\r\n"],"mappings":"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"}
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
// but the weird part is that when enabled, "streaming" mode results in significantly slower parsing:
|
|
12
12
|
// about `3.1` secs. in "streaming" mode vs about `1.4` secs. in non-"streaming" mode.
|
|
13
13
|
//
|
|
14
|
+
// `saxen` has a PR open that adds "streaming" functionality: https://github.com/nikku/saxen/pull/27
|
|
15
|
+
//
|
|
14
16
|
// `sax` "bundled" size is `22.5 kB` (`8.1 kB` gzipped).
|
|
15
17
|
// `saxen` "bundled" size is `6.15 kB` (`2.7 kB` gzipped).
|
|
16
18
|
//
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parseXmlStream.js","names":["default"],"sources":["../../source/xml/parseXmlStream.js"],"sourcesContent":["// Currently there're 2 XML stream parser implementations:\r\n// * `sax` — The \"classic\" one. Supports Node.js streams.\r\n// * `saxen` — The small and fast one.\r\n//\r\n// `sax` has been around for a long time, and is written by a well-known developer,\r\n// but it performance is very subpar compared to `saxen`: reading a `10 MB` `.xlsx` file\r\n// with `sax` is about `1.4` secs while with `saxen` it's about `0.3` secs,\r\n// meaning that `saxen` is light-years ahead of `sax` in terms of performance.\r\n//\r\n// `sax` has an advantage of parsing XML from a Node.js stream rather than from just a `string`,\r\n// but the weird part is that when enabled, \"streaming\" mode results in significantly slower parsing:\r\n// about `3.1` secs. in \"streaming\" mode vs about `1.4` secs. in non-\"streaming\" mode.\r\n//\r\n// `sax` \"bundled\" size is `22.5 kB` (`8.1 kB` gzipped).\r\n// `saxen` \"bundled\" size is `6.15 kB` (`2.7 kB` gzipped).\r\n//\r\nexport { default as default } from './parseXmlStream.saxen.js'"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,OAAkB,QAAQ,2BAA2B"}
|
|
1
|
+
{"version":3,"file":"parseXmlStream.js","names":["default"],"sources":["../../source/xml/parseXmlStream.js"],"sourcesContent":["// Currently there're 2 XML stream parser implementations:\r\n// * `sax` — The \"classic\" one. Supports Node.js streams.\r\n// * `saxen` — The small and fast one.\r\n//\r\n// `sax` has been around for a long time, and is written by a well-known developer,\r\n// but it performance is very subpar compared to `saxen`: reading a `10 MB` `.xlsx` file\r\n// with `sax` is about `1.4` secs while with `saxen` it's about `0.3` secs,\r\n// meaning that `saxen` is light-years ahead of `sax` in terms of performance.\r\n//\r\n// `sax` has an advantage of parsing XML from a Node.js stream rather than from just a `string`,\r\n// but the weird part is that when enabled, \"streaming\" mode results in significantly slower parsing:\r\n// about `3.1` secs. in \"streaming\" mode vs about `1.4` secs. in non-\"streaming\" mode.\r\n//\r\n// `saxen` has a PR open that adds \"streaming\" functionality: https://github.com/nikku/saxen/pull/27\r\n//\r\n// `sax` \"bundled\" size is `22.5 kB` (`8.1 kB` gzipped).\r\n// `saxen` \"bundled\" size is `6.15 kB` (`2.7 kB` gzipped).\r\n//\r\nexport { default as default } from './parseXmlStream.saxen.js'"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAASA,OAAkB,QAAQ,2BAA2B"}
|