guigrpa / docx-templates

Template-based docx report creation
MIT License
882 stars 145 forks source link

IMAGE - creating object in template using image data? #350

Closed MattCrum1 closed 7 months ago

MattCrum1 commented 7 months ago

I'm feeding a docx template from Node-Red, passing it the "msg.payload" JSON object which contains an array of host objects, with "name" and "image" for each. "name" is a string, "image" is base64 image data.

Using a loop, I can print the host.name fine for each host, but am struggling to get the image to work.

I know that it expects a specific object structure - was hoping that there was a way to build it in the template itself like this - but it keeps giving an unexpected token error. Tried a couple of things including fix smart quotes:

+++INS $host.name +++  <=== Works fine
+++IMAGE { width: 6, height: 6, $host.image, extension: '.png' } +++
+++IMAGE { width: 6, height: 6, "data:image/png;base64,$host.image", extension: '.png' } +++

"Error: Error executing command '{ width: 6, height: 6, $host.image, extension: '.png' }': Unexpected token ':'"

Do we know if it is possible to insert an image like this, or do I have to create the object in the script and call it from the template (ideally want to avoid this ...).

Appreciate any pointers - thanks

jjhbw commented 7 months ago

If that is the exact error string you're getting, it may have something to do with string literal quoting used, as the 'command' featured in the error message lacks the data:image/png;base64, substring.

Regardless, injecting images like this is not supported, so even if it works I wouldn't count on it working in the future.

If you really want to go this way, you can try is using anonymous function that returns your object, e.g. IMAGE ()=> { width: 6, height: 6, "data:image/png;base64,$host.image", extension: '.png' }, taking special care to get the literal quoting correct. I'm not sure from the top of my head whether this will work, but worth a try.

MattCrum1 commented 7 months ago

Thanks @jjhbw - I've set the object value in the JSON array to the correct format - "host.image" value now looks like this:

{ width: 6, height: 6, extension: '.png', data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlUAAAC2CAIAAAB... }

Tried then injecting it like this in the template, but it doesn't seem to like it:

+++IMAGE $host.image +++

Error is ""Error: Error executing command 'IMAGE $host.image': invalid image width: undefined (in cm)"" - which suggests that it is not able to read $host.image?

It shows up fine in an "INS" tag - perhaps it's reading it in as a string rather than an object? Thanks for your patience - not fluent in JS (as may be obvious).

MattCrum1 commented 7 months ago

Ended up getting it to work by sending the $host.image to a function, which sends it straight back again - will keep that, unless there's a way to read $host.image within the IMAGE tag directly:

+++IMAGE getImageObject($host.image) +++

additionalJsContext: { getImageObject: base64data => { const data = base64data; return { width: 8.8, height: 3, data, extension: '.png' }; },