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.
I wasn't able to make progress. The error is the same as above. I CAN get past it if I do
sudo npm i -S jsreport --unsafe-perm=true
jsreport init
But, in the application there is still an error. The error is:
or: Failed to launch chrome!
[0730/185614.730358:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
at onClose (/opt/mynewapp/node_modules/puppeteer/lib/Launcher.js:342:14)
at Interface.helper.addEventListener (/opt/mynewapp/node_modules/puppeteer/lib/Launcher.js:331:50)
at emitNone (events.js:111:20)
at Interface.emit (events.js:208:7)
at Interface.close (readline.js:368:8)
at Socket.onend (readline.js:147:10)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
The above error was on the jsreport init
call
I am having this same issue as well. I've gone through the amazon-linux steps but they fail with the same error. Trying to work through it now, but not sure how to get around this.
jsreport installation not found, installing jsreport latest version now, wait a moment...
Unexpected error happened: Command failed: npm i -S jsreport
ERROR: Failed to download Chromium r662092! Set "PUPPETEER_SKIP_CHROMIUM_DOWNLOAD" env variable to skip download.
{ Error: EACCES: permission denied, mkdir '/opt/mynewapp/node_modules/puppeteer/.local-chromium'
-- ASYNC --
at BrowserFetcher.<anonymous> (/opt/mynewapp/node_modules/puppeteer/lib/helper.js:110:27)
at Object.<anonymous> (/opt/mynewapp/node_modules/puppeteer/install.js:64:16)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
at startup (bootstrap_node.js:204:16)
at bootstrap_node.js:625:3
errno: -13,
code: 'EACCES',
syscall: 'mkdir',
path: '/opt/mynewapp/node_modules/puppeteer/.local-chromium' }
npm WARN pdfjs-dist@2.0.489 requires a peer of webpack@^2.0.0 || ^3.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN worker-loader@1.1.1 requires a peer of webpack@^2.0.0 || ^3.0.0 || ^4.0.0 but none is installed. You must install peer dependencies yourself.
npm WARN jsreport-server@ No description
npm WARN jsreport-server@ No repository field.
npm WARN jsreport-server@ No license field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! puppeteer@1.17.0 install: `node install.js`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the puppeteer@1.17.0 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2019-07-30T18_08_13_488Z-debug.log
(1).
caused by error (1) -> meta = {"killed":false,"code":1,"signal":null,"cmd":"npm i -S jsreport"}, stack = Error:
at ChildProcess.exithandler (child_process.js:281:12)
at emitTwo (events.js:126:13)
at ChildProcess.emit (events.js:214:7)
at maybeClose (internal/child_process.js:915:16)
at Socket.stream.socket.on (internal/child_process.js:336:11)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at Pipe._handle.close [as _onclose] (net.js:561:12)
Thanks! I wasn't aware that the template properties worked this way.
Yep. The above file was correct. I was able to change the limit from 3 processes to 10 and then everything worked. Hope this is useful to someone in the future.
I have a chrome-image
template that I am rendering and I want to clip the height of the image based on the number of rows of data that end up in the image. Is there a way to specify a custom clip height in the request to the template or in a beforeRender script? I can't have it be a static value like the UI wants.
Thanks!
I think I found it at node_modules\jsreport-scripts\lib\defaultProxyHandlers.js
. Please let me know if this is correct.
I am getting the following error:
Error: Reached maximum number of script rendering requests. Verify that reporter.render is not causing cycle
This is because in the beforeRender
script I am intentionally rendering 6 other chrome image templates. I need these images so that I can take their bytes and inject them into my final docxtemplater template. Everything works if I ask it to only render 3 of the image templates. Once I increase it to 4 it stops working.
How can I increase this limit? If there is no config for it, can you let me know where in the code this is? I will change it in my fork.
Thanks!
@jan_blaha after I make this change how do I do the equivalent of npm install jsreport-docxtemplater
? Can I just replace the jsreport-docxtemplater folder under node-modules?
Thanks for the info. I'll give it a shot and let you know what happens.