繁体   English   中英

使用itextsharp重新排序pdf文件中的页面

[英]Reorder pages in a pdf file using itextsharp

我正在尝试重新排序PDF文件中的多个页面。 我在博客中找到了一些代码但却无法使用它。 我有两页pdf,我想让最后一页显示为第一页。 我总是得到一个例外,说页码必须与订单匹配。 当我检查文档对象时,它显示0页。 但传入的PDF有两页。

public void reOrder(string inputFile)
{ 
    Document document = new Document();
    FileStream fs = new FileStream(inputFile, FileMode.Open);
    PdfWriter writer = PdfWriter.GetInstance(document, fs);
    document.AddDocListener(writer);                
    writer.SetLinearPageMode();
    int[] order = {2,1};
    writer.ReorderPages(order);
}

每当您使用iTextSharp编写需要创建新文档的内容时,它都不会写入现有文档。 在您的情况下,页面重新排序需要编写,因此您需要创建一个新文档,将页面重新排序然后重新排序。 (当然,您也可以在导入时重新排序它们。)

        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();
                }
            }
        }

来自@Mathew Leger的回答

修剪页面的选项是使用PdfReader.SelectPages()与PdfStamper结合使用。 我用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();
        }
    }
}

然后,您只需使用每个条件的正确页面选择调用此方法。

条件1:

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

条件2:

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

要么

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

条件3:

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

以下是关于构成页面选择的iTextSharp源代码的注释。 这是在SequenceList类中,用于处理页面选择:

/**
* 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.
*/

@Chris Haas的答案很好,但这不是唯一的方法。

这是我的情况:

  1. 我首先使用XMLWorker和Razor视图生成了一个文档。
  2. 然后我添加了零对多的图像,每个图像都是他们自己的页面。
  3. 客户想要对文档重新排序,以使图像页面跟随第1页(即第2,3,4页等)。

以下是我用来执行此操作的代码:

    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);
    }

请注意这一行:

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

如果要移动文档中的最后一页,则必须使用此行。 我不知道为什么。

但如果有必要,那么在完成后你需要这一行来删除空白页面:

    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();
        }
    }

特别感谢@Craig Howard 上面的片段

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM