2013-04-16 115 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的鏈接以瞭解執行此操作的替代方法。 –