當 PDF 內容跨頁較長,單純在產生時設定背景圖往往導致後續頁面變成空白。本文提供兩種成熟方案:iTextSharp(開源)與 Spire.PDF Free(商業免費版),分別示範如何對「已存在的 PDF」逐頁疊加背景圖片,解決跨頁背景遺失問題。
核心邏輯:PdfReader 讀取原檔 → PdfStamper 建立輸出流 → 逐頁取得 GetUnderContent(頁面最底層) → AddImage 疊加 → 關閉流完成。
public void SetPdfBackgroundWithITextSharp(string srcPath, string destPath, string imgPath)
{
using (FileStream fs = new FileStream(destPath, FileMode.Create, FileAccess.ReadWrite))
using (PdfReader reader = new PdfReader(srcPath))
using (PdfStamper stamper = new PdfStamper(reader, fs))
{
// 載入圖片並固定在 (0,0)
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imgPath);
img.SetAbsolutePosition(0, 0);
int total = reader.NumberOfPages;
for (int page = 1; page <= total; page++)
{
PdfContentByte canvas = stamper.GetUnderContent(page); // 底層
// 若需保留原內容可選擇 GetOverContent(page) 疊在最上層
canvas.AddImage(img);
}
// stamper.Close() 會自動關閉 reader 與 fs
}
}
GetUnderContent 將圖片置於現有內容之下;若需浮水印效果(置於內容之上),改用 GetOverContent。SetAbsolutePosition(0,0) 以頁面左下角為原點;若 PDF 頁面尺寸不一,建議先讀取 reader.GetPageSize(page) 計算置中座標。E-iceblue 提供的免費版支援 PdfPageBase.BackgroundImage 屬性,幾行程式碼即可完成:
using System.Drawing;
using Spire.Pdf;
public void SetPdfBackgroundWithSpire(string srcPath, string destPath, string imgPath)
{
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(srcPath);
Image bg = Image.FromFile(imgPath);
foreach (PdfPageBase page in doc.Pages)
page.BackgroundImage = bg; // 自動套用至每頁
doc.SaveToFile(destPath);
// Process.Start(destPath); // 如需自動開啟
}
| 項目 | iTextSharp | Spire.PDF Free |
|---|---|---|
| 授權 | LGPL/MPL (5.x) / AGPL (7.x) | 免費版含浮水印與頁數限制 |
| API 層級 | 底層操作,彈性高 | 高層封裝,語法簡潔 |
| 跨頁背景 | 手動迴圈控制 | 自動套用全文件 |
| 相依性 | 單一 DLL,無額外相依 | 需引用 Spire.Pdf.dll + Spire.License.dll |
| 中文支援 | 需額外註冊字體 | 內建較好 |
MediaBox。iTextSharp 方案建議在迴圈內依頁面大小縮放圖片:img.ScaleToFit(pageSize.Width, pageSize.Height);img.SetAbsolutePosition((pageSize.Width - img.ScaledWidth)/2, (pageSize.Height - img.ScaledHeight)/2);GetOverContent 疊加半透明圖層。Parallel.ForEach 或 Task.Run 進行平行處理,注意 PdfReader 非執行緒安全,每執行緒需獨立實例。using 區塊確保 PdfStamper/PdfDocument 正確 Dispose,避免檔案鎖定。class Program
{
static void Main(string[] args)
{
string src = @"sample.pdf";
string dest = @"result.pdf";
string bg = @"background.png";
// 任選一種
// SetPdfBackgroundWithITextSharp(src, dest, bg);
SetPdfBackgroundWithSpire(src, dest, bg);
Console.WriteLine("完成!輸出:" + dest);
}
// ... 上述兩個方法置於此處
}
若專案已引用 iTextSharp 且需精細控制疊加層級、座標、縮放,方案一最適合;若追求開發速度、頁數較少且能接受浮水印,方案二幾行代碼即可交付。實際選型請依授權政策、頁數規模與維護成本綜合評估。