How to display footer on every page and show additional content only on the last page using jsreport with NestJS integration



  • 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 0}} 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!



  • You are missing mergeWholeDocument:true in the template's pdfOperations.

    When you have something working in full jsreport but not in your code, the easiest way to find out the difference is to open the entity definition in studio

    0_1738154546953_upload-518c9267-7324-4c40-9f09-1420f8a9f857

    You would find there you are missing "mergeWholeDocument": true

    pdfOperations": [
        {
          "type": "merge",
          "mergeWholeDocument": true,      
           ....
        }
      ]
    


  • Hi!

    First of all, I want to sincerely thank you for your help with the evaluation of the last page in my document. I truly appreciate the support!

    Now, I hope I’m not asking for too much, but I need help with another issue.

    I’m using jsreport and I need to apply different margins to the pages, as the margins for the last page should be different from the previous ones. Specifically:

    • The footer changes on the last page due to unique content displayed only there.

    • The margin for the header on the first page is also different from the rest of the pages.

    • The bottom margin should change only on the last page.

    • I have tried using page:first and page:last with direct margin adjustments in the content container, but it doesn't seem to work as expected, and the content overlaps.

    Any suggestions or best practices would be greatly appreciated!

    https://playground.jsreport.net/w/anon/0ft5SBMO


Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.