0

I'm trying to change reorder pages of my PDF document, but i can't and I don't know why.

I read several articals about changing order, it's java(iText) and i have got few problems with it.(exampl1, exampl2, example3). This example on c#, but there is using other method(exampl4)

I want take my TOC on 12 page and put to 2 page. After 12 page I have other content. This is my template for change order of pages:

String.Format("1,%s, 2-%s, %s-%s", toc, toc-1, toc+1, n)

This is my method for changing order of pages:

         public void ChangePageOrder(string path)
    {
        MemoryStream baos = new MemoryStream();

        PdfReader sourcePDFReader = new PdfReader(path);
        int toc = 12;
        int n = sourcePDFReader.NumberOfPages;
        sourcePDFReader.SelectPages(String.Format("1,%s, 2-%s, %s-%s", toc, toc-1, toc+1, n));

        using (var fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
            {
                PdfStamper stamper = new PdfStamper(sourcePDFReader, fs);
                stamper.Close();
            }
    }

Here is call to method:

  ...
  doc.Close();

  ChangePageOrder(filePath);

What am I doing not right?

Thank you.

Community
  • 1
  • 1
Naomiss
  • 167
  • 4
  • 14

2 Answers2

1

Your code can't work because you are using path to create the PdfReader as well as to create the FileStream. You probably get an error such as "The file is in use" or "The file can't be accessed".

This is explained here:

You create a MemoryStream() named baos, but you aren't using that object anywhere. One way to solve your problem, is to replace the FileStream when you first create your PDF by that MemoryStream, and then use the bytes stored in that memory stream to create a PdfReader instance. In that case, PdfStamper won't be writing to a file that is in use.

Another option would be to use a different path. For instance: first you write the document to a file named my_story_unordered.pdf (created by PdfWriter), then you write the document to a file named my_story_reordered.pdf (created by PdfStamper).

It's also possible to create the final document in one go. In that case, you need to switch to linear mode. There's an example in my book "iText in Action - Second Edition" that shows how to do this: MovieHistory1

In the C# port of this example, you have:

writer.SetLinearPageMode();

In normal circumstances, iText will create a page tree with branches and leaves. As soon a a branch has more than 10 leaves, a new branch is created. With setLinearPageMode(), you tell iText not to do this. The complete page tree will consist of one branch with nothing but leaves (no extra branches). This is bad from the point of view of performance when viewing the document, but it's acceptable if the number of pages in your document is limited.

Once you've switched to page mode, you can reorder the pages like this:

document.NewPage();
// get the total number of pages that needs to be reordered
int total = writer.ReorderPages(null);
// change the order
int[] order = new int[total];
for (int i = 0; i < total; i++) {
  order[i] = i + toc;
  if (order[i] > total) {
    order[i] -= total;
  }
}
// apply the new order
writer.ReorderPages(order);

Summarized: if your document doesn't have many pages, use the ReorderPages method. If your document has many pages, use the method you've been experimenting with, but do it correctly. Don't try to write to the file that you are still trying to read.

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • I try to use `ReorderPages`, but document is becoming damaged. What is wrong? I copied your code and put it's after creating toc . – Naomiss Aug 26 '16 at 14:32
  • The example shared on the web site works; don't expect anyone to be able to answer your question "what is wrong?" You assume that people can see what you're doing. That's not true. From all your questions so far, I only know that you are not a developer. You just copy/paste code from other people without understanding what you are doing. I think that's your biggest mistake. I don't think anyone but you can fix this. You need to grow a better work attitude and strive to be smarter. – Bruno Lowagie Aug 26 '16 at 14:46
  • Thank you for your critic. I will be trying to become better. – Naomiss Aug 30 '16 at 08:08
0

Without going into details about what you should do you can loop through all pages from a pdf, put them into a new pdf doc with all the pages. You can put your logic inside the for loop.

reader = new PdfReader(sourcePDFpath);
sourceDocument = new Document(reader.GetPageSizeWithRotation(startpage));
pdfCopyProvider = new PdfCopy(sourceDocument, new System.IO.FileStream(outputPDFpath, System.IO.FileMode.Create));

sourceDocument.Open();

for (int i = startpage; i <= endpage; i++)
{
    importedPage = pdfCopyProvider.GetImportedPage(reader, i);
    pdfCopyProvider.AddPage(importedPage);
}
sourceDocument.Close();
reader.Close();
pmeyer
  • 890
  • 7
  • 31