I am generating Table of Contents at last,I want to move Table of Contents at Beginning.
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();
System.out.println("pdf changes are done.....");
}
catch(Exception ex) {
}
}
Please suggest some solutions.
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 ReorderPage 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)[http://itextpdf.com/sites/default/files/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.
Update:
In a comment, you were asking 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
You can select the pages readed by PdfReader:
PdfReader sourcePDFReader = new PdfReader(RESULT1);
reader.selectPages("1-13");
Then you can use PdfStamper or PdfCopy to assemble then in order.
Please refer to:
Itext Documentation, Related question
Edit: This is a piece of code i use to put a list of pdf together, maybe it's helpful to you. (You could read pages 15-16, save to pdf and then repeat with pages 1-13. Then combine the two resulting pdfs)
private byte[] combinePdf(List<byte[]> archivos) throws DocumentException,
IOException {
ByteArrayOutputStream osPdf = new ByteArrayOutputStream();
com.itextpdf.text.Document document = new com.itextpdf.text.Document();
PdfWriter writer = PdfWriter.getInstance(document, osPdf);
document.open();
PdfContentByte cb = writer.getDirectContent();
for (byte[] in : archivos) {
PdfReader reader = new PdfReader(in);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
document.newPage();
PdfImportedPage page = writer.getImportedPage(reader, i);
cb.addTemplate(page, 0, 0);
}
}
osPdf.flush();
document.close();
return osPdf.toByteArray();
}
Edit 2: as Bruno posted, this is a bad solution because all the pdf links are lost using the document/ pdfWritter combination.