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 0}} 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 0}}
<div style="page-break-before: always;"></div>
{{/if}}
<main class="main">
<header class="header">
// header
</header>
<footer class="footer">
<span>Page {{getPageNumber 0}} 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.