【问题标题】:Reorder pages in a pdf file using itextsharp使用 itextsharp 重新排序 pdf 文件中的页面
【发布时间】:2012-07-02 22:38:37
【问题描述】:

我正在尝试重新排序 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);
}

【问题讨论】:

    标签: c# pdf-generation itextsharp


    【解决方案1】:

    每当您使用 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();
                    }
                }
            }
    

    【讨论】:

      【解决方案2】:

      @Chris Haas' answer 很好,但不是唯一的方法。

      这是我的情况:

      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
      

      如果您想移动文档中的最后一页,此行是必需的。 (I have no idea why.)

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

          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 the snippet above

      【讨论】:

        【解决方案3】:

        来自@Mathew Leger's answer

        修剪页面的一个选项是结合使用 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();
                }
            }
        }
        

        然后你只需要为每个条件选择正确的页面来调用这个方法。

        条件一:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-04-24
          相关资源
          最近更新 更多