2012-07-02 8 views
1

Я пытаюсь переупорядочить несколько страниц в файле PDF. Я нашел код в блоге, но не смог заставить его работать. У меня есть двухстраничный pdf-файл, и я хочу, чтобы последняя страница отображалась как первая. Я всегда получаю исключение, говоря, что номер страницы должен совпадать с порядком. Когда я проверил объект документа, он отображает 0 страниц. Но PDF-файл имеет две страницы.Переупорядочить страницы в pdf-файле, используя itextsharp

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

ответ

2

Всякий раз, когда вы используете 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(); 
       } 
      } 
     } 
0

@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.

1

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

Тогда вам просто нужно вызвать этот метод с правильным выбором страницы для каждого условия.

Условие 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. 
*/ 
Смежные вопросы