diff --git a/.gitignore b/.gitignore index 2810f3742..032779be9 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,9 @@ tmp/* # WebStorm .idea +# VS Code +.vscode + # Intellij IDEA exceljs.iml diff --git a/lib/stream/xlsx/workbook-writer.js b/lib/stream/xlsx/workbook-writer.js index 2cdd7f950..8e412566d 100644 --- a/lib/stream/xlsx/workbook-writer.js +++ b/lib/stream/xlsx/workbook-writer.js @@ -97,8 +97,16 @@ class WorkbookWriter { async commit() { // commit all worksheets, then add suplimentary files await this.promise; + await this.addMedia(); await this._commitWorksheets(); - await Promise.all([this.addContentTypes(), this.addApp(), this.addCore(), this.addSharedStrings(), this.addStyles(), this.addWorkbookRels()]); + await Promise.all([ + this.addContentTypes(), + this.addApp(), + this.addCore(), + this.addSharedStrings(), + this.addStyles(), + this.addWorkbookRels(), + ]); await this.addWorkbook(); return this._finalize(); } @@ -114,6 +122,16 @@ class WorkbookWriter { return this._worksheets.length || 1; } + addImage(image) { + const id = this.media.length; + this.media.push(Object.assign({}, image, {type: 'image'})); + return id; + } + + getImage(id) { + return this.media[id]; + } + addWorksheet(name, options) { // it's possible to add a worksheet with different than default // shared string handling @@ -197,6 +215,7 @@ class WorkbookWriter { worksheets: this._worksheets.filter(Boolean), sharedStrings: this.sharedStrings, commentRefs: this.commentRefs, + media: this.media, }; const xform = new ContentTypesXform(); const xml = xform.toXml(model); @@ -205,6 +224,29 @@ class WorkbookWriter { }); } + addMedia() { + return Promise.all( + this.media.map((medium, idx) => { + medium.name = `image${idx+1}.${medium.extension}`; + if (medium.type === 'image') { + const filename = `xl/media/${medium.name}`; + if (medium.filename) { + return this.zip.file(medium.filename, {name: filename}); + } + if (medium.buffer) { + return this.zip.append(medium.buffer, {name: filename}); + } + if (medium.base64) { + const dataimg64 = medium.base64; + const content = dataimg64.substring(dataimg64.indexOf(',') + 1); + return this.zip.append(content, {name: filename, base64: true}); + } + } + throw new Error('Unsupported media'); + }) + ); + } + addApp() { return new Promise(resolve => { const model = { diff --git a/lib/stream/xlsx/worksheet-writer.js b/lib/stream/xlsx/worksheet-writer.js index 499cc6e6f..930bb0143 100644 --- a/lib/stream/xlsx/worksheet-writer.js +++ b/lib/stream/xlsx/worksheet-writer.js @@ -150,21 +150,11 @@ class WorksheetWriter { // auto filter this.autoFilter = options.autoFilter || null; + this._media = []; + // start writing to stream now this._writeOpenWorksheet(); - // background - if (options.background && options.background.type === 'image') { - const imageName = this._workbook.addMedia(options.background); - const pictureId = this._sheetRelsWriter.addMedia({ - Target: `../media/${imageName}`, - Type: RelType.Image, - }); - this._background = { - rId: pictureId, - }; - } - this.startedData = false; } @@ -429,8 +419,21 @@ class WorksheetWriter { this._merges.push(dimensions); } + // ========================================================================= + + addBackgroundImage(imageId) { + this._background = { + imageId, + }; + } + + getBackgroundImageId() { + return this._background && this._background.imageId; + } + // ================================================================================ + _write(text) { xmlBuffer.reset(); xmlBuffer.addText(text); @@ -571,7 +574,20 @@ class WorksheetWriter { _writeBackground() { if (this._background) { - this.stream.write(xform.picture.toXml(this._background)); + + if(this._background.imageId !== undefined){ + const image = this._workbook.getImage(this._background.imageId); + const pictureId = this._sheetRelsWriter.addMedia({ + Target: `../media/${image.name}`, + Type: RelType.Image, + }); + + this._background = { + ...this._background, + rId: pictureId, + }; + } + this.stream.write(xform.picture.toXml({rId: this._background.rId})); } } diff --git a/test/test-image-stream-writer.js b/test/test-image-stream-writer.js new file mode 100644 index 000000000..d5f30af59 --- /dev/null +++ b/test/test-image-stream-writer.js @@ -0,0 +1,28 @@ +const path = require('path'); +const Excel = require('../lib/exceljs.nodejs.js'); +const HrStopwatch = require('./utils/hr-stopwatch'); + +const [, , filename] = process.argv; + +const wb = new Excel.stream.xlsx.WorkbookWriter({filename}); + +const imageId = wb.addImage({ + filename: path.join(__dirname, 'data/image2.png'), + extension: 'png', +}); + +const ws = wb.addWorksheet('Foo'); +ws.addBackgroundImage(imageId); + +const stopwatch = new HrStopwatch(); +stopwatch.start(); + +wb.commit() +.then(() => { + const micros = stopwatch.microseconds; + console.log('Done.'); + console.log('Time taken:', micros); +}) +.catch(error => { + console.log(error.message); +}); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy