-2

I am working on a project where as part of statements I need to attach arbitrary PDF files. These PDF files need to be marked by a title and page numbering, in the top-right corner of the PDF file. This is a legal requirement as these attachments are referred to by their title and total number of pages from the statements.

I (naively) hacked together some code that appears to be working on PDF files with pages in the Portrait orientation (at least the PDF files I tested with). However when I use this code on pages in a Landscape orientation, the title and numbering isn't visible.


The code:

PdfContentByte canvas = pdfStamper.getOverContent( pageNr );

Phrase phrase = new Phrase( sb.toString( ), new Font( FontFamily.HELVETICA, 9f ) ); // sb holds title + page numbering
float width = ColumnText.getWidth( phrase );

ColumnText.showTextAligned ( // draw text top-right
    canvas,
    Element.ALIGN_LEFT,
    phrase,
    canvas.getPdfDocument( ).right( ) - width, //x
    canvas.getPdfDocument( ).top( ) + 9, //y
    0 //rotation
);

Examples:

  • Portrait where it appears to work:

enter image description here

  • Landscape where it doesn't work:

enter image description here


Questions:

  • Where did I go wrong?
  • Is it possible to write such a piece of code that does it right for all possible page orientations?
  • If so, how?
TT.
  • 15,774
  • 6
  • 47
  • 88

2 Answers2

1

You are adding the content, but you are adding it at the wrong place. See PageSize of PDF always the same between landscape and portrait with itextpdf

Let's assume that you are working with an A4 page using portrait orientation. That pages measures 595 by 842 user units. 595 is the width; 842 is the height.

Now let's switch to landscape. This can be done in two different ways:

  1. define a width of 595 and a height of 842, and a rotation of 90 degrees.
  2. define a width of 842 and a height of 595.

Which way is used to define the landscape orientation will have an impact on the value of the right() and top() method. I am pretty sure that you are adding the header to the landscape pages, but you are adding them outside the visible area of the page.

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • Thank you for your insights Bruno. I solved the issue by using `pdfReader.getPageSizeWithRotation( pageNr )` as the basis to place the title/numbering. – TT. Dec 27 '16 at 09:40
0

For those interested, I ended up doing it as follows. This works for both Portrait and Landscape orientations. This uses the PdfReader.getPageSizeWithRotation method to get the proper page size.


private String pageText(int pageNr, int pageTotal) {
    return ""; // generate string to display top-right of PDF here
}

private void addDocumentObjects(int pageNr, PdfReader pdfReader, PdfStamper pdfStamper) {
    final float pageMargin = 25f;
    final float textSize = 9f;
    final float lineMargin = 5f;

    Phrase phrase = new Phrase (
        pageText(pageNr, pdfReader.getNumberOfPages()),
        new Font(FontFamily.HELVETICA, textSize)
    );
    final float phraseWidth = ColumnText.getWidth(phrase);

    PdfContentByte canvas = pdfStamper.getOverContent(pageNr);
    com.itextpdf.text.Rectangle pageRectangle = pdfReader.getPageSizeWithRotation(pageNr);

    // draw white background rectangle before adding text + line
    canvas.setColorFill(BaseColor.WHITE);
    canvas.rectangle (
        pageRectangle.getRight(pageMargin) - phraseWidth, //x
        pageRectangle.getTop(pageMargin), //y
        phraseWidth, // width
        textSize + lineMargin //height
    );
    canvas.fill();

    // draw text top right
    canvas.setColorFill(BaseColor.BLACK);
    ColumnText.showTextAligned (
        canvas, //canvas
        Element.ALIGN_LEFT, //alignment
        phrase, //phrase
        pageRectangle.getRight(pageMargin) - phraseWidth, //x 
        pageRectangle.getTop(pageMargin), //y
        0 //rotation
    );

    // draw line under text
    canvas.setColorStroke(BaseColor.BLACK);
    canvas.setLineWidth(1);
    canvas.moveTo (
        pageRectangle.getRight(pageMargin) - phraseWidth, //x
        pageRectangle.getTop(pageMargin) - lineMargin //y
    );
    canvas.lineTo (
        pageRectangle.getRight(pageMargin), //x
        pageRectangle.getTop(pageMargin) - lineMargin //y
    );
    canvas.stroke();
}
TT.
  • 15,774
  • 6
  • 47
  • 88