diff --git a/commonjs/excelParser.js b/commonjs/excelParser.js index e45290d..f1b7cda 100644 --- a/commonjs/excelParser.js +++ b/commonjs/excelParser.js @@ -46,16 +46,11 @@ function extractFiles(path, sheet) { return new Promise(function (resolve, reject) { var filePromises = []; - stream.pipe(_unzipper2.default.Parse()).on('error', reject).on('close', function () { + stream.pipe(_unzipper2.default.Parse()).on('error', reject).on('finish', function () { Promise.all(filePromises).then(function () { return resolve(files); }); - }) - // For some reason `end` event is not emitted. - // .on('end', () => { - // Promise.all(filePromises).then(() => resolve(files)); - // }) - .on('entry', function (entry) { + }).on('entry', function (entry) { var file = files[entry.path]; if (file) { var contents = ''; diff --git a/commonjs/excelParser.js.map b/commonjs/excelParser.js.map index cd95662..6255635 100644 --- a/commonjs/excelParser.js.map +++ b/commonjs/excelParser.js.map @@ -1 +1 @@ -{"version":3,"sources":["../excelParser.js"],"names":["parseXlsx","ns","a","select","useNamespaces","extractFiles","path","sheet","files","strings","stream","createReadStream","Promise","resolve","reject","filePromises","pipe","Parse","on","all","then","entry","file","contents","push","data","toString","autodrain","calculateDimensions","cells","comparator","b","allRows","map","cell","row","sort","allCols","column","minRow","maxRow","length","minCol","maxCol","extractData","values","DOMParser","parseFromString","valuesDoc","string","t","textContent","join","parseError","colToInt","col","letters","trim","split","n","i","indexOf","na","CellCoords","parseInt","Cell","cellNode","r","getAttribute","type","value","coords","node","d","_","cols","rows","times","action"],"mappings":"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","file":"excelParser.js","sourcesContent":["import fs from 'fs';\nimport Stream from 'stream';\nimport unzip from 'unzipper';\nimport xpath from 'xpath';\nimport XMLDOM from 'xmldom';\n\nconst ns = { a: 'http://schemas.openxmlformats.org/spreadsheetml/2006/main' };\nconst select = xpath.useNamespaces(ns);\n\nfunction extractFiles(path, sheet) {\n const files = {\n strings: {},\n sheet: {},\n 'xl/sharedStrings.xml': 'strings',\n [`xl/worksheets/sheet${sheet}.xml`]: 'sheet'\n };\n\n const stream = path instanceof Stream ? path : fs.createReadStream(path);\n\n return new Promise((resolve, reject) => {\n const filePromises = [];\n\n stream\n .pipe(unzip.Parse())\n .on('error', reject)\n .on('close', () => {\n Promise.all(filePromises).then(() => resolve(files));\n })\n // For some reason `end` event is not emitted.\n // .on('end', () => {\n // Promise.all(filePromises).then(() => resolve(files));\n // })\n .on('entry', (entry) => {\n const file = files[entry.path];\n if (file) {\n let contents = '';\n filePromises.push(new Promise((resolve) => {\n entry\n .on('data', data => contents += data.toString())\n .on('end', () => {\n files[file].contents = contents;\n resolve();\n });\n }));\n } else {\n entry.autodrain();\n }\n });\n });\n}\n\nfunction calculateDimensions (cells) {\n const comparator = (a, b) => a - b;\n const allRows = cells.map(cell => cell.row).sort(comparator);\n const allCols = cells.map(cell => cell.column).sort(comparator);\n const minRow = allRows[0];\n const maxRow = allRows[allRows.length - 1];\n const minCol = allCols[0];\n const maxCol = allCols[allCols.length - 1];\n\n return [\n { row: minRow, column: minCol },\n { row: maxRow, column: maxCol }\n ];\n}\n\nfunction extractData(files) {\n let sheet;\n let values;\n const data = [];\n\n try {\n sheet = new XMLDOM.DOMParser().parseFromString(files.sheet.contents);\n const valuesDoc = new XMLDOM.DOMParser().parseFromString(files.strings.contents);\n values = select('//a:si', valuesDoc)\n .map(string => select('.//a:t[not(ancestor::a:rPh)]', string).map(t => t.textContent).join(''));\n } catch(parseError){\n return [];\n }\n\n function colToInt(col) {\n const letters = [\"\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\"];\n col = col.trim().split('');\n\n let n = 0;\n\n for (let i = 0; i < col.length; i++) {\n n *= 26;\n n += letters.indexOf(col[i]);\n }\n\n return n;\n };\n\n const na = {\n textContent: ''\n };\n\n class CellCoords {\n constructor(cell) {\n cell = cell.split(/([0-9]+)/);\n this.row = parseInt(cell[1]);\n this.column = colToInt(cell[0]);\n }\n }\n\n class Cell {\n constructor(cellNode) {\n const r = cellNode.getAttribute('r');\n const type = cellNode.getAttribute('t') || '';\n const value = (select('a:v', cellNode, 1) || na).textContent;\n const coords = new CellCoords(r)\n\n this.column = coords.column;\n this.row = coords.row;\n this.value = value;\n this.type = type;\n }\n }\n\n const cells = select('/a:worksheet/a:sheetData/a:row/a:c', sheet).map(node => new Cell(node));\n\n let d = select('//a:dimension/@ref', sheet, 1);\n if (d) {\n d = d.textContent.split(':').map(_ => new CellCoords(_));\n } else {\n d = calculateDimensions(cells);\n }\n\n const cols = d[1].column - d[0].column + 1;\n const rows = d[1].row - d[0].row + 1;\n\n times(rows, () => {\n const row = [];\n times(cols, () => row.push(''));\n data.push(row);\n });\n\n for (const cell of cells) {\n let value = cell.value;\n\n if (cell.type == 's') {\n value = values[parseInt(value)];\n }\n\n if (data[cell.row - d[0].row]) {\n data[cell.row - d[0].row][cell.column - d[0].column] = value;\n }\n }\n\n return data;\n}\n\nexport default function parseXlsx(path, sheet = '1') {\n return extractFiles(path, sheet).then((files) => extractData(files));\n};\n\nfunction times(n, action) {\n let i = 0;\n while (i < n) {\n action();\n i++;\n }\n}\n"]} \ No newline at end of file +{"version":3,"sources":["../excelParser.js"],"names":["parseXlsx","ns","a","select","useNamespaces","extractFiles","path","sheet","files","strings","stream","createReadStream","Promise","resolve","reject","filePromises","pipe","Parse","on","all","then","entry","file","contents","push","data","toString","autodrain","calculateDimensions","cells","comparator","b","allRows","map","cell","row","sort","allCols","column","minRow","maxRow","length","minCol","maxCol","extractData","values","DOMParser","parseFromString","valuesDoc","string","t","textContent","join","parseError","colToInt","col","letters","trim","split","n","i","indexOf","na","CellCoords","parseInt","Cell","cellNode","r","getAttribute","type","value","coords","node","d","_","cols","rows","times","action"],"mappings":"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","file":"excelParser.js","sourcesContent":["import fs from 'fs';\r\nimport Stream from 'stream';\r\nimport unzip from 'unzipper';\r\nimport xpath from 'xpath';\r\nimport XMLDOM from 'xmldom';\r\n\r\nconst ns = { a: 'http://schemas.openxmlformats.org/spreadsheetml/2006/main' };\r\nconst select = xpath.useNamespaces(ns);\r\n\r\nfunction extractFiles(path, sheet) {\r\n const files = {\r\n strings: {},\r\n sheet: {},\r\n 'xl/sharedStrings.xml': 'strings',\r\n [`xl/worksheets/sheet${sheet}.xml`]: 'sheet'\r\n };\r\n\r\n const stream = path instanceof Stream ? path : fs.createReadStream(path);\r\n\r\n return new Promise((resolve, reject) => {\r\n const filePromises = [];\r\n\r\n stream\r\n .pipe(unzip.Parse())\r\n .on('error', reject)\r\n .on('finish', () => {\r\n Promise.all(filePromises).then(() => resolve(files));\r\n })\r\n .on('entry', (entry) => {\r\n const file = files[entry.path];\r\n if (file) {\r\n let contents = '';\r\n filePromises.push(new Promise((resolve) => {\r\n entry\r\n .on('data', data => contents += data.toString())\r\n .on('end', () => {\r\n files[file].contents = contents;\r\n resolve();\r\n });\r\n }));\r\n } else {\r\n entry.autodrain();\r\n }\r\n });\r\n });\r\n}\r\n\r\nfunction calculateDimensions (cells) {\r\n const comparator = (a, b) => a - b;\r\n const allRows = cells.map(cell => cell.row).sort(comparator);\r\n const allCols = cells.map(cell => cell.column).sort(comparator);\r\n const minRow = allRows[0];\r\n const maxRow = allRows[allRows.length - 1];\r\n const minCol = allCols[0];\r\n const maxCol = allCols[allCols.length - 1];\r\n\r\n return [\r\n { row: minRow, column: minCol },\r\n { row: maxRow, column: maxCol }\r\n ];\r\n}\r\n\r\nfunction extractData(files) {\r\n let sheet;\r\n let values;\r\n const data = [];\r\n\r\n try {\r\n sheet = new XMLDOM.DOMParser().parseFromString(files.sheet.contents);\r\n const valuesDoc = new XMLDOM.DOMParser().parseFromString(files.strings.contents);\r\n values = select('//a:si', valuesDoc)\r\n .map(string => select('.//a:t[not(ancestor::a:rPh)]', string).map(t => t.textContent).join(''));\r\n } catch(parseError){\r\n return [];\r\n }\r\n\r\n function colToInt(col) {\r\n const letters = [\"\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\"];\r\n col = col.trim().split('');\r\n\r\n let n = 0;\r\n\r\n for (let i = 0; i < col.length; i++) {\r\n n *= 26;\r\n n += letters.indexOf(col[i]);\r\n }\r\n\r\n return n;\r\n };\r\n\r\n const na = {\r\n textContent: ''\r\n };\r\n\r\n class CellCoords {\r\n constructor(cell) {\r\n cell = cell.split(/([0-9]+)/);\r\n this.row = parseInt(cell[1]);\r\n this.column = colToInt(cell[0]);\r\n }\r\n }\r\n\r\n class Cell {\r\n constructor(cellNode) {\r\n const r = cellNode.getAttribute('r');\r\n const type = cellNode.getAttribute('t') || '';\r\n const value = (select('a:v', cellNode, 1) || na).textContent;\r\n const coords = new CellCoords(r)\r\n\r\n this.column = coords.column;\r\n this.row = coords.row;\r\n this.value = value;\r\n this.type = type;\r\n }\r\n }\r\n\r\n const cells = select('/a:worksheet/a:sheetData/a:row/a:c', sheet).map(node => new Cell(node));\r\n\r\n let d = select('//a:dimension/@ref', sheet, 1);\r\n if (d) {\r\n d = d.textContent.split(':').map(_ => new CellCoords(_));\r\n } else {\r\n d = calculateDimensions(cells);\r\n }\r\n\r\n const cols = d[1].column - d[0].column + 1;\r\n const rows = d[1].row - d[0].row + 1;\r\n\r\n times(rows, () => {\r\n const row = [];\r\n times(cols, () => row.push(''));\r\n data.push(row);\r\n });\r\n\r\n for (const cell of cells) {\r\n let value = cell.value;\r\n\r\n if (cell.type == 's') {\r\n value = values[parseInt(value)];\r\n }\r\n\r\n if (data[cell.row - d[0].row]) {\r\n data[cell.row - d[0].row][cell.column - d[0].column] = value;\r\n }\r\n }\r\n\r\n return data;\r\n}\r\n\r\nexport default function parseXlsx(path, sheet = '1') {\r\n return extractFiles(path, sheet).then((files) => extractData(files));\r\n};\r\n\r\nfunction times(n, action) {\r\n let i = 0;\r\n while (i < n) {\r\n action();\r\n i++;\r\n }\r\n}\r\n"]} \ No newline at end of file diff --git a/excelParser.js b/excelParser.js index 7f11261..cee096d 100644 --- a/excelParser.js +++ b/excelParser.js @@ -23,13 +23,9 @@ function extractFiles(path, sheet) { stream .pipe(unzip.Parse()) .on('error', reject) - .on('close', () => { + .on('finish', () => { Promise.all(filePromises).then(() => resolve(files)); }) - // For some reason `end` event is not emitted. - // .on('end', () => { - // Promise.all(filePromises).then(() => resolve(files)); - // }) .on('entry', (entry) => { const file = files[entry.path]; if (file) {