我正在尝试重新排序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);
}
答案 0 :(得分:3)
每当您使用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();
}
}
}
答案 1 :(得分:1)
修剪页面的选项是将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.
*/
答案 2 :(得分:0)
@Chris Haas' answer很好,但这不是唯一的方法。
以下是我的情况:
XMLWorker
和Razor视图生成了一个文档。以下是我用来执行此操作的代码:
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();
}
}