使用itextsharp将页面插入现有的PDF文件

6
我们正在使用itextsharp将多个PDF文件合并成一个单独的PDF。如果要在已有多页的PDF文件中插入新页面,应该怎么做呢?当我使用add page时,它会覆盖现有的页面,并且只保存了所选的第一页。
以下是我用于将页面添加到现有PDF的代码:
PdfReader reader = new PdfReader(sourcePdfPath);
                Document document = new Document(reader.GetPageSizeWithRotation(1));
                PdfCopy pdfCopy = new PdfCopy(document, new System.IO.FileStream(outputPdfPath, System.IO.FileMode.Create));
                MemoryStream memoryStream = new MemoryStream();
                PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
                document.AddDocListener(writer);
                document.Open();

                for (int p = 1; p <= reader.NumberOfPages; p++)
                {
                    if (pagesToExtract.FindIndex(s => s == p) == -1) continue;
                    document.SetPageSize(reader.GetPageSize(p));
                    document.NewPage();
                    PdfContentByte cb = writer.DirectContent;
                    PdfImportedPage pageImport = writer.GetImportedPage(reader, p);

                    int rot = reader.GetPageRotation(p);
                    if (rot == 90 || rot == 270)
                    {
                        cb.AddTemplate(pageImport, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(p).Height);
                    }
                    else
                    {
                        cb.AddTemplate(pageImport, 1.0F, 0, 0, 1.0F, 0, 0);
                    }

                    pdfCopy.AddPage(pageImport);
                }

                pdfCopy.Close();
6个回答

6
这段代码是可行的。你需要使用另一个文件来输出结果。
private static void AppendToDocument(string sourcePdfPath1, string sourcePdfPath2, string outputPdfPath)
{
    using (var sourceDocumentStream1 = new FileStream(sourcePdfPath1, FileMode.Open))
    {
        using (var sourceDocumentStream2 = new FileStream(sourcePdfPath2, FileMode.Open))
        {
            using (var destinationDocumentStream = new FileStream(outputPdfPath, FileMode.Create))
            {
                var pdfConcat = new PdfConcatenate(destinationDocumentStream);
                var pdfReader = new PdfReader(sourceDocumentStream1);

                var pages = new List<int>();
                for (int i = 0; i < pdfReader.NumberOfPages; i++)
                {
                    pages.Add(i);
                }

                pdfReader.SelectPages(pages);
                pdfConcat.AddPages(pdfReader);

                pdfReader = new PdfReader(sourceDocumentStream2);

                pages = new List<int>();
                for (int i = 0; i < pdfReader.NumberOfPages; i++)
                {
                    pages.Add(i);
                }

                pdfReader.SelectPages(pages);
                pdfConcat.AddPages(pdfReader);

                pdfReader.Close();
                pdfConcat.Close();
            }
        }
    }
}

2
这段代码可以工作,只需要修复一个小错误就行。需要将 for (int i = 0; i < pdfReader.NumberOfPages; i++) 改为 for (int i = 0; i <= pdfReader.NumberOfPages; i++) 两处都需要修改。 - Radenko Zec

3

我已经尝试过这段代码,它对我有效,但不要忘记验证所使用的路径的页面数量和存在性。

以下是代码:

private static void AppendToDocument(string sourcePdfPath, string outputPdfPath, List<int> neededPages)
    {

        var sourceDocumentStream = new FileStream(sourcePdfPath, FileMode.Open);
        var destinationDocumentStream = new FileStream(outputPdfPath, FileMode.Create);
        var pdfConcat = new PdfConcatenate(destinationDocumentStream);

        var pdfReader = new PdfReader(sourceDocumentStream);
        pdfReader.SelectPages(neededPages);
        pdfConcat.AddPages(pdfReader);

        pdfReader.Close();
        pdfConcat.Close();
    }

