From fb9a357e1652b4d7d619f48f2315c863ff60152f Mon Sep 17 00:00:00 2001 From: Piotr Zawadzki Date: Fri, 1 Nov 2019 23:26:34 +0100 Subject: [PATCH 1/3] Improve performance of writeFile by reducing number of styles coversion (use weekMap) --- lib/xlsx/xform/style/styles-xform.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/xlsx/xform/style/styles-xform.js b/lib/xlsx/xform/style/styles-xform.js index e8b7235d7..97db808fe 100644 --- a/lib/xlsx/xform/style/styles-xform.js +++ b/lib/xlsx/xform/style/styles-xform.js @@ -82,6 +82,8 @@ class StylesXform extends BaseXform { // add default fills this._addFill({type: 'pattern', pattern: 'none'}); this._addFill({type: 'pattern', pattern: 'gray125'}); + + this.weakMap = new Map() } render(xmlStream, model) { From 1abe9bbcad7f2c8334db5cde1bedeff6cd00c60c Mon Sep 17 00:00:00 2001 From: Piotr Zawadzki Date: Sat, 2 Nov 2019 16:26:01 +0100 Subject: [PATCH 2/3] Optimize generated excel with data validation - reduce number of entries (it makes excel opens generated file much faster) --- .../xform/sheet/data-validations-xform.js | 54 +++++++++++++++++-- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/lib/xlsx/xform/sheet/data-validations-xform.js b/lib/xlsx/xform/sheet/data-validations-xform.js index 1495165d3..b4a4b50dc 100644 --- a/lib/xlsx/xform/sheet/data-validations-xform.js +++ b/lib/xlsx/xform/sheet/data-validations-xform.js @@ -28,17 +28,65 @@ function assignBool(definedName, attributes, name, defaultValue) { } } +function mergeDataValidations(model) { + const valueAddressesMap = new Map(); + _.each(model, (value, address) => { + const key = JSON.stringify(value); + let mapPerColumn = valueAddressesMap.get(key); + if (!mapPerColumn) { + mapPerColumn = new Map(); + valueAddressesMap.set(key, mapPerColumn); + } + + const columnNo = address.match(/[A-Z]+/)[0]; + const rowNo = parseInt(address.match(/\d+/)[0], 10); + + let rowArray = mapPerColumn.get(columnNo); + if (!rowArray) { + rowArray = []; + mapPerColumn.set(columnNo, rowArray); + } + rowArray.push(rowNo); + }); + + const mergedResults = {}; + valueAddressesMap.forEach((columnsMap, formulaeValue) => { + columnsMap.forEach((rows, columnNo) => { + const sortedRowNumbers = rows.sort((a, b) => a - b); + const arrayOfRanges = []; + sortedRowNumbers.forEach(rowNum => { + const previousNumber = arrayOfRanges.length > 0 ? arrayOfRanges[arrayOfRanges.length - 1].max : null; + if (previousNumber && previousNumber === rowNum - 1) { + arrayOfRanges[arrayOfRanges.length - 1].max = rowNum; + } else { + arrayOfRanges.push({min: rowNum, max: rowNum}); + } + }); + arrayOfRanges.forEach(range => { + if (range.min === range.max) { + mergedResults[`${columnNo}${range.min}`] = JSON.parse(formulaeValue); + } else { + mergedResults[`${columnNo}${range.min}:${columnNo}${range.max}`] = JSON.parse(formulaeValue); + } + }); + }); + }); + + return mergedResults; +} + class DataValidationsXform extends BaseXform { get tag() { return 'dataValidations'; } render(xmlStream, model) { - const count = model && Object.keys(model).length; + const optimizedModel = mergeDataValidations(model); + const count = optimizedModel && Object.keys(optimizedModel).length; if (count) { xmlStream.openNode('dataValidations', {count}); - _.each(model, (value, address) => { + _.each(optimizedModel, (value, address) => { xmlStream.openNode('dataValidation'); if (value.type !== 'any') { xmlStream.addAttribute('type', value.type); @@ -75,7 +123,7 @@ class DataValidationsXform extends BaseXform { (value.formulae || []).forEach((formula, index) => { xmlStream.openNode(`formula${index + 1}`); if (value.type === 'date') { - xmlStream.writeText(utils.dateToExcel(formula)); + xmlStream.writeText(utils.dateToExcel(new Date(formula))); } else { xmlStream.writeText(formula); } From 2c3acb726a985a33bc2bc80a3ff20c6cfb8eca8f Mon Sep 17 00:00:00 2001 From: Piotr Zawadzki Date: Tue, 5 Nov 2019 10:24:30 +0100 Subject: [PATCH 3/3] StylesXform - use WeakMap instead Map --- lib/xlsx/xform/style/styles-xform.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/xlsx/xform/style/styles-xform.js b/lib/xlsx/xform/style/styles-xform.js index 97db808fe..1c67edc8f 100644 --- a/lib/xlsx/xform/style/styles-xform.js +++ b/lib/xlsx/xform/style/styles-xform.js @@ -83,7 +83,7 @@ class StylesXform extends BaseXform { this._addFill({type: 'pattern', pattern: 'none'}); this._addFill({type: 'pattern', pattern: 'gray125'}); - this.weakMap = new Map() + this.weakMap = new WeakMap(); } render(xmlStream, model) {