How to reorder the pages of a PDF file?

Tags: PdfStamperselectPagesreorder pagesiText 5

I am generating Table of Contents after creating a document and I want to move Table of Contents to the start of the document. Suppose that I have 16 pages in my PDF and that the TOC starts from page 13 and ends on page 15. I want to move the TOC to the second page, so that the first page remains page 1 and the last page remains page 16. This code doesn't give me what I want:

public void changePagesOrder() {
    try {
        PdfReader sourcePDFReader = new PdfReader(RESULT1);    
        int n = sourcePDFReader.getNumberOfPages();
        System.out.println("no of pages in pdf files..."+n);
        int totalNoPages=n;
        int tocStartsPage=13;
        sourcePDFReader.selectPages(String.format("%d-%d, 2-%d",
            tocStartsPage, totalNoPages-1, tocStartsPage -2));
        PdfStamper stamper = new PdfStamper(sourcePDFReader,
            new FileOutputStream(RESULT2));
        stamper.close();
    }
    catch(Exception ex) { }
}
Posted on StackOverflow on Jun 18, 2015 by Surya Rawat

Your formula is wrong. You have:

sourcePDFReader.selectPages(String.format("%d-%d, 2-%d",
    tocStartsPage, totalNoPages-1, tocStartsPage -2);

But that puts your TOC at page 1. That is not what you want according to your description.

You want something like this:

PdfReader reader = new PdfReader(baos.toByteArray());
int startToc = 13;
int n = reader.getNumberOfPages();
reader.selectPages(String.format("1,%s-%s, 2-%s, %s",
    startToc, n-1, startToc - 1, n));
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();

This code was tested using the ReorderPages example on a PDF with 16 pages, having the text Page 1, Page 2, ..., Page 16 as content. The result was the following PDF: reordered.pdf

The pages are now in this order: page 1, page 13, page 14, page 15, page 2, page 3, page 4, page 5, page 6, page 7, page 8, page 9, page 10, page 11, page 12, page 16. This is the order you described in your question.

It's working! Thanks a lot. I just want to say, I am working on iText for the last two months and I found it very interesting. One small extra question: I want to understand how the string formatter is working in this case.

You want to know how String.format() worked in this case. Let's look at what we want to achieve first. We have pages in this order:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16

We want to reorder them like this:

1, 13, 14, 15, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 16

This means that we need this pattern:

1, 13-15, 2-12, 16

This is a hard-coded pattern, where two variables are important:

  • The start of the TOC: page 13 (startToc)

  • The final page: 16 (n)

From these variables, we derive two more variables:

  • The last page of the TOC. This is the last page minus one, or 16 - 1 = 15 (n - 1)

  • The last page before the TOC: 13 - 1 = 12 (startToc - 1)

We can now rewrite the pattern like this:

1, startToc-(n - 1), 2-(startToc - 1), n

We need to make this a String, so that's why we use String.format():

String.format("1,%s-%s, 2-%s, %s", startToc, n-1, startToc - 1, n)

The first occurrence of %s is replaced by the first parameter after the String, the second occurrence of %s is replaced by the second parameter after the String, and so on...

If startToc = 13 and n = 16, this results in:

1, 13-15, 2-12, 16

Further reading: How to reorder pages in an existing PDF file?