With Flying Saucer, how do I generate a pdf with a page number and page total on every page at the footer?

18,285

Solution 1

You could also try a slightly more succinct approach:

@page {
  @bottom-right {
    content: "Page " counter(page) " of " counter(pages);
  }
}

You need to put this in your css/style, and you do not need to add an extra footer HTML element.

Solution 2

In your html, you need to put this somewhere in the body tag:

<div id="footer">
    page <span id="pagenumber"></span> of <span id="pagecount"></span>
</div>

And this should be your css/style:

    #footer {
        position: running(footer);
        text-align: right;
    }

    @page {
        @bottom-right {
            content: element(footer);
        }
    }

    #pagenumber:before {
        content: counter(page);
    }

    #pagecount:before {
        content: counter(pages);
    }

You can learn more about that @bottom-right option here.

Solution 3

Important Error & Solution!

For Starters, using John Mark's solution below is the CORRECT way to get it working:

@page {
  @bottom-right {
    content: "Page " counter(page) " of " counter(pages);
  }
}

However many people may have encountered the following issue where your PDF HAS STOPPED GENERATING!

This is solved by updating your VERSION of FLYING SAUCER.

I was running 9.1.4 when my PDF stopped generating due to the @page & @bottom-right css code.

This was a glitch in Flying Saucer that was fixed in version 9.1.5!

Make sure to update to 9.1.5 and use John Mark's answer.

Solution 4

@John Mark 's solution worked for me. In my application I needed to embed the style info in the HTML, so I wrapped this in <style> tags and put it inside the <head> before <title>. Maybe that info will be useful to someone else.

Solution 5

The most upvoted answer did not work for me, the footer only showed on the last page. (This behavior is also mentioned in the comments below the answer provided by Daniel Kaplan.)

The solution to this problem was provided by the following comment:

@PauloOliveira It shows only on the last page when the is too far down in the . Place it somewhere higher so that it will print before the first page ends. But John Mark's answer is better. – Edward Feb 3 '20 at 12:16

So what has worked for me (using FlyingSaucer rendering with OpenPDF) is the following - placing the definition of the footer element somewhere above the main content and applying the solution provided by Daniel Kaplan:

<body>
  <div id="header">Some header content</div>
  <div id="footer">
    page <span id="pagenumber"></span> of <span id="pagecount"></span>
  </div>
  <div th:each="item: ${listOfItems}">
    [The long content listing things over multiple pages...]
  </div>
</body>

And the CSS code:

@page {
    size: A4 portrait;
    margin-top: 2cm;
    margin-left: 2cm;
    margin-right: 2cm;
    margin-bottom: 3cm;

    @bottom-left {
        content: element(footer); /* footer element must be specified before end of first page! */
        vertical-align: top;
    }
}


#pagecount::after {
    content: counter(pages);
}

#pagenumber::after {
    counter-increment: page;
    counter-reset: page 1;

    content: counter(page);
}
Share:
18,285
Rana Ghosh
Author by

Rana Ghosh

Updated on June 02, 2022

Comments

  • Rana Ghosh
    Rana Ghosh almost 2 years

    It took me a little more research than I would have liked to figure this out on my own, so I'm going to post a comprehensive answer here. It seems like the information to do this is spread across many different websites and I'd like to put it in one place. This answer may be the same thing, but my eyes glaze over because it's in a Java string and not in a html template. Here's the question:

    I'm rendering a PDF and I want a footer at the bottom of the page that says, "Page n of m" where "n" is the page number you're on and "m" is the total pages in the document. How do I do that?