Hmm.. It's an older version of jsreport-docxtemplater. I will repeat that I do have this working - I am using a docx as a template, but now I can't change it.
jsreport-cli@2.0.7
jsreport@2.5.0
jsreport-docxtemplater@1.0.0
jsreport-unoconv@0.2.0
Hmm.. It's an older version of jsreport-docxtemplater. I will repeat that I do have this working - I am using a docx as a template, but now I can't change it.
jsreport-cli@2.0.7
jsreport@2.5.0
jsreport-docxtemplater@1.0.0
jsreport-unoconv@0.2.0
I am using the docxtemplater recipe on my template. I want to switch it to use a different docx file, but I can't remember where to do that. Looking at the video at https://jsreport.net/learn/docxtemplater it shows that after creating a template and selecting the docxtemplater recipe I should be able to select from the 'docxtemplater asset' dropdown. On my instance of jsreport I don't have that. I know the setting exists because this template is already hooked up and running against this docx file.
I'm on jsreport version 2.5.0
Here's an image:
So, where is this setting? I can't find it.
I was able to get this working. a few weeks ago. I had to modify the jsreport-docxtemplater module and the jsreport-scripts module.
The jsreport-scripts change was just to allow more render calls in a pre-render script. Without this change I was limited to a max of 3 images I could put inside my final document. The change I made is documented in this forum post: https://forum.jsreport.net/topic/1170/error-reached-maximum-number-of-script-rendering-requests
The jsreport-docxtemplater module change was to attach the image module to the docxtemplater instance and to auto detect the size of the PNG images I wanted to substitute into the document.
The changes are all to the jsreport-docxtemplater/lib/recipe.js file. Around where the docxtemplater instance is being created and the document is being generated, the code now looks like this
function base64DataURLToArrayBuffer(dataURL) {
let binaryString;
if (typeof window !== "undefined") {
binaryString = window.atob(dataURL);
} else {
binaryString = Buffer.from(dataURL, "base64").toString("binary");
}
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {
const ascii = binaryString.charCodeAt(i);
bytes[i] = ascii;
}
return bytes.buffer;
}
// This function gets the width and height of a PNG. A PNG’s width and height are always bytes 16-24 of its byte representation.
// Here is a stack overflow post where some of this is explained and shows how to convert the base64 to the width and height.
//https://stackoverflow.com/questions/15327959/get-height-and-width-dimensions-from-base64-png
// In node it works differently because there is no atob function.
function getPngDimensions(base64) {
// This is essentially the atob() function on the first 50 characters of the base64 representation of an image.
// We only care to process the first 50 chars or so because we only need bytes 16-24 after it's converted.
const header = Buffer.from(base64.slice(0,50), 'base64').toString('binary').slice(16,24);
const uint8 = Uint8Array.from(header, c => c.charCodeAt(0))
const dataView = new DataView(uint8.buffer)
return {
width: dataView.getInt32(0),
height: dataView.getInt32(4)
}
}
const opts = {};
opts.getImage = function(tag) {
return base64DataURLToArrayBuffer(tag);
};
opts.getSize = function(img) {
var sizeObj = getPngDimensions(img);
console.log(sizeObj);
return [sizeObj.width, sizeObj.height];
};
var imageModule = new ImageModule(opts);
var zip = new JSZip(templateAsset.content);
var docx = new Docxtemplater()
.attachModule(imageModule)
.loadZip(zip)
.setData(req.data)
.render();
also had to add
const ImageModule=require('docxtemplater-image-module')
to the top of the file.
For any of this to work I needed to first buy the docxtemplater image module. Once you've purchased this module you need to install it in your jsreport directory using npm. They will send you the command to run.
After you've made the javascript changes above to jsreport-scripts and jsreport-docxtemplater you need to delete the existing jsreport-scripts and jsreport-docxtemplater npm modules from your jsreport app directory and replace them with your customized versions (copy/paste or you can just make the change the the existing module itself).
To put this all together what I do is create a docxtemplater template with the appropriate markup for image substitution and in that recipe i create a beforeRender script that takes data posted to the template and posts it to another template which returns a PNG from a chrome-image recipe. I feed the return value from the image template into the data of the docxtemplater template. Below is an example of what I'm doing in the beforeRender.
const jsreport = require('jsreport-proxy')
async function beforeRender(req, res, done) {
const promise1 = jsreport.render({template: {name: 'MyTemplate'}, data: {"myData": req.data.myData, "otherData": req.data.otherData }});
var myResult = await promise1;
myContentAsBase64 = Buffer.from(myResult.content).toString('base64');
req.data.myImageData = myContentAsBase64;
done();
}
Reminder that if you want to generate more than 3
templates in this before render script that you NEED to make the corresponding change in jsreport-scripts module.
And that's it! Hope this helps someone in the future.
I didn't need to change the permissions of node_modules. There may be an alternate way to solve the problem, though.
Thanks! I had no idea.
I have a docxtemplater recipe that I use unoconv to turn the docx file into a PDF. On the same recipe if I don't do PDF conversion it will download a doc to my downloads folder when I run the recipe. When I turn on unoconv/PDF conversion the recipe shows the converted PDF in the preview window, but doesn't download it. How can I get the download to happen?
You may be right. I did have to play around with node_modules permissions, but don't remember if that made it into the final cut or not. As I terraform this I'll remember and update.
Just figured it out. Wow. I thought I was going to have to switch to Ubuntu, but the following fixes it for me.
sudo npm i -S jsreport --unsafe-perm=true
jsreport init
and then change your chrome options like is listed in the CentOS documentation
https://jsreport.net/learn/centos`
# change in the jsreport.config.json the following
# it makes chrome less secure but currently the only way on CentOS
"chrome": {
"launchOptions": {
"args": ["--no-sandbox"]
}
}
A few more notes. I'm on amazon linux 2 and I'm not using elastic beanstalk. I'm not running on docker.