1

I'm exploring different options for .NET PDF libraries. One of my requirements is to place a box at the bottom of the first page and if any of the content reaches the box, it should overflow onto the next page.

For example: enter image description here

Shown above, paragraph 7 would normally take up some of the space that's occupied by the "reserved" area. Instead, the part that would have taken up that space is shifted to the next page.

That image was achieved using Gembox.Document by adding the box as a footer element that only renders on the first page. However, in iText7, the examples I've seen for adding a footer (such as this one), places the content as a floating element that renders over the existing content and does not affect the layout/flow of the rest of the document.

I also tried adding a paragraph on the PageEnd event handler without the canvas (snippet below), but instead of adding it to the specified page, it's added to the end of the entire document.

public void HandleEvent(Event evt)
{
    var docEvent = (PdfDocumentEvent)evt;
    var page = docEvent.GetPage();
    int pageNum = docEvent.GetDocument().GetPageNumber(page);

    if (pageNum == 1)
    {
        doc.Add(new Paragraph("Testing a thing"));
    }
}

Is the type of effect I'm looking for something that I can replicate using iText7?

Quangdao Nguyen
  • 1,343
  • 11
  • 25
  • 1
    In itext you have to set the page margins so that there is enough space for your extras (headers, footers, margin notes). – mkl Dec 09 '21 at 06:15

2 Answers2

3

I believe you can combine the concepts of https://github.com/itext/i7ns-samples/blob/develop/itext/itext.samples/itext/samples/sandbox/acroforms/AddExtraTable.cs and https://github.com/itext/i7ns-samples/blob/develop/itext/itext.samples/itext/samples/sandbox/events/TextFooter.cs to achieve what you need.

The idea is as follows:

  • reserve place for your box by making iText give the document's renderer less space for the first page
  • fill this box with a help of iText's end page events

Another option was suggested in How can I insert an element to the bottom of a specific page in iText7? : you can temporary call Document#setBottomMargin , since elements added via Document#add will not be placed on margins. Then, once the first page is layouted, you can set the initial margins again. This option, however, requires understanding of you layout flow, since the margins should be set only after the content of the first page is layouted.

One more suggestion: althouth event functionality is rather flexible and useful, it seems like using a sledgehammer to crack a nut. You need to call Canvas#ShowTextAligned, which could be done without any event handling. So ideally I would prefer to do the following:

  • handle page's layout area via an extension of DocumentRenderer
  • Calling Canvas#ShowTextAligned to fill the reserved box.
Uladzimir Asipchuk
  • 2,368
  • 1
  • 9
  • 19
  • Thanks for the tips! We ended up settling on GemBox but I've accepted this answer for anyone else who might be looking for this. – Quangdao Nguyen Dec 15 '21 at 19:18
1

As you said, you are exploring different .NET PDF libraries. So I would advise PDFFlow library, which does exactly what you need. If you have a footer, main document flow will take the rest of page area and will be automatically continued at the next page without overlaying footer.

DocumentBuilder.New()
    .AddSection()
        .AddParagraph("long text")
    .ToSection()
        .AddFooterToBothPages(40)
            .AddParagraph("this a footer set for each page of this section")
.ToDocument()
    .Build("result.pdf");

Repeating Area example

Here is a tutorial with code examples of using headers, footers, left/right repeating areas: AddingRepeatingArea tutorial.

Hope, this will help you :)