Skip to content
This repository has been archived by the owner on Jul 22, 2022. It is now read-only.

issue #58 #59

Merged
merged 1 commit into from
Jan 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 120 additions & 129 deletions lib/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,145 +2,121 @@ var fs = require('fs'),
mime = require('mime'),
imgsz = require('image-size');

var drawing = function (imgURI) {
var d = {
var drawing = function (imgURI, anchor) {
anchor = anchor || module.exports.Image.ONE_CELL;

var xml = {},
key = 'xdr:' + anchor;
xml[key] = {};

var d = {
props: {
image: imgURI,
imageId: 0,
index: 0,
imageId: -1,
mimeType: '',
extension: '',
width: 0,
height: 0,
dpi: 96
},
xml: {
'xdr:oneCellAnchor': [
{
'xdr:from': {
'xdr:col': 0,
'xdr:colOff': 0,
'xdr:row': 0,
'xdr:rowOff': 0
}
},
{
'xdr:ext': {
'@cx': 0 * 9525,
'@cy': 0 * 9525
}
},
{
'xdr:pic': {
'xdr:nvPicPr': [
{
'xdr:cNvPr': {
'@descr': 'image',
'@id': 0,
'@name': 'Picture'
}
},
'xdr:cNvPicPr'
],
'xdr:blipFill': {
'a:blip': {
'@cstate': 'print',
'@r:embed': 'rId0',
'@xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
}
},
'xdr:spPr': [
{
'@bwMode': 'auto'
},
{
'a:xfrm': {
'a:off': {
'@x': 0,
'@y': 0
},
'a:ext': {
'@cx': 0 * 9525,
'@cy': 0 * 9525
}
}
},
{
'a:prstGeom': [
{
'@prst': 'rect'
},
'a:avLst'
]
},
'a:noFill',
{
'a:ln': ['a:noFill']
}
]
}
},
'xdr:clientData'
]
},
xml: xml,

Position: function (r, c, offY, offX) {
Position: function (r, c, offY, offX, to_offY, to_offX) {
var offsetX = offX ? offX : 0;
var offsetY = offY ? offY : 0;

d.xml['xdr:oneCellAnchor'].e4nForEach(function (v) {
if (v['xdr:from']) {
v['xdr:from']['xdr:col'] = c - 1;
v['xdr:from']['xdr:row'] = r - 1;
v['xdr:from']['xdr:colOff'] = offsetX;
v['xdr:from']['xdr:rowOff'] = offsetY;
} else if (v['xdr:pic'] && offX && offY) {
var spPR = v['xdr:pic']['xdr:spPr'];
spPR.e4nForEach(function (o) {
if (o['a:xfrm']) {
o['a:xfrm']['a:off']['@x'] = offsetX;
o['a:xfrm']['a:off']['@y'] = offsetY;
}
});
var xdr;

if (anchor === module.exports.Image.ABSOLUTE) {
xdr = d.xml[key]['xdr:pos'] = {};
xdr['@y'] = r * 9525 * (96 / d.props.dpi); //r - represents Y pixels
xdr['@x'] = c * 9525 * (96 / d.props.dpi); //c - represents X pixels
} else {
xdr = d.xml[key]['xdr:from'] = {};

xdr['xdr:col'] = c - 1;
xdr['xdr:colOff'] = offsetX * 9525 * (96 / d.props.dpi);
xdr['xdr:row'] = r - 1;
xdr['xdr:rowOff'] = offsetY * 9525 * (96 / d.props.dpi);

if (anchor === module.exports.Image.TWO_CELL) {
xdr = d.xml[key]['xdr:to'] = {};
offsetX = to_offY ? to_offY : 0;
offsetY = to_offX ? to_offX : 0;

xdr['xdr:col'] = offX || c; //offX - represents end column index
xdr['xdr:colOff'] = 0;
xdr['xdr:row'] = offY || r; //offY - represents end row index
xdr['xdr:rowOff'] = 0;
}
});
}
return d;
},
Properties: function (props) {
Object.keys(props).e4nForEach(function (k) {
Object.keys(props).forEach(function (k) {
d.props[k] = props[k];
});
return d;
},
SetID: function (id) {
d.xml['xdr:oneCellAnchor'].e4nForEach(function (v) {
if (v['xdr:pic']) {
v['xdr:pic']['xdr:nvPicPr'][0]['xdr:cNvPr']['@id'] = id;
v['xdr:pic']['xdr:blipFill']['a:blip']['@r:embed'] = 'rId' + id;
}
});
d.props.imageId = id;
},
updateSize: function () {
d.xml['xdr:oneCellAnchor'].e4nForEach(function (v) {
if (v['xdr:ext']) {
v['xdr:ext']['@cx'] = d.props.width * 9525 * (96 / d.props.dpi);
v['xdr:ext']['@cy'] = d.props.height * 9525 * (96 / d.props.dpi);
} else if (v['xdr:pic']) {
var spPR = v['xdr:pic']['xdr:spPr'];
spPR.e4nForEach(function (o) {
if (o['a:xfrm']) {
o['a:xfrm']['a:ext']['@cx'] = d.props.width * 9525 * (96 / d.props.dpi);
o['a:xfrm']['a:ext']['@cy'] = d.props.height * 9525 * (96 / d.props.dpi);
ImageProperties: function (index, imageId, name, descr) {
var pic = d.xml[key]['xdr:pic'] = {
'xdr:nvPicPr': {
'xdr:cNvPr': {},
'xdr:cNvPicPr': {
'a:picLocks': {
'@noChangeArrowheads': 1,
'@noChangeAspect': 1
}
}
},
'xdr:blipFill': {
'a:blip': {
'@r:embed': 'rId' + imageId,
'@xmlns:r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
},
'a:srcRect': {},
'a:stretch': {
'a:fillRect': {}
}
});
},
'xdr:spPr': {
'@bwMode': 'auto',
'a:xfrm': {},
'a:prstGeom': {
'@prst': 'rect'
}
}
},
cNvPr = pic['xdr:nvPicPr']['xdr:cNvPr'];
d.xml[key]['xdr:clientData'] = {};

cNvPr['@descr'] = descr || 'image';
cNvPr['@id'] = index;
cNvPr['@name'] = name || 'Picture';

d.props.imageId = imageId;
d.props.index = index;
return d;
},
Size: function (width, height) {
if (anchor !== module.exports.Image.TWO_CELL) {
width = isNaN(parseFloat(width)) ? 100 : width;
height = isNaN(parseFloat(height)) ? 15 : height;
d.xml[key]['xdr:ext'] = {
'@cx': width * 9525 * (96 / d.props.dpi),
'@cy': height * 9525 * (96 / d.props.dpi)
}
});
}
d.props.width = width;
d.props.height = height;
return d;
}

};

return d;
};

module.exports.Image = function (imgURI) {
module.exports.Image = function (imgURI, anchor) {

var wb = this.wb.workbook;
var wSs = this.wb.worksheets;
Expand All @@ -151,7 +127,7 @@ module.exports.Image = function (imgURI) {
var extension = mimeType.split('/')[1];

var contentTypeAdded = false;
wb.Content_Types.Types.e4nForEach(function (t) {
wb.Content_Types.Types.forEach(function (t) {
if (t['Default']) {
if (t['Default']['@ContentType'] === mimeType) {
contentTypeAdded = true;
Expand Down Expand Up @@ -199,7 +175,7 @@ module.exports.Image = function (imgURI) {
};
}

var d = new drawing(imgURI);
var d = new drawing(imgURI, anchor);


d.Properties({
Expand All @@ -208,31 +184,42 @@ module.exports.Image = function (imgURI) {
});

var dim = imgsz(imgURI);
d.Properties({
d.Position(1, 1);
d.Size({
'width': dim.width,
'height': dim.height
});
d.updateSize();

ws.drawings.drawings.push(d);
var imgID = 0;
wSs.e4nForEach(function (s) {
var fontInWS = null;
wSs.forEach(function (s) {
if (s.drawings) {
imgID += s.drawings.drawings.length;
for (var i in s.drawings.drawings) {
var d = s.drawings.drawings[i];
if (d.props && d.props.imageId !== -1 && d.props.image === imgURI) {
imgID = d.props.imageId;
fontInWS = s;
}
}
}
return fontInWS === null;
});
d.SetID(imgID);
ws.drawings.drawings.push(d);
d.ImageProperties(ws.drawings.drawings.length, imgID);

ws.drawings.rels.Relationships.push({
'Relationship': {
'@Id': 'rId' + imgID,
'@Target': '../media/image' + imgID + '.' + extension,
'@Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'
}
});
if (fontInWS !== ws) {
ws.drawings.rels.Relationships.push({
'Relationship': {
'@Id': 'rId' + imgID,
'@Target': '../media/image' + imgID + '.' + extension,
'@Type': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image'
}
});
}

var relExists = false;
ws.rels['Relationships'].e4nForEach(function (r) {
ws.rels['Relationships'].forEach(function (r) {
if (r['Relationship']) {
if (r['Relationship']['@Id'] === 'rId1') {
relExists = true;
Expand All @@ -254,3 +241,7 @@ module.exports.Image = function (imgURI) {

return d;
};

module.exports.Image.ONE_CELL = 'oneCellAnchor';
module.exports.Image.TWO_CELL = 'twoCellAnchor';
module.exports.Image.ABSOLUTE = 'absoluteAnchor';
15 changes: 14 additions & 1 deletion sample.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,20 @@ function createWorkBook(){

ws.Row(1).Height(140);
ws.Cell(1,1,2,6,true);
ws.Image('sampleFiles/image1.png').Position(1,1,0,0);

//Absolute position near D3
ws.Image('sampleFiles/image1.png', ws.Image.ABSOLUTE).Position(218, 400).Size(255, 50); //y-pixels, X-pixels

//A3
ws.Image('sampleFiles/image1.png', ws.Image.ONE_CELL).Position(3, 1, 10, 40).Size(255, 50); //row, column, offsetY, offsetX

//A1-F2
ws.Image('sampleFiles/image1.png', ws.Image.TWO_CELL).Position(1, 1, 2, 6, 2, 5); //begin-row, begin-column, end-row, end-column, offsetY, offsetX

//D5
ws.Image('sampleFiles/image1.png', ws.Image.TWO_CELL).Position(5, 4); //row, column (in one cell re-scale in cell)


ws.Row(3).Height(50);
ws.Cell(3,1,3,6,true);
ws.Row(17).Height(60);
Expand Down