2013-04-16 110 views
2

我想在另一个PDF页面中插入PDF页面。我想为此使用iTextSharp。将PDF插入PDF(不合并文件)

我有一个矢量图可以导出为单页PDF文件。我想将此文件添加到其他PDF文档的页面中,就像我将图像添加到PDF文档一样。

这可能吗?

这样做的目的是保留放大而不丢失质量的能力。

使用PDF矢量重现矢量图非常困难,因为它是一个非常复杂的图。

将矢量绘图导出为高分辨率图像不是一种选择,因为我必须在单个PDF文档中使用它们中的很多。最终的PDF会非常大,写得太慢。

回答

8

虽然有很多方法可以解决这个问题,但这样做相对容易。如果你正在创建一个包含其他文档的新文档,那么最简单的方法就是使用PdfWriter.GetImportedPage(PdfReader, Int)。这会给你一个PdfImportedPage(从PdfTemplate继承)。一旦你有了,你可以使用PdfWriter.DirectContent.AddTemplate(PdfImportedPage, Matrix)将它添加到你的新文档中。

AddTemplate()有一些重载,但最简单的一个(至少对我来说)是需要System.Drawing.Drawing2D.Matrix的那个。如果你使用这个,你可以轻松地缩放和翻译(改变x,y),而不必用“矩阵”术语思考。

以下是显示此功能的示例代码。它的目标是iTextSharp 5.4.0,但如果删除using语句,它应该与4.1.6几乎相同。它首先创建一个带有12页随机背景颜色的样本PDF。然后,它创建第二个文档,并将第一个PDF中的每个页面按50%缩放,以使4个旧页面适合1个新页面。查看代码评论以获取更多详细信息。此代码假定所有页面大小相同,如果情况不同,则可能需要执行进一步的计算。

//Test files that we'll be creating 
var file1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File1.pdf"); 
var file2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File2.pdf"); 

//For test purposes we'll fill the pages with a random background color 
var R = new Random(); 

//Standard PDF creation, nothing special here 
using (var fs = new FileStream(file1, FileMode.Create, FileAccess.Write, FileShare.None)) { 
    using (var doc = new Document()) { 
     using (var writer = PdfWriter.GetInstance(doc, fs)) { 
      doc.Open(); 

      //Create 12 pages with text on each one 
      for (int i = 1; i <= 12; i++) { 
       doc.NewPage(); 

       //For test purposes fill the page with a random background color 
       var cb = writer.DirectContentUnder; 
       cb.SaveState(); 
       cb.SetColorFill(new BaseColor(R.Next(0, 256), R.Next(0, 256), R.Next(0, 256))); 
       cb.Rectangle(0, 0, doc.PageSize.Width, doc.PageSize.Height); 
       cb.Fill(); 
       cb.RestoreState(); 

       //Add some text to the page 
       doc.Add(new Paragraph("This is page " + i.ToString())); 
      } 
      doc.Close(); 
     } 
    } 
} 

//Create our combined file 
using (var fs = new FileStream(file2, FileMode.Create, FileAccess.Write, FileShare.None)) { 
    using (var doc = new Document()) { 
     using (var writer = PdfWriter.GetInstance(doc, fs)) { 

      //Bind a reader to the file that we created above 
      using (var reader = new PdfReader(file1)) { 
       doc.Open(); 

       //Get the number of pages in the original file 
       int pageCount = reader.NumberOfPages; 

       //Loop through each page 
       for (int i = 0; i < pageCount; i++) { 
        //We're putting four original pages on one new page so add a new page every four pages 
        if (i % 4 == 0) { 
         doc.NewPage(); 
        } 

        //Get a page from the reader (remember that PdfReader pages are one-based) 
        var imp = writer.GetImportedPage(reader, (i + 1)); 
        //A transform matrix is an easier way of dealing with changing dimension and coordinates on an rectangle 
        var tm = new System.Drawing.Drawing2D.Matrix(); 

        //Scale the image by half 
        tm.Scale(0.5f, 0.5f); 

        //PDF coordinates put 0,0 in the bottom left corner. 
        if (i % 4 == 0) { 
         tm.Translate(0, doc.PageSize.Height);     //The first item on the page needs to be moved up "one square" 
        } else if (i % 4 == 1) { 
         tm.Translate(doc.PageSize.Width, doc.PageSize.Height); //The second needs to be moved up and over 
        } else if (i % 4 == 2) { 
                       //Nothing needs to be done for the third 
        } else if (i % 4 == 3) { 
         tm.Translate(doc.PageSize.Width, 0);     //The fourth needs to be moved over 
        } 

        //Add our imported page using the matrix that we set above 
        writer.DirectContent.AddTemplate(imp,tm); 

       } 

       doc.Close(); 
      } 
     } 
    } 
} 
+0

对。这是一个用例,其中一个文档的页面应该使用'PdfWriter'而不是'Pdf * Copy *'类中的一个导入到另一个文档中。 [如何合并多个pdf文件(在运行时生成)?](http://stackoverflow.com/a/15945467/1729265) – mkl

+0

@Chris Hass的答案。感谢您的出色回放,我也在其他问题上阅读了您的回复,并且我发现它们对于这一点很有帮助。再次感谢。 – user1106088

+0

此外,为了避免其他人在将来阅读此内容,上面的代码适用于基本的简单PDF。如果有任何表单域,注释,书签等(基本上不是文本,行和图像),请务必阅读@ mkl的链接以了解执行此操作的替代方法。 –