Page Header and Footer Tutorial
In this tutorial you'll see how to define page's header and footers for your reports.
    Some generators forces you to declare page headers and footers at document head (for example LaTeX), some others force to declare them at the document's body (for example HTML). So, it's a good practice to create a function to generate page's header and footer, and call it according to reportGenerator.isHeaderAndFooterDeclarationAtDocumentHead(). This way, you can change from using any generator without any code changes.

reportGenerator.beginDocument();

reportGenerator.beginDocumentHead();
/* Check if must generate page's header and footer at head */
if (reportGenerator.isHeaderAndFooterDeclarationAtDocumentHead()) {
   generateHeaderAndFooter(reportGenerator);
}
reportGenerator.endDocumentHead();

reportGenerator.beginDocumentBody();
/* Check if must generate page's header and footer at body */
if (!reportGenerator.isHeaderAndFooterDeclarationAtDocumentHead()) {
   generateHeaderAndFooter(reportGenerator);
}

reportGenerator.endDocumentBody();

reportGenerator.endDocument();
         
    Let's see how to define things on our generateHeaderAndFooter function.
    Headers and footers are divided in 3 positions: left, center and right, each of them with its respective alignment (ie: left header is left aligned, center footer is centered, and so on). You can simultaneously use any of those 6 definitions. Let's use here a centered header, a left and a right oriented footer.

void generateHeaderAndFooter(ReportGenerator reportGenerator) throws ReportGenerationException {
   reportGenerator.beginPageHeaderCenter();
   reportGenerator.addText("I'm a document title");
   reportGenerator.addSeparatorLine();
   reportGenerator.endPageHeaderCenter();

   reportGenerator.beginPageFooterLeft();
   reportGenerator.addText(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
   reportGenerator.endPageFooterLeft();

   reportGenerator.beginPageFooterRight();
   reportGenerator.addText("Page ");
   reportGenerator.addCurrentPageNumber();
   reportGenerator.addText(" of ");
   reportGenerator.addTotalPagesCount();
   reportGenerator.endPageFooterRight();
}
         
    Let's explain some elements you see above. At headers and footers you can add texts and images. We've added a textual title centered to the header with:

         reportGenerator.addText("I'm a document title");
         
inside our beginPageHeaderCenter() endPageHeaderCenter block.
    You can also add a line separator from the header to body or from the footer to the body. A separator line will be of the whole page width, so is sufficient to just declare the separator line once on one of the 3 headers (or in one of the 3 footers, if is a footer separator, obviously). There's the mean of the code, inside the same block:

reportGenerator.addSeparatorLine();
         
    At the right aligned footer block:

reportGenerator.beginPageFooterRight();
reportGenerator.addText("Page ");
reportGenerator.addCurrentPageNumber();
reportGenerator.addText(" of ");
reportGenerator.addTotalPagesCount();
reportGenerator.endPageFooterRight();
         
you can see two special elements: the current page number and document's total pages. The last one can only be added to headers or footers, because it's only defined after the document creation is finished. The first one can be used anywhere. With the above code will see on each page a "Page X of Y" text.
    Finally, as you can see, page's header and footer are always the same between all pages of a document. It's this way to make NervalReports portable to any kind of generator, with similar results in each of them.
Here's the pdf generated by NervalReports' PDFReportGenerator:

And here you can download the full code of this tutorial.