Gayolomao
Gayolomao

Reputation: 596

Bookmarks imbalance when rotating pdf page

I'm building a PDF with multiple tables. Some of them are wider than usual, so I have to rotate several pages (put them in landscape) in order to see the whole table comfortably.

The problem is: when I rotate the document into landscape, the bookmarks generated from that point are delayed (more or less) one page. It's not exactly one page, there is an imbalaced, but I've been able to workaround it by shifting those bookmarks one page back.

At the biggining I tried to rotate the document while it was being written. Then I tried to open do both writings (portrait and landscape) in separated documents, merging them into one final document with their bookmarks. The (bad) result is the same in both cases.

Here is the code I use for it:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
ByteArrayOutputStream baosLandscape = new ByteArrayOutputStream();
ByteArrayOutputStream baosTotal = new ByteArrayOutputStream();

PdfCopyFields copier = new PdfCopyFields(baosTotal);
copier.setViewerPreferences(PdfWriter.PageModeUseOutlines);

Document document = new Document(PageSize.A4, 72, 48, 48, 24);
PdfWriter writer = PdfWriter.getInstance(document, baos);
writer.setViewerPreferences(PdfWriter.PageModeUseOutlines);
document.open();
// WRITE MY TABLES IN PORTRAIT
document.close();

Document documentLandscape = new Document(PageSize.A4.rotate(), 48, 65, 71, 48);
PdfWriter writerLandscape = PdfWriter.getInstance(documentLandscape, baosLandscape);
documentLandscape.open();
// WRITE MY TABLES IN LANDSCAPE
documentLandscape.close();

PdfReader reader = new PdfReader(baos.toByteArray());
List bookmarks = SimpleBookmark.getBookmark(reader);
copier.addDocument(reader);

PdfReader readerLandscape = new PdfReader(baosLandscape.toByteArray());
List bookmarksLandscape = SimpleBookmark.getBookmark(readerLandscape);
copier.addDocument(readerLandscape);

// HERE IT IS WHERE I CORRECT THE DELAY FOR THE LANDSCAPE BOOKMARKS
SimpleBookmark.shiftPageNumbers(bookmarksLandscape, reader.getNumberOfPages()-1, null);
bookmarks.addAll(bookmarksLandscape);

copier.setOutlines(bookmarks);
copier.close();

return baosTotal;

But, as I mentioned before, it is not exactly one page, and in the end the bookmarks are not as exact as I would like.

Have any of you faced this problem before? Any solution for that? Or am I doing something wrong?

Thanks in advance!

P.S.: I forgot to mention that I am generating the bookmarks by creating a Chapter and Sections (a bookmark is generated per each Section) inside it and, finally, adding the Chapter to the Document:

  Paragraph titulo = new Paragraph("TITLE", myTitleFont);
  titulo.setSpacingAfter(20f);
  Chapter chapter = new Chapter(titulo, 5);
  chapter.setNumberDepth(0);
  Section section = null;

  for(int i = 0; i < MAX; i++){
    Paragraph tableName = new Paragraph("Table " + i, myFont);
    section = chapter.addSection(10f, tableName, i);
    section.setNumberDepth(0);

    // GENERATE eventsTable

    eventsTable.setSpacingBefore(10f);
    eventsTable.setSpacingAfter(20f);
    section.add(eventsTable);

    section.newPage();
    section.setComplete(true);
  }

  chapter.setComplete(true);
  document.add(chapter);

Upvotes: 1

Views: 212

Answers (1)

ggkmath
ggkmath

Reputation: 4246

@Gayolomao, not sure if this helps, but I just ran into a similar problem. When I set a bookmark on a landscape page (located after a portrait page), it shows up one page later.

Here's how I set bookmarks for portrait page, which works great for portrait pages (although, when used for a landscape page, the bookmark shows up on the start of the 2nd landscape page):

document.newPage();
sect = "Chapter 1 Title";
sectionBookmark=new PdfOutline(root, new PdfDestination(PdfDestination.FITH, writer.getVerticalPosition(true)), sect);
document.add(new Paragraph(LEAD, sect, styleChapterTitle));

and here's how I modified it to get bookmark at top of the first landscape page located after a portrait page:

document.setPageSize(PageSize.A4.rotate());  // landscape
document.newPage();
sect="Chapter 2 Title";
sectionBookmark=new PdfOutline(root, new PdfDestination(PdfDestination.FITH,0),sect); // use 0 on landscape pages to trigger bookmark at top of page
document.add(new Paragraph(LEAD, sect, styleChapterTitle));

Upvotes: 1

Related Questions