From 1408dd417f5cd59e20209fad84c16e33d975f8f6 Mon Sep 17 00:00:00 2001 From: Christian Holm Date: Mon, 5 Dec 2016 10:00:34 +0100 Subject: [PATCH 1/4] Read and write the date1904 property --- .../xform/book/workbook-properties-xform.js | 58 +++++++++++++++++++ lib/xlsx/xform/book/workbook-xform.js | 11 ++-- lib/xlsx/xlsx.js | 1 + spec/unit/xlsx/xform/book/data/book.1.1.json | 5 +- spec/unit/xlsx/xform/book/data/book.1.2.xml | 2 +- spec/unit/xlsx/xform/book/data/book.1.3.json | 5 +- .../book/workbook-properties-xform.spec.js | 27 +++++++++ 7 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 lib/xlsx/xform/book/workbook-properties-xform.js create mode 100644 spec/unit/xlsx/xform/book/workbook-properties-xform.spec.js diff --git a/lib/xlsx/xform/book/workbook-properties-xform.js b/lib/xlsx/xform/book/workbook-properties-xform.js new file mode 100644 index 000000000..5deea9a62 --- /dev/null +++ b/lib/xlsx/xform/book/workbook-properties-xform.js @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2016 Guyon Roche + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ +'use strict'; + +var utils = require('../../../utils/utils'); +var BaseXform = require('../base-xform'); + +var WorksheetPropertiesXform = module.exports = function() { +}; + +utils.inherits(WorksheetPropertiesXform, BaseXform, { + + render: function(xmlStream, model) { + xmlStream.leafNode('workbookPr', { + date1904: model.date1904, + defaultThemeVersion: 164011, + filterPrivacy: 1 + }); + }, + + parseOpen: function(node) { + if (node.name === 'workbookPr') { + this.model = {}; + + if (node.attributes.date1904 !== undefined) { + this.model.date1904 = parseInt(node.attributes.date1904); + }; + return true; + } else { + return false; + } + }, + parseText: function() { + }, + parseClose: function() { + return false; + } +}); diff --git a/lib/xlsx/xform/book/workbook-xform.js b/lib/xlsx/xform/book/workbook-xform.js index a7d8416b4..61afa0ce5 100644 --- a/lib/xlsx/xform/book/workbook-xform.js +++ b/lib/xlsx/xform/book/workbook-xform.js @@ -34,11 +34,12 @@ var ListXform = require('../list-xform'); var DefinedNameXform = require('./defined-name-xform'); var SheetXform = require('./sheet-xform'); var WorkbookViewXform = require('./workbook-view-xform'); +var WorkbookPropertiesXform = require('./workbook-properties-xform'); var WorkbookXform = module.exports = function() { this.map = { fileVersion: WorkbookXform.STATIC_XFORMS.fileVersion, - workbookPr: WorkbookXform.STATIC_XFORMS.workbookPr, + workbookPr: new WorkbookPropertiesXform(), bookViews: new ListXform({tag: 'bookViews', count: false, childXform: new WorkbookViewXform()}), sheets: new ListXform({tag: 'sheets', count: false, childXform: new SheetXform()}), definedNames: new ListXform({tag: 'definedNames', count: false, childXform: new DefinedNameXform()}), @@ -56,7 +57,6 @@ utils.inherits(WorkbookXform, BaseXform, { }, STATIC_XFORMS: { fileVersion: new StaticXform({tag: 'fileVersion', $: {appName: 'xl', lastEdited: 5, lowestEdited: 5, rupBuild: 9303}}), - workbookPr: new StaticXform({tag: 'workbookPr', $: {defaultThemeVersion: 164011, filterPrivacy: 1}}), calcPr: new StaticXform({tag: 'calcPr', $: {calcId: 171027}}) } },{ @@ -88,7 +88,7 @@ utils.inherits(WorkbookXform, BaseXform, { xmlStream.openNode('workbook', WorkbookXform.WORKBOOK_ATTRIBUTES); this.map.fileVersion.render(xmlStream); - this.map.workbookPr.render(xmlStream); + this.map.workbookPr.render(xmlStream, model.properties); this.map.bookViews.render(xmlStream, model.views); this.map.sheets.render(xmlStream, model.sheets); this.map.definedNames.render(xmlStream, model.definedNames); @@ -129,12 +129,13 @@ utils.inherits(WorkbookXform, BaseXform, { switch(name) { case 'workbook': this.model = { - sheets: this.map.sheets.model + sheets: this.map.sheets.model, + properties: this.map.workbookPr.model, + views: this.map.bookViews.model }; if (this.map.definedNames.model) { this.model.definedNames = this.map.definedNames.model; } - this.model.views = this.map.bookViews.model; return false; default: diff --git a/lib/xlsx/xlsx.js b/lib/xlsx/xlsx.js index f3822cee6..e620c5658 100644 --- a/lib/xlsx/xlsx.js +++ b/lib/xlsx/xlsx.js @@ -140,6 +140,7 @@ XLSX.prototype = { model.sheets = workbook.sheets; model.definedNames = workbook.definedNames; model.views = workbook.views; + model.properties = workbook.properties; }); break; case 'xl/_rels/workbook.xml.rels': diff --git a/spec/unit/xlsx/xform/book/data/book.1.1.json b/spec/unit/xlsx/xform/book/data/book.1.1.json index 76136c236..853f7de04 100644 --- a/spec/unit/xlsx/xform/book/data/book.1.1.json +++ b/spec/unit/xlsx/xform/book/data/book.1.1.json @@ -4,5 +4,8 @@ ], "sheets": [ {"name": "Values", "id": 1, "rId": "rId1"} - ] + ], + "properties": { + "date1904": 1 + } } \ No newline at end of file diff --git a/spec/unit/xlsx/xform/book/data/book.1.2.xml b/spec/unit/xlsx/xform/book/data/book.1.2.xml index 07ae8eaf8..9911a6403 100644 --- a/spec/unit/xlsx/xform/book/data/book.1.2.xml +++ b/spec/unit/xlsx/xform/book/data/book.1.2.xml @@ -1,7 +1,7 @@ - + diff --git a/spec/unit/xlsx/xform/book/data/book.1.3.json b/spec/unit/xlsx/xform/book/data/book.1.3.json index 22d6b84e7..7f5af31ec 100644 --- a/spec/unit/xlsx/xform/book/data/book.1.3.json +++ b/spec/unit/xlsx/xform/book/data/book.1.3.json @@ -4,5 +4,8 @@ ], "sheets": [ {"name": "Values", "id": 1, "rId": "rId1"} - ] + ], + "properties": { + "date1904": 1 + } } \ No newline at end of file diff --git a/spec/unit/xlsx/xform/book/workbook-properties-xform.spec.js b/spec/unit/xlsx/xform/book/workbook-properties-xform.spec.js new file mode 100644 index 000000000..a2c03f2c7 --- /dev/null +++ b/spec/unit/xlsx/xform/book/workbook-properties-xform.spec.js @@ -0,0 +1,27 @@ +'use strict'; + +var WorkbookPropertiesXform = require('../../../../../lib/xlsx/xform/book/workbook-properties-xform'); +var testXformHelper = require('./../test-xform-helper'); + +var expectations = [ + { + title: 'default', + create: function() { return new WorkbookPropertiesXform(); }, + preparedModel: {}, + xml: '', + parsedModel: {}, + tests: ['render', 'renderIn'] + }, + { + title: 'date1904', + create: function() { return new WorkbookPropertiesXform(); }, + preparedModel: { date1904: 1}, + xml: '', + parsedModel: { date1904: 1}, + tests: ['render', 'renderIn', 'parse'] + } +]; + +describe('WorkbookPropertiesXform', function() { + testXformHelper(expectations); +}); \ No newline at end of file From 6a6942d0492f3617e6258be5868ff238637e72c8 Mon Sep 17 00:00:00 2001 From: Christian Holm Date: Mon, 5 Dec 2016 10:09:34 +0100 Subject: [PATCH 2/4] Pass properties in and out --- lib/doc/workbook.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/doc/workbook.js b/lib/doc/workbook.js index 4f566c4b5..4884c6237 100644 --- a/lib/doc/workbook.js +++ b/lib/doc/workbook.js @@ -140,6 +140,7 @@ Workbook.prototype = { lastPrinted: this.lastPrinted, created: this.created, modified: this.modified, + properties: this.properties, worksheets: this._worksheets.filter(Boolean).map(function(worksheet) { return worksheet.model; }), definedNames: this._definedNames.model, views: this.views, @@ -151,7 +152,7 @@ Workbook.prototype = { category: this.category, description: this.description, language: this.language, - revision: this.revision + revision: this.revision, }; }, set model(value) { @@ -173,6 +174,7 @@ Workbook.prototype = { this.language = value.language; this.revision = value.revision; + this.properties = value.properties; this._worksheets = []; value.worksheets.forEach(function(worksheetModel) { var id = worksheetModel.id; From 00a065a06a5bda61cbdaacb6388986b1ed0bc2ff Mon Sep 17 00:00:00 2001 From: Christian Holm Date: Mon, 5 Dec 2016 10:32:29 +0100 Subject: [PATCH 3/4] Initialize workbook properties --- lib/doc/workbook.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/doc/workbook.js b/lib/doc/workbook.js index 4884c6237..69817e262 100644 --- a/lib/doc/workbook.js +++ b/lib/doc/workbook.js @@ -37,6 +37,7 @@ var CSV = require('./../csv/csv'); var Workbook = module.exports = function() { this.created = new Date(); this.modified = this.created; + this.properties = {}; this._worksheets = []; this.views = []; this._definedNames = new DefinedNames(); From 804e3532098d473e186877379c7cd2fa7a247365 Mon Sep 17 00:00:00 2001 From: Christian Holm Date: Mon, 5 Dec 2016 10:43:45 +0100 Subject: [PATCH 4/4] Default properties on write also --- lib/stream/xlsx/workbook-writer.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/stream/xlsx/workbook-writer.js b/lib/stream/xlsx/workbook-writer.js index f03a43065..8bf494b05 100644 --- a/lib/stream/xlsx/workbook-writer.js +++ b/lib/stream/xlsx/workbook-writer.js @@ -302,7 +302,8 @@ WorkbookWriter.prototype = { var model = { worksheets: this._worksheets.filter(Boolean), definedNames: this._definedNames.model, - views: this.views + views: this.views, + properties: {} }; return new Bluebird(function(resolve) {