Hello,
I'm working with JSReport integrated into my NestJS project, using chrome-pdf and pdf-utils for PDF generation. I am using Handlebars (hbs) as my template engine. I need help with two things:
-
I want to show a footer on every page, but on the last page, I need to include additional content in the footer. I am already using a helper function to get the page number, but the footer is not showing on all pages, or the additional content is not displaying only on the last page.
-
Also, the total page count returned in the PDF is incorrect. Could you guide me on how to fix this issue?
Here is my current setup:
import { Controller, Get, Res } from '@nestjs/common';
import { Response } from 'express';
import { ReportService } from 'reportes/services/jsReport.service';
import { readFileSync } from 'fs';
import { join } from 'path';
@Controller('report')
export class ReportController {
constructor(private readonly reportService: ReportService) { }
@Get()
async getReport(@Res() res: Response) {
const templateHtml = readFileSync(
join(__dirname, '..', '..', '..', `views/solicitudes/solicitud-biopsia-report.hbs`),
'utf8'
);
const template = {
engine: 'handlebars',
recipe: 'chrome-pdf',
content: templateHtml,
helpers: readFileSync(
join(__dirname, '..', '..', '..', 'views/solicitudes/helpers.js'),
'utf8'
),
chrome: {
marginTop: '15px',
marginBottom: '90px',
marginLeft: '0',
marginRight: '0',
format: 'Letter',
printBackground: true,
},
pdfOperations: [
{
type: 'merge',
template: {
engine: 'handlebars',
recipe: 'chrome-pdf',
content: readFileSync(
join(__dirname, '..', '..', '..', 'views/solicitudes/footer.hbs'),
'utf8'
),
helpers: readFileSync(
join(__dirname, '..', '..', '..', 'views/solicitudes/helpers.js'),
'utf8'
)
},
mergeToFront: false,
}
],
};
const data = {};
const report = await this.reportService.generateReport(template, data);
res.setHeader('Content-Type', 'application/pdf');
res.send(report);
}
}
Footer Template (footer.hbs):
<html>
<head>
<style>
* {
box-sizing: border-box;
}
html, body {
margin: 0px;
padding: 0px;
}
.footer {
width: 100%;
padding-bottom: 20px;
border-top: 1px solid black;
}
</style>
</head>
<body>
{{#each $pdf.pages}}
<div style="page-break-before: always;"></div>
<footer class="footer">
{{#if @last}}
<h1>This is a disclaimer (shown only on the last page)</h1>
{{/if}}
<span>Page {{getPageNumber 4}} of {{getTotalPages ../$pdf.pages}}</span>
</footer>
{{/each}}
</body>
</html>
Helper Functions:
function getPageNumber(pageIndex) {
if (pageIndex == null) {
return '';
}
return pageIndex + 1;
}
function getTotalPages(pages) {
if (!pages) {
return '';
}
return pages.length;
}
Issues:
The footer does not appear on all pages, and the additional content only appears on the last page.
The total page count is incorrect.
Environment:
Node.js version: 22.13.1
JSReport version: 4.
Note: The template works in the JSReport playground, but not in my NestJS project. https://playground.jsreport.net/w/anon/0ft5SBMO
Can anyone help me with this?
Thanks in advance!