UNPKG

read-excel-file

Version:

Read `.xlsx` files in a web browser or in Node.js

73 lines 3.1 kB
/** * Parses spreadsheet info. * @param {string} content * @param {function} parseXml — SAX XML parser. * @returns {object} An object of shape `{ epoch1904: boolean, sheets: Sheet[] }`. */ export default function parseSpreadsheetInfo(content, parseXml) { var state = createInitialState(); return parseXml(content, state, onOpenTag, null, null).then(function () { return getResultFromState(state); }); function createInitialState() { return { workbookPr: undefined, sheets: [] }; } function getResultFromState(state) { return { epoch1904: state.workbookPr ? state.workbookPr.epoch1904 : false, sheets: state.sheets }; } function onOpenTag(tagName, attributes, state) { if (tagName === 'workbookPr') { // The official Open XML specification dictates that the top-level `<workbook/>` element // should only contain exactly one `<workbookPr/>` element. In case of multiple ones, // only the first one is being read and the rest are simply ignored. // // There's a `1904-based-dates.xlsx` test case that happens to include multiple `<workbookPr/>` // elements by accident, most likely because I edited its `.xml` files by hand and didn't notice // the already-existing `<workbookPr/>` tag. // // At first I thought about just fixing that one `.xlsx` test file but later // I saw that another library called `SheetJS` specifically handles such cases // by only reading the first `<workbookPr/>` element and ignoring the rest, // so I though that perhaps it would make some sense to do same thing here. // https://github.com/SheetJS/sheetjs/issues/1619 // if (!state.workbookPr) { // Read `<workbookPr/>` element attributes to detect whether dates are 1900-based or 1904-based. // https://support.microsoft.com/en-gb/help/214330/differences-between-the-1900-and-the-1904-date-system-in-excel // http://webapp.docx4java.org/OnlineDemo/ecma376/SpreadsheetML/workbookPr.html state.workbookPr = { epoch1904: attributes.date1904 === '1' }; } } else if (tagName === 'sheet') { // Example of `<sheets/>` element: // ``` // <sheets> // <sheet // xmlns:ns="http://schemas.openxmlformats.org/officeDocument/2006/relationships" // name="Sheet1" // sheetId="1" // ns:id="rId3"/> // </sheets> // ``` if (attributes.name) { state.sheets.push({ // `sheetId` attribute value is an arbitrary, `1`-based unique positive integer // assigned to a worksheet, typically starting at `1` for the first sheet. // Deleting and adding new sheets might cause the sheetId values to become non-sequential. // For example, `sheetId`s could be `1`, `2`, `4`, if sheet `3` was deleted. id: Number(attributes.sheetId), name: attributes.name, relationId: attributes.id }); } } } } //# sourceMappingURL=parseSpreadsheetInfo.js.map