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

我正在尝试重新排序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. * 

* The general systax is:
* [!][o][odd][e][even]start-end *

* 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 上面的片段 。