From c7c213216c2047517e275d4c513bb7434bf8c805 Mon Sep 17 00:00:00 2001 From: Ocke Janssen Date: Thu, 21 Sep 2017 14:05:10 +0200 Subject: [PATCH 1/7] Impl --- lib/xlsx/xform/drawing/cell-position-xform.js | 2 +- .../xform/drawing/two-cell-anchor-xform.js | 25 ++++++++---- spec/integration/workbook/images.spec.js | 39 +++++++++++++++++++ test/test-image-oneCell.js | 33 ++++++++++++++++ 4 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 test/test-image-oneCell.js diff --git a/lib/xlsx/xform/drawing/cell-position-xform.js b/lib/xlsx/xform/drawing/cell-position-xform.js index e8047ff99..a178a940a 100644 --- a/lib/xlsx/xform/drawing/cell-position-xform.js +++ b/lib/xlsx/xform/drawing/cell-position-xform.js @@ -30,7 +30,7 @@ utils.inherits(CellPositionXform, BaseXform, { this.map['xdr:col'].render(xmlStream, col); this.map['xdr:colOff'].render(xmlStream, colOff); - var row = Math.floor(model.row); + var row = model.editAsOneCell ? 0 : Math.floor(model.row); var rowOff = Math.floor((model.row - row) * 180000); this.map['xdr:row'].render(xmlStream, row); this.map['xdr:rowOff'].render(xmlStream, rowOff); diff --git a/lib/xlsx/xform/drawing/two-cell-anchor-xform.js b/lib/xlsx/xform/drawing/two-cell-anchor-xform.js index d3d959a98..f6caada0e 100644 --- a/lib/xlsx/xform/drawing/two-cell-anchor-xform.js +++ b/lib/xlsx/xform/drawing/two-cell-anchor-xform.js @@ -35,7 +35,7 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { // Note - zero based model.tl = { col: range.left - 1, - row: range.top - 1, + row: range.top - 1 }; // zero based but also +1 to cover to bottom right of br cell model.br = { @@ -49,7 +49,12 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { }, render: function(xmlStream, model) { - xmlStream.openNode(this.tag); + if(model.range.editAs) + xmlStream.openNode(this.tag, {editAs: model.range.editAs}); + else + xmlStream.openNode(this.tag); + model.tl.editAsOneCell = model.range.editAs == 'oneCell'; + model.br.editAsOneCell = model.range.editAs == 'oneCell'; this.map['xdr:from'].render(xmlStream, model.tl); this.map['xdr:to'].render(xmlStream, model.br); @@ -67,6 +72,9 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { switch (node.name) { case this.tag: this.reset(); + this.model = { + editAs: node.attributes['editAs'] + }; break; default: this.parser = this.map[node.name]; @@ -93,11 +101,10 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { } switch (name) { case this.tag: - this.model = { - tl: this.map['xdr:from'].model, - br: this.map['xdr:to'].model, - picture: this.map['xdr:pic'].model, - }; + this.model = this.model || {}; + this.model.tl = this.map['xdr:from'].model; + this.model.br = this.map['xdr:to'].model; + this.model.picture = this.map['xdr:pic'].model; return false; default: // could be some unrecognised tags @@ -121,6 +128,10 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { br: model.br, }; } + if (model.editAs) { + model.range.editAs = model.editAs; + delete model.editAs; + } delete model.tl; delete model.br; } diff --git a/spec/integration/workbook/images.spec.js b/spec/integration/workbook/images.spec.js index eb3c8d248..c6c51c84a 100644 --- a/spec/integration/workbook/images.spec.js +++ b/spec/integration/workbook/images.spec.js @@ -91,5 +91,44 @@ describe('Workbook', function() { expect(Buffer.compare(imageData, image.buffer)).to.equal(0); }); }); + + it('stores embedded image with oneCell', function() { + var wb = new Excel.Workbook(); + var ws = wb.addWorksheet('blort'); + var wb2, ws2; + + var imageId = wb.addImage({ + filename: IMAGE_FILENAME, + extension: 'jpeg', + }); + + ws.addImage(imageId, { + tl: { col: 0.1125, row: 0.4 }, + br: { col: 2.101046875, row: 3.4 }, + editAs: 'oneCell' + }); + + return wb.xlsx.writeFile(TEST_XLSX_FILE_NAME) + .then(function() { + wb2 = new Excel.Workbook(); + return wb2.xlsx.readFile(TEST_XLSX_FILE_NAME); + }) + .then(function() { + ws2 = wb2.getWorksheet('blort'); + expect(ws2).to.not.be.undefined(); + + return fsReadFileAsync(IMAGE_FILENAME); + }) + .then(function(imageData) { + const images = ws2.getImages(); + expect(images.length).to.equal(1); + + const imageDesc = images[0]; + expect(imageDesc.range.editAs).to.equal('oneCell'); + + const image = wb2.getImage(imageDesc.imageId); + expect(Buffer.compare(imageData, image.buffer)).to.equal(0); + }); + }); }); }); diff --git a/test/test-image-oneCell.js b/test/test-image-oneCell.js new file mode 100644 index 000000000..95dc2e01c --- /dev/null +++ b/test/test-image-oneCell.js @@ -0,0 +1,33 @@ +var fs = require('fs'); +var path = require('path'); + +var HrStopwatch = require('./utils/hr-stopwatch'); + +var Workbook = require('../excel').Workbook; + +var filename = process.argv[2]; + +var wb = new Workbook(); +var ws = wb.addWorksheet('blort'); + +var imageId = wb.addImage({ + filename: path.join(__dirname, 'data/image2.png'), + extension: 'png', +}); +ws.addImage(imageId, { + tl: { col: 0.1125, row: 0.4 }, + br: { col: 2.101046875, row: 3.4 }, + editAs: 'oneCell' +}); + +var stopwatch = new HrStopwatch(); +stopwatch.start(); +wb.xlsx.writeFile(filename) + .then(function() { + var micros = stopwatch.microseconds; + console.log('Done.'); + console.log('Time taken:', micros) + }) + .catch(function(error) { + console.error(error.stack); + }); From 818c75b6c85da737ee305f1f265271410b4de80e Mon Sep 17 00:00:00 2001 From: Kay Ramme Date: Thu, 28 Sep 2017 09:55:00 +0200 Subject: [PATCH 2/7] EUDEV-7310 need Jenkins job, should run build before publish - adapted --- package.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index e8916f374..c00fcca61 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "end-to-end-test": "mocha --require spec/config/setup spec/end-to-end --recursive", "clean": "rm -rf build/ && rm -rf dist", "build": "./node_modules/.bin/grunt build", + "prepublish": "./node_modules/.bin/grunt build", "manual-test": "node spec/manual/app.js", "preversion": "npm run clean && npm run build && npm test", "postversion": "git push --no-verify && git push --tags --no-verify" @@ -96,5 +97,15 @@ "dist", "LICENSE", "README.md" - ] + ], + "triple-j": { + "prerequisites": [ + "@digital-coupons/buildnpm.npm" + ], + "config": { + "project": { + "assignedNode": "linux" + } + } + } } From ae5e3d4ece6589434a8bafd63d36e41d56ee60a8 Mon Sep 17 00:00:00 2001 From: Kay Ramme Date: Thu, 28 Sep 2017 10:04:37 +0200 Subject: [PATCH 3/7] EUDEV-7310 better be scoped - adapted --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c00fcca61..1cead1c36 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "exceljs", + "name": "@digital-coupons/exceljs", "version": "0.6.0", "description": "Excel Workbook Manager - Read and Write xlsx and csv Files.", "private": false, From 19204a65025cc90832b0d20e74bd1dc506e98185 Mon Sep 17 00:00:00 2001 From: Kay Ramme Date: Fri, 29 Sep 2017 12:27:32 +0200 Subject: [PATCH 4/7] Revert "EUDEV-7310 better be scoped - adapted" This reverts commit ae5e3d4ece6589434a8bafd63d36e41d56ee60a8. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1cead1c36..c00fcca61 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "@digital-coupons/exceljs", + "name": "exceljs", "version": "0.6.0", "description": "Excel Workbook Manager - Read and Write xlsx and csv Files.", "private": false, From dffc1ccca8b21e603307698f1481083c535992e9 Mon Sep 17 00:00:00 2001 From: Kay Ramme Date: Fri, 29 Sep 2017 12:28:00 +0200 Subject: [PATCH 5/7] Revert "EUDEV-7310 need Jenkins job, should run build before publish - adapted" This reverts commit 818c75b6c85da737ee305f1f265271410b4de80e. --- package.json | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/package.json b/package.json index c00fcca61..e8916f374 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "end-to-end-test": "mocha --require spec/config/setup spec/end-to-end --recursive", "clean": "rm -rf build/ && rm -rf dist", "build": "./node_modules/.bin/grunt build", - "prepublish": "./node_modules/.bin/grunt build", "manual-test": "node spec/manual/app.js", "preversion": "npm run clean && npm run build && npm test", "postversion": "git push --no-verify && git push --tags --no-verify" @@ -97,15 +96,5 @@ "dist", "LICENSE", "README.md" - ], - "triple-j": { - "prerequisites": [ - "@digital-coupons/buildnpm.npm" - ], - "config": { - "project": { - "assignedNode": "linux" - } - } - } + ] } From 6192fcbb32065a56cb0e5b4b4afac8805d5c4629 Mon Sep 17 00:00:00 2001 From: Ocke Janssen Date: Thu, 12 Oct 2017 12:50:56 +0200 Subject: [PATCH 6/7] add missing braces - fixed --- lib/xlsx/xform/drawing/two-cell-anchor-xform.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/xlsx/xform/drawing/two-cell-anchor-xform.js b/lib/xlsx/xform/drawing/two-cell-anchor-xform.js index f6caada0e..8d7b0ae12 100644 --- a/lib/xlsx/xform/drawing/two-cell-anchor-xform.js +++ b/lib/xlsx/xform/drawing/two-cell-anchor-xform.js @@ -49,12 +49,13 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { }, render: function(xmlStream, model) { - if(model.range.editAs) + if (model.range.editAs) { xmlStream.openNode(this.tag, {editAs: model.range.editAs}); - else + } else { xmlStream.openNode(this.tag); - model.tl.editAsOneCell = model.range.editAs == 'oneCell'; - model.br.editAsOneCell = model.range.editAs == 'oneCell'; + } + model.tl.editAsOneCell = model.range.editAs === 'oneCell'; + model.br.editAsOneCell = model.range.editAs === 'oneCell'; this.map['xdr:from'].render(xmlStream, model.tl); this.map['xdr:to'].render(xmlStream, model.br); @@ -73,7 +74,7 @@ utils.inherits(TwoCellAnchorXform, BaseXform, { case this.tag: this.reset(); this.model = { - editAs: node.attributes['editAs'] + editAs: node.attributes.editAs }; break; default: From 7b43c68593278743be51e20009085a7538256cbb Mon Sep 17 00:00:00 2001 From: Ocke Janssen Date: Thu, 12 Oct 2017 12:56:21 +0200 Subject: [PATCH 7/7] add missing doc - fixed --- README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 8ee893f58..56a8b92b3 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ npm install exceljs Contributions are very welcome! It helps me know what features are desired or what bugs are causing the most pain. I have just one request; If you submit a pull request for a bugfix, please add a unit-test or integration-test (in the spec folder) that catches the problem. - Even a PR that just has a failing test is fine - I can analyse what the test is doing and fix the code from that. + Even a PR that just has a failing test is fine - I can analyse what the test is doing and fix the code from that. To be clear, all contributions added to this library will be included in the library's MIT licence. @@ -168,7 +168,7 @@ The Workbook views controls how many separate windows Excel will open when viewi ```javascript workbook.views = [ { - x: 0, y: 0, width: 10000, height: 20000, + x: 0, y: 0, width: 10000, height: 20000, firstSheet: 0, activeTab: 1, visibility: 'visible' } ] @@ -265,8 +265,8 @@ var worksheetWriter = workbookWriter.addSheet('sheet', { // adjust pageSetup settings afterwards worksheet.pageSetup.margins = { - left: 0.7, right: 0.7, - top: 0.75, bottom: 0.75, + left: 0.7, right: 0.7, + top: 0.75, bottom: 0.75, header: 0.3, footer: 0.3 }; @@ -306,9 +306,9 @@ worksheet.pageSetup.printTitlesRow = '1:3'; | Name | Value | | ----------------------------- | --------- | -| Letter | undefined | +| Letter | undefined | | Legal | 5 | -| Executive | 7 | +| Executive | 7 | | A4 | 9 | | A5 | 11 | | B5 (JIS) | 13 | @@ -473,9 +473,9 @@ dobCol.eachCell({ includeEmpty: true }, function(cell, rowNumber) { worksheet.spliceColumns(3,2); // remove one column and insert two more. -// Note: columns 4 and above will be shifted right by 1 column. -// Also: If the worksheet has more rows than values in the colulmn inserts, -// the rows will still be shifted as if the values existed +// Note: columns 4 and above will be shifted right by 1 column. +// Also: If the worksheet has more rows than values in the colulmn inserts, +// the rows will still be shifted as if the values existed var newCol3Values = [1,2,3,4,5]; var newCol4Values = ['one', 'two', 'three', 'four', 'five']; worksheet.spliceColumns(3, 1, newCol3Values, newCol4Values); @@ -586,7 +586,7 @@ row.eachCell({ includeEmpty: true }, function(cell, colNumber) { worksheet.spliceRows(4,3); // remove one row and insert two more. -// Note: rows 4 and below will be shifted down by 1 row. +// Note: rows 4 and below will be shifted down by 1 row. var newRow3Values = [1,2,3,4,5]; var newRow4Values = ['one', 'two', 'three', 'four', 'five']; worksheet.spliceRows(3, 1, newRow3Values, newRow4Values); @@ -1084,6 +1084,7 @@ expect(worksheet.getColumn(3).collapsed).to.be.false; Adding images to a worksheet is a two-step process. First, the image is added to the workbook via the addImage() function which will also return an imageId value. Then, using the imageId, the image can be added to the worksheet either as a tiled background or covering a cell range. +The cell range can also have the property editAs with the value 'oneCell' which allows to set the anchor to cell. Note: As of this version, adjusting or transforming the image is not supported. @@ -1240,7 +1241,7 @@ The CSV parser uses [fast-csv](https://www.npmjs.com/package/fast-csv) to read t Dates are parsed using the npm module [moment](https://www.npmjs.com/package/moment). If no dateFormats are supplied, the following are used: - + * moment.ISO_8601 * 'MM-DD-YYYY' * 'YYYY-MM-DD' @@ -1531,7 +1532,7 @@ A shared formula can be assigned to a cell using a new value form: worksheet.getCell('B3').value = { sharedFormula: 'A3', result: 10 }; ``` -This specifies that the cell B3 is a formula that will be derived from the formula in +This specifies that the cell B3 is a formula that will be derived from the formula in A3 and its result is 10. The formula convenience getter will translate the formula in A3 to what it should be in B3: @@ -1643,7 +1644,7 @@ To mitigate this the following two changes were added to 0.3.0: ExcelJS now supports dependency injection for the promise library. You can restore Bluebird promises by including the following code in your module... - + ```javascript ExcelJS.config.setValue('promise', require('bluebird')); ```