Image rendering in content but not header
-
@mike-subtilis are you following all the steps mentioned here (https://jsreport.net/learn/assets#embedding-assets-as-links, https://jsreport.net/learn/assets#external-files-access)? i think that you don't have some asset's options enabled.
-
I think so. Using a basic node-express app, I've added the following endpoint.
I've tried:
- fileAsset equals the absolute path as listed below, as link or dataURI, and with the rootUrlForLinks present or missing
- fileAsset equals the '/images/home.jpg' with the rootUrlForLinks, and I can access that image via "http://localhost:3000/images/home.jpg"
I'm not sure if there's additional work I need to do to preload the assets. But in all cases I get Error during rendering report: Asset ~/Documents/dev/span/utilities/report-test/public/images/home.jpg not found.
I'm probably missing something obvious. I can get it to work in the standalone jsreport server, but not when using jsreport as a library.
router.get('/', function(req, res, next) { const fileAsset = '~/Documents/dev/span/utilities/report-test/public/images/home.jpg'; const invoiceTemplate = `<h1>BODY</h1><img src='{#asset ${fileAsset} @encoding=link}' style='display: none;'></img> <h1> Invoice </h1>`; jsreport.render({ template: { content: invoiceTemplate, engine: 'jsrender', recipe: 'phantom-pdf', phantom: { header: `<img src='{#asset ${fileAsset} @encoding=link}' width="135" height="25"/> <span>My Great Report</span>`, footer: '<span>{#pageNum}/{#numPages}</span>', }, assets: { publicAccessEnabled: true, searchOnDiskIfNotFoundInStore: true, rootUrlForLinks: "http://localhost:3000", } }, data: { }, }).then(function(out) { console.log('SUCCESS!'); out.stream.pipe(res); }).catch(function(e) { console.log('error '); console.log(e); res.end(e.message); }); });
-
you need to also set (as shown in the docs of
assets
) thepublicAccessEnabled
andsearchOnDiskIfNotFoundInStore
options totrue
.have you done that too?
-
ah sorry, you are doing that, let me check more closely
-
maybe try to pass a real absolute path, you are using
~/Documents/dev/span/utilities/report-test/public/images/home.jpg
which has a~
character, try to normalize that to a full path, maybe usingpath.resolve
function of node's path module.
-
I tried the full regular path (/Users/mikecullingham/Documents/dev/span/utilities/report-test/public/images/home.jpg) trying dataURI & link encoding types with the same result both times.
-
asset
options must be passed when creating a jsreport instance (not in render method), in your case since you are not creating any instance you don't have the chance to pass those options, so you will need to create a jsreport instance.example working code:
var express = require('express'); // creating jsreport with custom asset options var jsreport = require('jsreport')({ assets: { allowedFiles: '**/*.*', // this is important because here you pass what types files (or even inside directories) do you allow, in this case i'm allowing everything publicAccessEnabled: true, searchOnDiskIfNotFoundInStore: true, rootUrlForLinks: "http://localhost:5488" } }); var app = express(); var server; app.get('/render', function(req, res) { const fileAsset = '/Users/mikecullingham/Documents/dev/span/utilities/report-test/public/images/home.jpg'; const invoiceTemplate = `<h1>BODY</h1><img src='{#asset ${fileAsset} @encoding=dataURI}' style='display: none;'></img> <h1> Invoice </h1>`; jsreport .render({ template: { content: invoiceTemplate, engine: 'jsrender', recipe: 'phantom-pdf', phantom: { header: `<img src='{#asset ${fileAsset} @encoding=dataURI}' width="135" height="25"/> <span>My Great Report</span>`, footer: '<span>{#pageNum}/{#numPages}</span>' } }, data: {} }) .then(function(out) { console.log('SUCCESS!'); out.stream.pipe(res); }) .catch(function(e) { console.log('error '); console.log(e); res.end(e.message); }); }); server = app.listen(9500, () => { console.log('SERVER STARTED'); jsreport .init() .then(() => console.log('JSREPORT STARTED')) .catch(err => console.error('ERROR WHILE STARTING JSREPORT', err)); });
-
Thanks for all the quick communication btw. I'll take a look at that. I'm also looking at doing a more SOA approach where we use the jsreport server and call out from out own app, which has its own advantages.
-
I'm also looking at doing a more SOA approach where we use the jsreport server and call out from out own app, which has its own advantages.
exactly, in my opinion that is the best way to communicate with jsreport, it will also let you manage server resources separately, which it's better
-
and just for the record, the reason why it works as standalone server and not when using it as a library is because in standalone server you can put
assets
options indev.config.json
/prod.config.json
, but when using jsreport as a library, you either create a new instance of jsreportvar jseport = require('jsreport')(/* custom options here */); jsreport.render()
(with the possibility to pass custom options, like theassets
options) or use a default onevar jsreport = require('jsreport'); jsreport.render()
which has some defaults (which you can not override).so since you were using the default instance you were not able to override
assets
options, fixable by creating an instance.
-
just for the record there is method to change options for
render
shortcut as well. It just got somehow out of the documentation.var jsreport = require('jsreport') jsreport.renderDefaults.assets = {....} jsreport.render(...)