Skip to content

Commit

Permalink
Background images working
Browse files Browse the repository at this point in the history
  • Loading branch information
guyonroche committed Nov 23, 2016
1 parent 0b93c4b commit 008e292
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 125 deletions.
2 changes: 2 additions & 0 deletions TODO.txt
@@ -1,6 +1,8 @@

TODO:

On the way to the impossible we might find something eminently doable

Page Setup

Themes:
Expand Down
Expand Up @@ -23,17 +23,30 @@
'use strict';

var utils = require('../../utils/utils');
var RelType = require('../../xlsx/rel-type');

var HyperlinkWriter = module.exports = function(options) {
var HyperlinksProxy = function(sheetRelsWriter) {
this.writer = sheetRelsWriter;
};
HyperlinksProxy.prototype = {
push: function(hyperlink) {
this.writer.addHyperlink(hyperlink);
}
};

var SheetRelsWriter = module.exports = function(options) {
// in a workbook, each sheet will have a number
this.id = options.id;

// count of all relationships
this.count = 0;

// keep record of all hyperlinks
this._hyperlinks = [];

this._workbook = options.workbook;
};
HyperlinkWriter.prototype = {
SheetRelsWriter.prototype = {

get stream() {
if (!this._stream) {
Expand All @@ -50,24 +63,32 @@ HyperlinkWriter.prototype = {
return this._hyperlinks.forEach(fn);
},

push: function(hyperlink) {
// if first hyperlink, must open stream and write xml intro
if (!this._hyperlinks.length) {
this._writeOpen();
}
get hyperlinksProxy() {
return this._hyperlinksProxy ||
(this._hyperlinksProxy = new HyperlinksProxy(this));
},
addHyperlink: function(hyperlink) {
// Write to stream
var relationship = {
Target: hyperlink.target,
Type: RelType.Hyperlink,
TargetMode: 'External'
};
var rId = this._writeRelationship(relationship);

// store sheet stuff for later
this._hyperlinks.push({
address: hyperlink.address,
rId: hyperlink.rId
rId: rId,
address: hyperlink.address
});
},

// and write to stream
this._writeRelationship(hyperlink);
addMedia: function(media) {
return this._writeRelationship(media);
},

commit: function() {
if (this._hyperlinks.length) {
if (this.count) {
// write xml utro
this._writeClose();
// and close stream
Expand All @@ -81,14 +102,32 @@ HyperlinkWriter.prototype = {
'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">');
},
_writeRelationship: function(hyperlink) {
this.stream.write(
'<Relationship' +
' Id="' + hyperlink.rId + '"' +
' Type="' + hyperlink.type + '"' +
' Target="' + hyperlink.target + '"' +
' TargetMode="' + hyperlink.targetMode + '"' +
'/>');
_writeRelationship: function(relationship) {
if (!this.count) {
this._writeOpen();
}

var rId = 'rId' + ++this.count;

if (relationship.TargetMode) {
this.stream.write(
'<Relationship' +
' Id="' + rId + '"' +
' Type="' + relationship.Type + '"' +
' Target="' + relationship.Target + '"' +
' TargetMode="' + relationship.TargetMode + '"'+
'/>');
} else {
this.stream.write(
'<Relationship' +
' Id="' + rId + '"' +
' Type="' + relationship.Type + '"' +
' Target="' + relationship.Target + '"' +
'/>');
}


return rId;
},
_writeClose: function() {
this.stream.write('</Relationships>');
Expand Down
10 changes: 5 additions & 5 deletions lib/stream/xlsx/workbook-writer.js
Expand Up @@ -216,7 +216,7 @@ WorkbookWriter.prototype = {
return new Bluebird(function(resolve) {
var xform = new RelationshipsXform();
var xml = xform.toXml([
{rId: 'rId1', type: RelType.OfficeDocument, target: 'xl/workbook.xml'}
{Id: 'rId1', Type: RelType.OfficeDocument, Target: 'xl/workbook.xml'}
]);
self.zip.append(xml, {name: '/_rels/.rels'});
resolve();
Expand Down Expand Up @@ -273,19 +273,19 @@ WorkbookWriter.prototype = {
var self = this;
var count = 1;
var relationships = [
{rId: 'rId' + (count++), type: RelType.Styles, target: 'styles.xml'},
{rId: 'rId' + (count++), type: RelType.Theme, target: 'theme/theme1.xml'}
{Id: 'rId' + (count++), Type: RelType.Styles, Target: 'styles.xml'},
{Id: 'rId' + (count++), Type: RelType.Theme, Target: 'theme/theme1.xml'}
];
if (this.streamedValues.count) {
relationships.push(
{rId: 'rId' + (count++), type: RelType.SharedStrings, target: 'sharedStrings.xml'}
{Id: 'rId' + (count++), Type: RelType.SharedStrings, Target: 'sharedStrings.xml'}
);
}
this._worksheets.forEach(function (worksheet) {
if (worksheet) {
worksheet.rId = 'rId' + (count++);
relationships.push(
{rId: worksheet.rId, type: RelType.Worksheet, target: 'worksheets/sheet' + worksheet.id + '.xml'}
{Id: worksheet.rId, Type: RelType.Worksheet, Target: 'worksheets/sheet' + worksheet.id + '.xml'}
);
}
});
Expand Down
35 changes: 28 additions & 7 deletions lib/stream/xlsx/worksheet-writer.js
Expand Up @@ -26,6 +26,8 @@ var fs = require('fs');
var _ = require('lodash');

var utils = require('../../utils/utils');
var RelType = require('../../xlsx/rel-type');

var colCache = require('../../utils/col-cache');
var Dimensions = require('../../doc/range');

Expand All @@ -34,7 +36,7 @@ var StringBuf = require('../../utils/string-buf');
var Row = require('../../doc/row');
var Column = require('../../doc/column');

var HyperlinkWriter = require('./hyperlink-writer');
var SheetRelsWriter = require('./sheet-rels-writer');
var DataValidations = require('../../doc/data-validations');

var xml = new StringBuf();
Expand All @@ -51,6 +53,7 @@ var HyperlinkXform = require('../../xlsx/xform/sheet/hyperlink-xform');
var SheetViewXform = require('../../xlsx/xform/sheet/sheet-view-xform');
var PageMarginsXform = require('../../xlsx/xform/sheet/page-margins-xform');
var PageSetupXform = require('../../xlsx/xform/sheet/page-setup-xform');
var PictureXform = require('../../xlsx/xform/sheet/picture-xform');

// since prepare and render is functional, we can use singletons
var xform = {
Expand All @@ -62,7 +65,8 @@ var xform = {
hyperlinks: new ListXform({tag: 'hyperlinks', length: false, childXform: new HyperlinkXform()}),
sheetViews: new ListXform({tag: 'sheetViews', length: false, childXform: new SheetViewXform()}),
pageMargins: new PageMarginsXform(),
pageSeteup: new PageSetupXform()
pageSeteup: new PageSetupXform(),
picture: new PictureXform()
};


Expand Down Expand Up @@ -90,7 +94,7 @@ var WorksheetWriter = module.exports = function(options) {
this._merges.add = function(){}; // ignore cell instruction

// keep record of all hyperlinks
this._hyperlinkWriter = new HyperlinkWriter(options);
this._sheetRelsWriter = new SheetRelsWriter(options);

// keep a record of dimensions
this._dimensions = new Dimensions();
Expand Down Expand Up @@ -147,6 +151,18 @@ var WorksheetWriter = module.exports = function(options) {
// start writing to stream now
this._writeOpenWorksheet();

// background
if (options.background && options.background.type === 'image') {
var imageName = this._workbook.addMedia(options.background);
var pictureId = this._sheetRelsWriter.addMedia({
Target: '../media/' + imageName,
Type: RelType.Image
});
this._background = {
rId: pictureId
};
}

this.startedData = false;
};

Expand Down Expand Up @@ -197,13 +213,14 @@ WorksheetWriter.prototype = {
this._writeDataValidations();
this._writePageMargins();
this._writePageSetup();
this._writeBackground();
this._writeCloseWorksheet();

// signal end of stream to workbook
this.stream.end();

// also commit the hyperlinks if any
this._hyperlinkWriter.commit();
this._sheetRelsWriter.commit();

this.committed = true;
},
Expand Down Expand Up @@ -452,7 +469,7 @@ WorksheetWriter.prototype = {
var options = {
styles: this._workbook.styles,
sharedStrings: self.useSharedStrings ? self._workbook.sharedStrings : undefined,
hyperlinks: this._hyperlinkWriter,
hyperlinks: this._sheetRelsWriter.hyperlinksProxy,
merges: this._merges
};
xform.row.prepare(model, options);
Expand All @@ -474,11 +491,10 @@ WorksheetWriter.prototype = {
xml.addText('</mergeCells>');

this.stream.write(xml);
//stringBufStack.push(xml);
}
},
_writeHyperlinks: function() {
this.stream.write(xform.hyperlinks.toXml(this._hyperlinkWriter._hyperlinks));
this.stream.write(xform.hyperlinks.toXml(this._sheetRelsWriter._hyperlinks));
},
_writeDataValidations: function() {
this.stream.write(xform.dataValidations.toXml(this.dataValidations.model));
Expand All @@ -489,6 +505,11 @@ WorksheetWriter.prototype = {
_writePageSetup: function() {
this.stream.write(xform.pageSeteup.toXml(this.pageSetup));
},
_writeBackground: function() {
if (this._background) {
this.stream.write(xform.picture.toXml(this._background));
}
},
_writeDimensions: function() {
this._write('<dimension ref="' + this._dimensions + '"/>');
},
Expand Down
2 changes: 1 addition & 1 deletion lib/xlsx/xform/core/content-types-xform.js
Expand Up @@ -57,7 +57,7 @@ utils.inherits(ContentTypesXform, BaseXform, {
xmlStream.openNode('Types', ContentTypesXform.TYPES_PROPERTY_ATTRIBUTES);

var mediaHash = {};
model.media.forEach(function(medium) {
(model.media || []).forEach(function(medium) {
if (medium.type === 'image') {
var imageType = medium.image.type;
if (!mediaHash[imageType]) {
Expand Down
4 changes: 2 additions & 2 deletions lib/xlsx/xform/sheet/worksheet-xform.js
Expand Up @@ -95,7 +95,7 @@ utils.inherits(WorkSheetXform, BaseXform, {
Id: rId,
Type: RelType.Hyperlink,
Target: hyperlink.target,
TargetType: 'External'
TargetMode: 'External'
});
});

Expand Down Expand Up @@ -223,7 +223,7 @@ utils.inherits(WorkSheetXform, BaseXform, {
return h;
}, {});
options.hyperlinkMap = (model.hyperlinks || []).reduce(function(h, hyperlink) {
h[hyperlink.address] = rels[hyperlink.Id];
h[hyperlink.address] = rels[hyperlink.rId].Target;
return h;
}, {});

Expand Down

0 comments on commit 008e292

Please sign in to comment.