2
你可以使用以下代码片段,其中src是输入PDF文件名的IEnumerable<string>。请确保您现有的PDF文件是这些来源之一。 PdfConcatenate类在最新的iTextSharp发行版中。
var result = "combined.pdf";
var fs = new FileStream(result, FileMode.Create);
var conc = new PdfConcatenate(fs, true);
foreach(var s in src) {
    var r = new PdfReader(s);
    conc.AddPages(r);
}
conc.Close();

我正在尝试从源PDF中获取特定页面并将它们添加到现有的PDF中。唯一的问题是它没有将其添加到现有的PDF中,而是仅覆盖它。 - Rob Banton
@Rob:出于某种原因,我没有从原始问题中得到这个。你的问题是否可以重新表述为需要将源文档中的某些(包括所有)页面合并成一个单独的文件?这意味着现有的PDF成为那些需要的所有页面之一? - Sergei Z

1

需要将页面数量调整为4的倍数:

private static void AppendToDocument(string sourcePdfPath)
{
    var tempFileLocation = Path.GetTempFileName();
    var bytes = File.ReadAllBytes(sourcePdfPath);

    using (var reader = new PdfReader(bytes))
    {
        var numberofPages = reader.NumberOfPages;
        var modPages = (numberofPages % 4);
        var pages = modPages == 0 ? 0 : 4 - modPages;

        if (pages == 0)
            return;

        using (var fileStream = new FileStream(tempFileLocation, FileMode.Create, FileAccess.Write))
        {
            using (var stamper = new PdfStamper(reader, fileStream))
            {
                var rectangle = reader.GetPageSize(1);
                for (var i = 1; i <= pages; i++)
                    stamper.InsertPage(numberofPages + i, rectangle);
            }
        }
    }

    File.Delete(sourcePdfPath);
    File.Move(tempFileLocation, sourcePdfPath);
}

1
PdfCopy适用于空白的Document。您应该每次添加一页来添加您想要的内容。
另一种选择是使用PdfStamper.InsertPage(pageNum, rectangle),然后在新页面上绘制一个PdfImportedPage
请注意,PdfImportedPage仅包含页面内容,而不包括注释或文档级别信息(“文档结构”,文档级JavaScript等),除非您使用带有PdfCopy的页面。
Stamper可能更高效并且使用的代码更少,但PdfCopy将导入所有页面级别信息,而不仅仅是页面内容。
这可能很重要,也可能不重要。这取决于您要导入哪个页面。

这个答案完美地解决了我的问题!我需要在现有的PDF中添加 n 个空白页面。使用 PdfStamper.InsertPage 就可以实现。谢谢! - user1229323

0

我知道我来晚了,但我混合了最好的两个答案,创建了一种方法,如果有人需要,它可以使用itextsharp将源PDF文档列表添加到单个文档中。

private static void appendToDocument(List<string> sourcePDFList, string outputPdfPath)
{
    //Output document name and creation
    FileStream destinationDocumentStream = new FileStream(outputPdfPath, FileMode.Create);
     //Object to concat source pdf's to output pdf
     PdfConcatenate pdfConcat = new PdfConcatenate(destinationDocumentStream);

     //For each source pdf in list...
     foreach (string sourcePdfPath in sourcePDFList)
     {
         //If file exists...
         if (File.Exists(sourcePdfPath))
         {
             //Open the document
             FileStream sourceDocumentStream = new FileStream(sourcePdfPath, FileMode.Open);
             //Read the document
             PdfReader pdfReader = new PdfReader(sourceDocumentStream);

             //Create an int list
             List<int> pages = new List<int>();
             //for each page in pdfReader
             for (int i = 1; i < pdfReader.NumberOfPages + 1; i++)
             {
                 //Add that page to the list
                 pages.Add(i);
             }

             //Add that page to the pages to add to ouput document
             pdfReader.SelectPages(pages);
             //Add pages to output page
             pdfConcat.AddPages(pdfReader);

             //Close reader
             pdfReader.Close();
         }
     }

    //Close pdfconcat
    pdfConcat.Close();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接