Skip to content

Commit 2629b1b

Browse files
committed
WorksheetWriter.addImage
1 parent 4f3b9e7 commit 2629b1b

File tree

4 files changed

+81
-59
lines changed

4 files changed

+81
-59
lines changed

lib/stream/xlsx/workbook-writer.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const ContentTypesXform = require('../../xlsx/xform/core/content-types-xform');
1414
const AppXform = require('../../xlsx/xform/core/app-xform');
1515
const WorkbookXform = require('../../xlsx/xform/book/workbook-xform');
1616
const SharedStringsXform = require('../../xlsx/xform/strings/shared-strings-xform');
17+
const DrawingXform = require('../../xlsx/xform/drawing/drawing-xform');
1718

1819
const WorksheetWriter = require('./worksheet-writer');
1920

@@ -99,6 +100,7 @@ class WorkbookWriter {
99100
// commit all worksheets, then add suplimentary files
100101
await this.promise;
101102
await this.addMedia();
103+
await this.addDrawings();
102104
await this._commitWorksheets();
103105
await Promise.all([
104106
this.addContentTypes(),
@@ -251,6 +253,25 @@ class WorkbookWriter {
251253
);
252254
}
253255

256+
addDrawings() {
257+
return Promise.all(
258+
this.drawings.map(drawing => {
259+
const drawingXform = new DrawingXform();
260+
const relsXform = new RelationshipsXform();
261+
if (drawing) {
262+
drawingXform.prepare(drawing, {});
263+
let xml = drawingXform.toXml(drawing);
264+
xml = relsXform.toXml(drawing.rels);
265+
return [
266+
this.zip.append(xml, {name: `xl/drawings/${drawing.name}.xml`}),
267+
this.zip.append(xml, {name: `xl/drawings/_rels/${drawing.name}.xml.rels`}),
268+
];
269+
}
270+
return null;
271+
}).flat().filter(Boolean)
272+
);
273+
}
274+
254275
addApp() {
255276
return new Promise(resolve => {
256277
const model = {

lib/stream/xlsx/worksheet-writer.js

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ const PictureXform = require('../../xlsx/xform/sheet/picture-xform');
3434
const ConditionalFormattingsXform = require('../../xlsx/xform/sheet/cf/conditional-formattings-xform');
3535
const HeaderFooterXform = require('../../xlsx/xform/sheet/header-footer-xform');
3636
const RowBreaksXform = require('../../xlsx/xform/sheet/row-breaks-xform');
37-
const ImageXForm = require('../../xlsx/xform/sheet/image-xform');
3837
const DrawingXform = require('../../xlsx/xform/drawing/drawing-xform');
39-
const RelationshipsXform = require('../../xlsx/xform/core/relationships-xform');
4038
const Image = require('../../doc/image');
4139

4240
// since prepare and render are functional, we can use singletons
@@ -53,7 +51,7 @@ const xform = {
5351
pageSeteup: new PageSetupXform(),
5452
autoFilter: new AutoFilterXform(),
5553
picture: new PictureXform(),
56-
drawing: new ImageXForm(),
54+
drawing: new DrawingXform(),
5755
conditionalFormattings: new ConditionalFormattingsXform(),
5856
headerFooter: new HeaderFooterXform(),
5957
rowBreaks: new RowBreaksXform(),
@@ -250,12 +248,13 @@ class WorksheetWriter {
250248
this._writePageMargins();
251249
this._writePageSetup();
252250
this._writeBackground();
251+
this._writeDrawings();
253252
this._writeHeaderFooter();
254253
this._writeRowBreaks();
255254

256255
// Legacy Data tag for comments
257256
this._writeLegacyData();
258-
this._writeDrawings();
257+
259258
this._writeCloseWorksheet();
260259
// signal end of stream to workbook
261260
this.stream.end();
@@ -487,7 +486,9 @@ class WorksheetWriter {
487486
this.anchors.push(im);
488487
}
489488

490-
// =========================================================================
489+
getImages() {
490+
return this._media.filter(m => m.type === 'image');
491+
}
491492

492493
addBackgroundImage(imageId) {
493494
this._background = {
@@ -714,29 +715,33 @@ class WorksheetWriter {
714715
}
715716

716717
_writeDrawings() {
717-
if (this._media.length > 0 ) {
718-
const {zip} = this.workbook;
719-
720-
const drawingXform = new DrawingXform();
721-
const lastDrawingId = this.workbook.drawings.length + 1;
722-
const relsXform = new RelationshipsXform();
723-
const xml = drawingXform.toXml(this);
724-
zip.append(xml, {name: `xl/drawings/drawing${lastDrawingId}.xml`});
725-
const xmlRels = relsXform.toXml(this.anchors.map((a, index) => {
726-
const image = this.workbook.getImage(a.imageId);
727-
return {
728-
Id: `rId${index + 1}`,
729-
Type: RelType.Image,
730-
Target: `../media/${image.name}`,
718+
if (this._media.length) {
719+
this.getImages().forEach((image, i) => {
720+
const lastDrawingId = this.workbook.drawings.length + 1;
721+
const drawingId = this._sheetRelsWriter.addMedia({
722+
Target: `../drawings/drawing${lastDrawingId}.xml`,
723+
Type: RelType.Drawing,
724+
});
725+
const imageObj = this.workbook.getImage(image.imageId);
726+
const drawing = {
727+
rId: drawingId,
728+
name: `drawing${lastDrawingId}`,
729+
rels: [{
730+
Id: 'rId1',
731+
Type: RelType.Image,
732+
Target: `../media/${imageObj.name}`,
733+
}],
734+
anchors: [{
735+
picture: {
736+
rId: image.imageId,
737+
},
738+
range: image.range,
739+
}],
731740
};
732-
}));
733-
this.workbook.drawings.push({name: `drawing${lastDrawingId}`});
734-
zip.append(xmlRels, {name: `xl/drawings/_rels/drawing${lastDrawingId}.xml.rels`});
735-
const drawingId = this._sheetRelsWriter.addMedia({
736-
Target: `../drawings/drawing${lastDrawingId}.xml`,
737-
Type: RelType.Drawing,
741+
this.workbook.drawings.push(drawing);
742+
xform.drawing.prepare(drawing, {});
743+
this.stream.write(xform.drawing.toXml(drawing));
738744
});
739-
this.stream.write(xform.drawing.toXml({rId: drawingId}));
740745
}
741746
}
742747

lib/xlsx/xform/sheet/image-xform.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

spec/integration/worksheet-xlsx-writer.spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const path = require('path');
12
const testutils = require('../utils/index');
23

34
const ExcelJS = verquire('exceljs');
@@ -535,4 +536,32 @@ describe('WorksheetWriter', () => {
535536
expect(ws.rowBreaks.length).to.equal(2);
536537
});
537538
});
539+
540+
describe('Images/Drawings', () => {
541+
it.skip('add images', async () => {
542+
// const wb = new ExcelJS.stream.xlsx.WorkbookWriter();
543+
const filename = path.join(__dirname, 'test.xlsx');
544+
const wb = new ExcelJS.stream.xlsx.WorkbookWriter({filename, useStyles: true, useSharedStrings: true});
545+
const ws1 = wb.addWorksheet('foo');
546+
const ws2 = wb.addWorksheet('bar');
547+
548+
const imageId1 = wb.addImage({
549+
filename: path.join(__dirname, 'data/image.png'),
550+
extension: 'png',
551+
});
552+
const imageId2 = wb.addImage({
553+
filename: path.join(__dirname, 'data/bubbles.jpg'),
554+
extension: 'jpg',
555+
});
556+
ws1.addImage(imageId1, {
557+
tl: {col: 0.25, row: 0.7},
558+
ext: {width: 160, height: 60},
559+
});
560+
ws2.addImage(imageId2, 'C1:F10');
561+
562+
ws1.commit();
563+
ws2.commit();
564+
await wb.commit();
565+
});
566+
});
538567
});

0 commit comments

Comments
 (0)