We are not using pappeteer
in our code but jsreport-chorme-pdf
package using it internally. Please check image below.
Any configuration that we can set to resolve this issue?
We are not using pappeteer
in our code but jsreport-chorme-pdf
package using it internally. Please check image below.
Any configuration that we can set to resolve this issue?
Windows server and node js API.
Yes, you are right I shared server-side code. We have one backend service that receives messages from RabbibtMQ and completes further processing to generate reports based on data and send them to UI.
But if I keep UI down and keep only the backend service running then also a blank tab opens on the server side only.
Every time when jsreport.render({...})
is called, an additional empty screen opens up.
This issue appears to be caused by the way the JS Report handles the rendering process, potentially due to incorrect configurations in the chrome-pdf recipe or browser handling of the file.
The file itself generated correctly, but the empty tab should not open during the process.
Please check the following configurations
/**Config*/
const jsreport = require('@jsreport/jsreport-core')({
allowLocalFilesAccess: true,
reportTimeout: 300000,
reports: { async: true },
logger: {
silent: false,
error: { transport: 'file', level: 'error', filename: 'logs/error.txt' },
file: { transport: 'file', level: 'info', filename: 'logs/log.txt' },
console: {
transport: 'console',
level: 'debug',
filename: 'logs/console.txt',
},
},
templatingEngines: {
numberOfWorkers: 4,
strategy: 'in-process',
templateCache: {
max: 100,
enabled: true,
},
},
});
jsreport.use(require('@jsreport/jsreport-handlebars')());
jsreport.use(
require('@jsreport/jsreport-chrome-pdf')({
launchOptions: {
args: ['--ignore-certificate-errors', '--headless', '--disable-gpu', '--no-sandbox', '--disable-dev-shm-usage'],
},
})
);
jsreport.use(require('@jsreport/jsreport-pdf-utils')({
"extensions": {
"pdf-utils": {
enabled: true,
}
}
}));
module.export = {
jsReportRender: async (
_id,
headerHeight,
footerHeight,
displayHeaderFooter,
header,
footer,
htmlContent,
headerFooterContent
) => {
return new Promise((resolve, reject) => {
const templateConfig = {
id: id,
shortid: 'ABC',
recipe: 'chrome-pdf',
engine: 'handlebars',
chrome: {
format: 'Letter',
marginRight: '20px',
marginLeft: '20px',
marginTop: headerHeight,
marginBottom: footerHeight,
displayHeaderFooter: displayHeaderFooter,
headerTemplate: header,
footerTemplate: footer,
mediaType: 'print',
},
content: htmlContent
};
// Conditionally add pdfOperations if headerFooterContent is not null
if (headerFooterContent) {
templateConfig.pdfOperations = [
{
type: "merge",
template: {
content: headerFooterContent,
engine: "handlebars",
recipe: "chrome-pdf",
helpers: `
function getPageNumber (pageIndex) {
if (pageIndex == null) {
return ''
}
const pageNumber = pageIndex + 1;
return pageNumber;
}
function getTotalPages (pages) {
if (!pages) {
return '';
}
return pages.length;
}
`
},
mergeToFront: true,
mergeWholeDocument: true,
renderForEveryPage: false
},
];
}
/** Render the report */
return jsreport.render({
template: templateConfig
}).then((out) => {
return resolve(out.content); // Ensure the output is properly handled here
}) .catch((err) => {
console.trace();
console.error(err);
reject(err);
});
});
}
}
We eagerly await your guidance and a solution to address this inconsistency.
Thank you for your assistance.
It works.
Thank you for your assistance.
We are not able to replicate the problem in the playground, but it works fine there. Please check the below for reference.
https://playground.jsreport.net/w/anon/PyLGRA04.
But the problem is that in my app, we always get 0 for the 5 value when printing the page number.
<html>
<head>
<style>
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
}
.header {
width: 100%;
padding-top: 20px;
border-bottom: 1px solid black;
}
.footer {
width: 100%;
padding-bottom: 20px;
border-top: 1px solid black;
text-align: right;
padding-right: 25px;
}
.header-logo {
padding-left: 25px;
}
.company-logo {
height: 50px;
object-fit: cover;
}
.header-content {
text-align: right;
padding-right: 25px;
}
</style>
</head>
<body>
{{#each $pdf.pages}}
{{#if 5}}
<div style="page-break-before: always;"></div>
{{/if}}
<main class="main">
<header class="header">
// header
</header>
<footer class="footer">
<span>Page {{getPageNumber 5}} of {{getTotalPages ../$pdf.pages}}</span>
</footer>
</main>
{{/each}}
</body>
</html>
We are experiencing an issue with JSReport when using Chrome PDF and Handlebars for rendering multi-page PDFs. The current page number is consistently rendered as 1 for all pages, rather than reflecting the correct page index. Despite looping through the $pdf.pages and utilizing the helper function getPageNumber, the page index remains static across all pages.
Issue Details:
Function: jsReportRender
Template Engine: Handlebars
Recipe: Chrome PDF
PDF Utils: Enabled for PDF manipulation
Behavior: In the rendered PDF, the Page {{getPageNumber 6}} of {{getTotalPages ../$pdf.pages}} block in the footer displays "Page 1 of X" on all pages, even though each page should display the correct current page number (1, 2, 3, etc.).
Expectation: The getPageNumber helper should increment the page number for each page rendered.
Current Outcome: The page number is stuck at 1 for all pages.
Template
This is jsReportRender
jsReportRender: async (
_id,
headerHeight,
footerHeight,
displayHeaderFooter,
header,
footer,
htmlContent,
headerFooterContent
) => {
return new Promise((resolve, reject) => {
const templateConfig = {
id: id,
shortid: 'xyz',
recipe: 'chrome-pdf',
engine: 'handlebars',
chrome: {
format: 'Letter',
marginRight: '20px',
marginLeft: '20px',
marginTop: headerHeight,
marginBottom: footerHeight,
displayHeaderFooter: displayHeaderFooter,
headerTemplate: header,
footerTemplate: footer,
mediaType: 'print',
},
content: htmlContent
};
/** Conditionally add pdfOperations if headerFooterContent is not null*/
if (headerFooterContent) {
templateConfig.pdfOperations = [
{
type: "merge",
template: {
content: headerFooterContent,
engine: "handlebars",
recipe: "chrome-pdf",
helpers: `
function getPageNumber (pageIndex) {
if (pageIndex == null) {
return ''
}
const pageNumber = pageIndex + 1;
return pageNumber;
}
function getTotalPages (pages) {
if (!pages) {
return '';
}
return pages.length; // Total number of pages
}
`
},
mergeToFront: true,
mergeWholeDocuments: true,
renderForEveryPage: false
},
];
}
// Render the report
return jsreport
.render({
template: templateConfig
})
.then((out)
=> {
return resolve(out.content);
})
.catch((err) => {
console.trace();
console.error(err);
reject(err);
});
});
},
Template
<html>
<head>
<style>
* {
box-sizing: border-box;
}
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
.main {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
}
.header {
width: 100%;
padding-top: 20px;
border-bottom: 1px solid black;
}
.footer {
width: 100%;
padding-bottom: 20px;
border-top: 1px solid black;
text-align: right;
padding-right: 25px;
}
.header-logo {
padding-left: 25px;
}
.company-logo {
height: 50px;
object-fit: cover;
}
.header-content {
text-align: right;
padding-right: 25px;
}
</style>
</head>
<body>
{{#each $pdf.pages}}
{{#if 6}}
<div style="page-break-before: always;"></div>
{{/if}}
<main class="main">
<header class="header">
// header
</header>
<footer class="footer">
<span>Page {{getPageNumber 6}} of {{getTotalPages ../$pdf.pages}}</span>
</footer>
</main>
{{/each}}
</body>
</html>
Config file
const jsreport = require('@jsreport/jsreport-core')({
allowLocalFilesAccess: true,
reportTimeout: 300000,
reports: { async: true },
logger: {
silent: false,
error: { transport: 'file', level: 'error', filename: 'logs/error.txt' },
file: { transport: 'file', level: 'info', filename: 'logs/log.txt' },
console: {
transport: 'console',
level: 'debug',
filename: 'logs/console.txt',
},
},
templatingEngines: {
numberOfWorkers: 4,
strategy: 'in-process',
templateCache: {
max: 100, // LRU cache with max 100 entries, see npm lru-cache for other options
enabled: true, // disable cache
},
},
});
Injecting the Handlebars engine
jsreport.use(require('@jsreport/jsreport-handlebars')());
Injecting the Chrome PDF recipe
jsreport.use(
require('@jsreport/jsreport-chrome-pdf')({
launchOptions: {
args: ['--ignore-certificate-errors', '--headless', '--disable-gpu', '--no-sandbox', '--disable-dev-shm-usage'],
},
})
);
Injecting PDF Utils for PDF manipulation
jsreport.use(require('@jsreport/jsreport-pdf-utils')());
module.exports = jsreport;
We eagerly await your guidance and a solution to address this inconsistency.
Thank you for your assistance.