Reorder pages in a pdf file using itextsharp

ε祈祈猫儿з 提交于 2019-12-03 22:28:38

Whenever you use iTextSharp to write something you need to create a new document, it will never write to an existing document. In your case, page reordering would require writing so you need create a new document, bring over the pages and then reorder them. (Of course, you could also just reorder them upon import, too.)

        var inputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");
        var output = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Output.pdf");

        //Bind a reader to our input file
        var reader = new PdfReader(inputFile);

        //Create our output file, nothing special here
        using (FileStream fs = new FileStream(output, FileMode.Create, FileAccess.Write, FileShare.None)) {
            using (Document doc = new Document(reader.GetPageSizeWithRotation(1))) {
                //Use a PdfCopy to duplicate each page
                using (PdfCopy copy = new PdfCopy(doc, fs)) {
                    doc.Open();
                    copy.SetLinearPageMode();
                    for (int i = 1; i <= reader.NumberOfPages; i++) {
                        copy.AddPage(copy.GetImportedPage(reader, i));
                    }
                    //Reorder pages
                    copy.ReorderPages(new int[] { 2, 1 });
                    doc.Close();
                }
            }
        }
Jim G.

From @Mathew Leger's answer:

An option for trimming pages is to use the PdfReader.SelectPages() combined with PdfStamper. I wrote the code below with iTextSharp 5.5.1.

public void SelectPages(string inputPdf, string pageSelection, string outputPdf)
{
    using (PdfReader reader = new PdfReader(inputPdf))
    {
        reader.SelectPages(pageSelection);

        using (PdfStamper stamper = new PdfStamper(reader, File.Create(outputPdf)))
        {
            stamper.Close();
        }
    }
}

Then you just have to call this method with the correct page selection for each condition.

Condition 1:

SelectPages(inputPdf, "1-4", outputPdf);

Condition 2:

SelectPages(inputPdf, "1-4,6", outputPdf);

or

SelectPages(inputPdf, "1-6,!5", outputPdf);

Condition 3:

SelectPages(inputPdf, "1-5", outputPdf);

Here's the comment from the iTextSharp source code on what makes up a page selection. This is in the SequenceList class which is used to process a page selection:

/**
* This class expands a string into a list of numbers. The main use is to select a
* range of pages.
* <p>
* The general systax is:<br>
* [!][o][odd][e][even]start-end
* <p>
* You can have multiple ranges separated by commas ','. The '!' modifier removes the
* range from what is already selected. The range changes are incremental, that is,
* numbers are added or deleted as the range appears. The start or the end, but not both, can be ommited.
*/
Jim G.

@Chris Haas' answer is good, but it's not the only way.

Here was my situation:

  1. I first generated a document with XMLWorker and a Razor view.
  2. Then I appended zero-to-many images, each as their own page.
  3. The customer wanted to reorder the document so that the image pages would follow page 1 (i.e. As pages 2, 3, 4, etc.).

Here was the code that I used to do this:

    private static void MoveImagesToPage2(ICollection imagesToBePrintedOnSeparatePages, IDocListener pdfDocument, PdfWriter pdfWriter)
    {
        pdfDocument.NewPage(); // required - http://itextpdf.com/examples/iia.php?id=98

        var numberOfPages = pdfWriter.ReorderPages(null);
        var newOrder = new int[numberOfPages];
        newOrder[0] = 1; // Keep page 1 as page 1

        var i = 1;
        for (var j = imagesToBePrintedOnSeparatePages.Count - 1; 0 <= j; j--)
        {
            newOrder[i] = numberOfPages - j;
            i++;
        }

        for (; i < numberOfPages; i++)
        {
            newOrder[i] = i - (imagesToBePrintedOnSeparatePages.Count - 1);
        }

        pdfWriter.ReorderPages(newOrder);
    }

Please be mindful of this line:

pdfDocument.NewPage(); // required - http://itextpdf.com/examples/iia.php?id=98

This line is necessary if you want to move the last page in the document. (I have no idea why.)

But if it's necessary, then you'll need this line to delete the blank page after you're done:

    private static byte[] RemoveTheLastPageWhichWasAddedForReordering(byte[] renderedBuffer)
    {
        var originalPdfReader = new PdfReader(renderedBuffer);

        using (var msCopy = new MemoryStream())
        {
            using (var docCopy = new Document())
            {
                using (var copy = new PdfCopy(docCopy, msCopy))
                {
                    docCopy.Open();
                    for (var pageNum = 1; pageNum <= originalPdfReader.NumberOfPages - 1; pageNum++)
                    {
                        copy.AddPage(copy.GetImportedPage(originalPdfReader, pageNum));
                    }
                    docCopy.Close();
                }
            }

            return msCopy.ToArray();
        }
    }

Special thanks to @Craig Howard for the snippet above.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!