該頁面可以包含自動翻譯的文字。
在 C# 中編輯 PDF
使用 Docotic.Pdf 來修改您的 PDF 文件。這是適用於 C# 和 VB.NET 的 PDF 編輯程式庫,結合了強大功能與直覺式 API。
Docotic.Pdf 提供許多編輯 PDF 文件的方法。以下是此程式庫在 PDF 編輯方面的一些主要功能:
- 將多個 PDF 合併為一個,或將單一 PDF 拆分為多個檔案。
- 縮小 PDF 檔案大小。
- 重新排列、刪除、旋轉或擷取頁面。
- 讀取、變更或刪除 PDF 中繼資料。
- 使用數位簽章簽署 PDF。
- 加密文件或移除 PDF 的密碼。
- 新增、編輯或移除註解與附件。
- 填寫 AcroForms,新增或移除表單控制項。
- 將表單欄位和註解展平,使其成為 PDF 內容的一部分。
- 在 PDF 中新增、刪除或取代文字。
- 插入、取代並調整影像大小。
- 新增浮水印與背景。
- 將掃描文件轉換為可編輯且可搜尋的文字。
接下來的各節將更詳細說明 PDF 編輯功能。這些章節也包含程式碼片段與相關資源的連結。
合併與分割 PDF
本節介紹兩項目標相反的功能。

合併 PDF
當您整合 PDF 檔案時,會建立一份單一 PDF 文件。合併後的 PDF 通常包含來自多個既有 PDF 檔案的相關資訊。
以下程式碼片段示範如何使用 Docotic.Pdf 合併 PDF 檔案。
using var pdf = new PdfDocument("first.pdf");
pdf.Append("second.pdf");
pdf.Save("merged.pdf");
這段程式碼非常簡單,因為它展示的是最基本的情況。我們有一篇文章說明更複雜的合併情境。例如,它示範如何合併已加密的文件。
分割 PDF
分割是指從原始 PDF 擷取選定頁面,以建立一個或多個新的 PDF 檔案。當您只想分享文件的一部分時,這個流程很有用。
以下程式碼片段示範如何從 PDF 的每一頁建立新文件。
using var pdf = new PdfDocument("compound.pdf");
for (int i = 0; i < pdf.PageCount; ++i)
{
using PdfDocument copy = pdf.CopyPages(i, 1);
// 有助於在複製的頁面參照
// 未使用的資源,例如字型、影像、樣式時,縮小檔案大小。
copy.RemoveUnusedResources();
copy.Save(i + ".pdf");
}
請閱讀專門文章,了解其他實作 PDF 分割器的方法。
PDF 壓縮
壓縮 PDF 時有兩種主要方法。第一種只套用不會改變檔案內容、只改變其形式的操作。第二種則還包含可能造成細節損失或文件品質下降、但能獲得更佳壓縮效果的變更。
無損 PDF 壓縮
預設情況下,程式庫會以較少位元組的方式儲存 PDF 物件。為此,它會排除未使用的物件、以無格式寫入物件,並在可能時使用較短的表示形式。
為了進一步改善壓縮效果,Docotic.Pdf 也會在輸出 PDF 中產生物件流。這是另一種以最精簡表示法寫入物件的方式。物件流會使用 Flate 演算法壓縮。
您可以使用儲存選項影響程式庫儲存物件的方式。
有些文件包含重複的字型、影像、色彩設定檔與其他物件。這通常發生在增量更新的文件,以及透過合併多份文件建立的檔案。使用 PdfDocument.ReplaceDuplicateObjects 方法對這些物件去重,能大幅減少輸出大小。
文件的頁面可能參照到未使用的資源。例如,先前曾在頁面上顯示、但現在已不再使用的影像。使用 PdfDocument.RemoveUnusedResources 方法可移除此類資源。
這些 PDF 操作都能在不損失品質的情況下縮小檔案大小。
有損轉換
對於包含影像的檔案,縮小 PDF 大小最有效的方法之一是變更影像的壓縮方案。例如,對影像使用 JPEG 之類的有損壓縮會減少大小。副作用是,影像上可能會出現壓縮失真與細節損失。
如果 PDF 中的影像比實際需要的大,您可以調整其大小。這甚至可能帶來更好的壓縮效果。另一個選項是將影像轉換為黑白(雙色)。
您可以將表單欄位與註解展平以節省一些空間。當您不再需要文件中的可編輯註解與表單欄位時,這很有用。
字型在文件中可能佔用大量空間。PdfDocument.RemoveUnusedFontGlyphs 方法可移除字型中未使用的字形,以最佳化輸出大小。字型子集化是此流程的另一個名稱。您甚至可以完全移除文件中的字型位元組(取消內嵌字型)。當文件包含像 Arial 這類常見字型的位元組時,這麼做可能很合理。
其他轉換會直接移除文件中的資訊。您可以移除中繼資料、結構資訊與應用程式私有資料。這些資料不可見,但只有在對文件使用者不重要時才應移除。
若要了解更多細節並查看一些程式碼範例,請閱讀如何縮小 PDF 檔案大小文章。
重新排序 PDF 頁面
有充分理由變更 PDF 內頁面的順序。例如,您可能需要將相關資訊分組,或透過確保文件流程符合邏輯來提升可讀性。

除了合併與分割頁面的能力之外,Docotic.Pdf 還提供一組廣泛的其他方法來重新排列 PDF 頁面。我將使用 C# 程式碼片段與 Docotic.Pdf API 展示如何組織 PDF 頁面。
您可以在範例程式碼的 頁面與導覽 群組中找到此節範例的完整測試專案。我在片段中使用 ten-pages.pdf。這是一份簡單的測試文件,每一頁都有 Page N 標題。
移動 PDF 頁面
以下片段示範如何移動連續範圍的頁面。程式碼會將前半部頁面移到文件末尾。
using var pdf = new PdfDocument("ten-pages.pdf");
pdf.MovePages(0, 5, pdf.PageCount);
pdf.Save("continuous-move.pdf");
也可以移動任意一組頁面。以下程式碼會將奇數頁移到文件末尾。
using var pdf = new PdfDocument("ten-pages.pdf");
int[] indexes = [0, 2, 4, 6, 8];
pdf.MovePages(indexes, pdf.PageCount);
pdf.Save("arbitrary-move.pdf");
若只要移動一頁,請使用 PdfDocument.MovePage 方法。
交換 PDF 頁面
若要交換兩頁,請使用下列程式碼。
using var pdf = new PdfDocument("ten-pages.pdf");
pdf.SwapPages(9, 0);
pdf.SwapPages(8, 1);
pdf.Save("swapped.pdf");
PdfDocument.SwapPages 方法接受兩個應交換位置的頁面索引。當頁數不等於兩頁時,請使用其中一個移動頁面方法。
新增與插入頁面
任何 PdfDocument 至少都包含一頁。當您建立新文件時,程式庫會隱含新增一頁。
以下示範如何使用 Docotic.Pdf API 在 PDF 中插入空白頁。您可以在索引從 0 到 PageCount(含)的位置插入頁面。
using var pdf = new PdfDocument();
var newPage = pdf.InsertPage(0);
newPage.Canvas.DrawString("This is the new first page");
pdf.Save("two-pages.pdf");
若要在 PDF 中新增空白頁,請使用 PdfDocument.AddPage 方法。此方法會在文件末尾新增一頁。它與呼叫 pdf.InsertPage(pdf.PageCount) 的效果相同。
若要從其他文件新增或插入頁面,請依照前置 PDF 章節所述,組合多個呼叫。您可以利用這組呼叫為 PDF 新增封面頁。
複製 PDF 頁面
透過程式庫 API,您可以將重複操作分成兩個連續操作。第一個是複製頁面操作。請參閱分割 PDF 章節中的程式碼範例。
第二個是貼上頁面操作。對於此操作,請使用 PdfDocument.Append 方法。接著將附加的頁面移動到所需位置。
擷取頁面
以下片段示範如何從 PDF 擷取頁面。它會從來源文件擷取前三頁。
using var pdf = new PdfDocument("ten-pages.pdf");
using (var extracted = pdf.ExtractPages(0, 3))
{
extracted.RemoveUnusedResources();
extracted.Save("three-pages.pdf");
}
pdf.Save("seven-pages.pdf");
ExtractPages 方法會從文件中移除頁面。因此,來源文件中只剩下七頁。程式庫不允許從只有一頁的文件擷取頁面。
我們建議對含有擷取頁面的文件移除未使用的資源。
從 PDF 移除頁面
請查看以下片段,示範如何在 PDF 文件中刪除頁面。實際上它使用 RemovePage 方法的不同多載刪除了兩頁。第一個多載接受頁面索引作為參數。第二個多載接受頁面物件。
using var pdf = new PdfDocument("ten-pages.pdf");
pdf.RemovePage(0);
pdf.RemovePage(pdf.Pages[0]);
pdf.Save("without-first-two-pages.pdf");
若要一次移除多頁,請使用 PdfDocument.RemovePages 方法。該方法的多載支援頁面索引陣列或頁面物件陣列。
數位簽章
Docotic.Pdf 在 PDF 中實作了許多數位簽章操作,可協助您維持 PDF 文件的可信度與法律效力。以下是此程式庫可執行的一些操作範例:
使用憑證簽署 PDF。在 PDF 中新增數位簽章,是確認簽署者身分並確保簽署後文件未被他人修改的方式。
認證簽章。若要為 PDF 新增額外限制,您可以使用認證簽章簽署它。您可以在簽署後完全鎖定 PDF,或允許少數類型的變更。
驗證 PDF 中的簽章。檢查數位簽章的有效性,以確認文件已簽署部分未變更。
允許多重簽章。合約、協議與表單通常需要多方在單一文件上簽署。對 PDF 新增多個簽章需要文件以增量方式儲存。
嵌入簽章時間戳記。可以在簽署選項中指定時間戳記授權單位 URL,並可選擇提供其認證資訊。程式庫會將收到的時間戳記嵌入簽章。
嵌入憑證。程式庫會自動將簽署憑證嵌入數位簽章。
數位簽章頁面包含範例程式碼與各項操作的更多資訊。
保護 PDF
您可以使用三項功能來確保 PDF 安全性。Docotic.Pdf 可雙向處理它們:此程式庫既可保護 PDF,也可解鎖受保護的 PDF。

密碼保護
此功能可讓您設定密碼以限制對 PDF 的存取。依據密碼類型,PDF 需要正確密碼才能開啟或修改文件。
PDF 中有兩種密碼:
- 開啟密碼(使用者密碼)。此類密碼用於開啟並檢視 PDF。若沒有正確密碼,符合規範的 PDF 檢視器不會開啟該文件。
- 權限密碼(擁有者密碼)。此密碼用於移除 PDF 的權限。使用擁有者密碼開啟 PDF 可允許所有操作,即使權限限制了某些動作,例如列印、複製或編輯 PDF。
您可以為同一份 PDF 文件同時設定兩種密碼。請閱讀解密 PDF 檔案以了解如何移除 PDF 文件的密碼。
加密
PDF 加密與 PDF 密碼會一起運作,以確保 PDF 內的敏感資訊只對合法使用者可用。只有擁有正確解密金鑰或密碼的使用者才能檢視內容。
Docotic.Pdf 可使用 RC4 40 位元、RC4 128 位元、AES 128 位元,以及 AES 256 位元加密演算法來加密 PDF 檔案。
權限與限制
您可以在 PDF 上設定各種權限,例如限制列印、複製文字、編輯文件等。這些權限只會影響使用者密碼開啟 PDF 時的體驗。若以擁有者密碼開啟 PDF,任何限制都不會套用。
若要從 PDF 移除權限,必須先移除 PDF 安全密碼。請閱讀如何使用 C# 與 Docotic.Pdf API執行此操作。
若想了解除了 PDF 安全性之外,如何確保PDF 完整性,請閱讀數位簽章相關章節。
PDF 中繼資料
PDF 中繼資料是嵌入在 PDF 檔案中的資訊,用來提供文件細節。中繼資料主要有兩個來源:PDF 文件屬性與 XMP 中繼資料。
文件屬性也常被稱為文件資訊字典、檔案資訊、中繼資料欄位、文件屬性與檔案屬性。
XMP(Extensible Metadata Platform)中繼資料本質上是嵌入在 PDF 中的 XML 檔案。XMP 使用彈性的資料模型,可儲存任意一組中繼資料屬性。此中繼資料使用命名空間來分組相關屬性。常見的命名空間包括 XMP Core/XMP Basic 與 Dublin Core。
Docotic.Pdf 完整支援 XMP 中繼資料與文件屬性。請注意,PDF 2.0 標準已將大多數文件資訊字典屬性標記為已淘汰。唯一的例外是建立日期與修改日期。
您可以在範例程式碼的 中繼資料群組 中找到此節範例的完整測試專案。
文件屬性
看看如何使用 Docotic.Pdf 編輯文件屬性。
using var pdf = new PdfDocument("file.pdf");
pdf.Info.Author = "An example code";
pdf.Info.Subject = "Showing how to access and change document metadata";
pdf.Info.Title = "Custom title goes here";
pdf.Info.Keywords = "pdf Docotic.Pdf";
pdf.Save("updated-file.pdf");
您可以變更每個屬性的值,但請注意,預設情況下程式庫會在儲存 PDF 前自動更新某些屬性。您可以在儲存選項中變更此行為。
若要移除文件屬性中指定的所有中繼資料,請使用 PdfInfo.Clear 方法。若您願意,該方法也只可移除自訂屬性。
XMP 中繼資料
此片段示範如何變更 PDF 文件中 XMP 中繼資料的屬性。
using var pdf = new PdfDocument("file.pdf");
pdf.Metadata.DublinCore.Creators = new XmpArray(XmpArrayType.Ordered);
pdf.Metadata.DublinCore.Creators.Values.Add(new XmpString("me"));
pdf.Metadata.DublinCore.Creators.Values.Add(new XmpString("Docotic.Pdf"));
pdf.Metadata.DublinCore.Format = new XmpString("application/pdf");
pdf.Metadata.Pdf.Producer = new XmpString("me too!");
pdf.Save("updated-file.pdf");
此程式碼會變更 Dublin Core 與 Adobe PDF 結構描述中的屬性。請注意,由於預設儲存選項的關係,Producer 屬性會被覆寫。
您可以使用 XmpMetatada.Save 方法之一擷取原始 XMP 中繼資料。該方法會產生包含所有屬性的 XML。
若要從文件中移除所有 XMP 中繼資料,請使用 XmpMetadata.Unembed 方法。
同步中繼資料
最好確保 XMP 中繼資料與 Document Info 屬性對應欄位具有相同值。若您在同一檔案中同時編輯這兩個中繼資料來源,這點尤其重要。
使用 PdfDocument.SyncMetadata 方法可同步 XMP 中繼資料與 Document Info 的值。當同一屬性在兩個來源中都已變更時,該方法會以另一來源的值覆寫其中一個來源。請閱讀此方法的文件以了解更多細節。
PDF 書籤
PDF 文件可以包含特殊捷徑或連結,協助讀者快速導覽至特定章節或頁面。PDF 大綱是書籤的另一個名稱。

檢視器應用程式通常會像書籍目錄一樣顯示書籤,但具有互動性。當讀者點擊書籤時,檢視器應用程式會跳到文件中的指定位置。也可以使用連結註解達成類似行為。
以下是示範如何向 PDF 新增書籤的 C# 程式碼片段:
using var pdf = new PdfDocument("ten-pages.pdf");
var root = pdf.OutlineRoot;
root.AddChild("Fifth page", 4);
root.AddChild("Seventh page", pdf.Pages[6]);
pdf.PageMode = PdfPageMode.UseOutlines;
pdf.Save("simple-bookmarks.pdf");
PDF 大綱可以有主書籤與子書籤,使大型文件更容易組織。以下示範如何在 PDF 中建立子書籤:
using var pdf = new PdfDocument("ten-pages.pdf");
var root = pdf.OutlineRoot;
var evenPages = root.AddChild("Even pages");
evenPages.AddChild("Second page", 1);
evenPages.AddChild("Fourth page", 3);
pdf.PageMode = PdfPageMode.UseOutlines;
pdf.Save("even-pages-bookmarks.pdf");
您可以將字型與色彩套用到書籤項目。請查看具有樣式的大綱完整範例。
若要從 PDF 移除書籤,請使用 RemoveChild 或 RemoveChildAt 方法。您可以在根節點上呼叫 RemoveAllChildren 方法來移除所有書籤。
檔案附件
PDF 附件是嵌入在 PDF 文件中的外部檔案。這些檔案也常被稱為內嵌檔案與檔案附件。您可以附加任何檔案:影像、音訊/視訊檔案、另一份 PDF、Word 文件、Excel 試算表,或其他任何檔案。
如果您想將多份 PDF 彼此附加,建立合併的 PDF 檔案,請查看關於合併 PDF 文件的文章。
以下 C# 程式碼示範如何在 Docotic.Pdf API 的協助下為 PDF 新增附件。
using var pdf = new PdfDocument();
var excelFile = pdf.CreateFileAttachment("this-year-figures.xlsx");
pdf.SharedAttachments.Add(excelFile);
pdf.Save("shared-attachment.pdf");
上述程式碼將檔案新增為共用附件。讀者可以在其檢視器的附件面板中找到附加檔案。
也可以將附件新增到 PDF 頁面。這類附件會像其他註解一樣顯示在頁面內容中。
using var pdf = new PdfDocument();
var page = pdf.Pages[0];
page.Canvas.DrawString(20, 100, "Here is this year's figures document:");
var bounds = PdfRectangle.FromLTRB(155, 100, 165, 110);
var excelFile = pdf.CreateFileAttachment("this-year-figures.xlsx");
pdf.Pages[0].AddFileAnnotation(bounds, excelFile);
pdf.Save("page-attachment.pdf");
請查看範例程式碼的 附件群組 以找到此節範例的完整測試專案。
若要從 PDF 移除附件,您需要列舉共用附件與頁面註解,並移除不需要的項目。以下的列舉程式碼範例可供參考。若要移除所有共用附件,您可以呼叫 pdf.SharedAttachments.Clear()。
若要從 PDF 擷取內嵌檔案,也需要列舉集合。以下是範例程式碼:
using var pdf = new PdfDocument("file-with-attachments.pdf");
int i = 0;
foreach (var attachment in pdf.SharedAttachments)
{
if (attachment?.Contents == null)
continue;
var fileName = attachment.Specification ?? $"attachment{i++}";
attachment.Contents.Save(fileName);
}
foreach (var widget in pdf.GetWidgets())
{
var attachment = (widget as PdfFileAttachmentAnnotation)?.File;
if (attachment?.Contents == null)
continue;
var fileName = attachment.Specification ?? $"attachment{i++}";
attachment.Contents.Save(fileName);
}
頁面標籤
PDF 頁面標籤是指在 PDF 文件中指派給頁面的自訂名稱或編號。與標準頁碼不同,頁面標籤可以包含字母、數字,甚至羅馬數字。頁面標籤的其他名稱包括頁面識別碼與頁面名稱。
以下示範如何使用 Docotic.Pdf 在 PDF 中新增頁面標籤:
using var pdf = new PdfDocument("ten-pages.pdf");
pdf.PageLabels.AddRange(0, 3, PdfPageNumberingStyle.LowercaseRoman);
pdf.PageLabels.AddRange(4, PdfPageNumberingStyle.DecimalArabic, string.Empty, 5);
pdf.PageLabels.AddRange(7, PdfPageNumberingStyle.DecimalArabic, "Appendix page ", 1);
pdf.Save("page-labels.pdf");
前四頁的標籤會是 i、ii、iii 和 iv。接下來三個標籤是 5、6 和 7。其餘頁面的標籤將是 Appendix page 1、Appendix page 2 和 Appendix page 3。
對 PDF 執行 OCR
有些 PDF 文件包含掃描頁面,在您能從中擷取文字之前需要先進行光學字元辨識(OCR)。OCR 的另一個使用情境,是從使用自訂字形到 Unicode 對應的 PDF 中擷取文字。

我們有一篇部落格文章示範如何對掃描文件執行 OCR。該文章包含一個不可搜尋的 PDF 範例,並示範如何使用 Tesseract OCR、C# 程式碼與 Docotic.Pdf 辨識僅含影像的 PDF 中的文字。您也可以在 Docotic.Pdf 的協助下,為掃描 PDF 檔案新增 OCR 文字圖層。
編輯頁面
本節說明對既有 PDF 頁面的變更,例如:
- 如何旋轉 PDF 頁面
- 如何變更頁面大小
- 在頁面畫布上使用向量圖形
- 新增 HTML 內容
請閱讀程式庫的 Layout API,了解如何建立 PDF 文件,其建構元件包括頁首與頁尾、表格、影像、文字段落等。
請查看其他章節以取得以下資訊:
旋轉頁面
請參閱以下 C# 程式碼片段,了解如何只旋轉 PDF 中的一頁:
using var pdf = new PdfDocument("existing.pdf");
pdf.Pages[0].Rotation = PdfRotation.Rotate180;
pdf.Save("rotated.pdf");
此程式碼將第一頁旋轉 180 度。您也可以將 PDF 頁面旋轉 0、90 與 270 度。
變更頁面大小
Docotic.Pdf 提供多種變更 PDF 頁面大小的方法。最簡單的情況下,您可以使用 PdfPage 物件的 Width 與 Height 屬性指定所需大小。對於既有文件,它不會調整文件頁面內容大小,也不會移除任何內容。它只會隱藏超出指定大小矩形外的所有頁面內容。
類似的方法是裁切頁面。您可以使用類似下列的 C# 程式碼變更頁面的 CropBox:
using var pdf = new PdfDocument("existing.pdf");
var page = pdf.Pages[0];
var cropBoxBefore = page.CropBox;
page.CropBox = new PdfBox(0, cropBoxBefore.Height - 256, 256, cropBoxBefore.Height);
pdf.Save("cropped.pdf");
如果您想要將頁面的一部分儲存為影像,變更裁切框就是合適的做法。
如果目標是在不同大小的頁面上保持所有內容可見,則請使用縮放方法。在以下程式碼片段中,我從頁面建立一個 XObject。XObject 類似向量影像。您可以在多個頁面上繪製同一物件,並依需要進行縮放與旋轉。
XObject 準備好之後,我會清除先前的頁面內容、縮小頁面,然後將物件繪製到縮小後的頁面上。
using var pdf = new PdfDocument("existing.pdf");
var page = pdf.Pages[0];
var pageXObject = pdf.CreateXObject(page);
page.Canvas.Clear();
page.Width /= 2;
page.Height /= 2;
page.Canvas.DrawXObject(pageXObject, 0, 0, page.Width, page.Height, 0);
pdf.Save("resized.pdf");
向量圖形
Docotic.Pdf 程式庫可為 PDF 文件新增線條、曲線與形狀等向量圖形。您可以從圖形物件建構圖形路徑。接著可以使用不同色彩空間的色彩來填滿或描邊路徑。
請在範例程式碼的 圖形群組 中尋找與圖形相關功能的範例程式碼。
也可以從 PDF 擷取圖形。先呼叫 GetObjects 方法,然後從 PdfPageObjectType.Path 類型的物件中擷取資訊。不要忘記 XObject 也可能包含巢狀路徑。
using var pdf = new PdfDocument("existing.pdf");
var options = new PdfObjectExtractionOptions();
var objects = pdf.Pages[0].GetObjects(options);
foreach (var obj in objects)
{
if (obj.Type == PdfPageObjectType.Path)
{
var path = (PdfPath)obj;
Console.WriteLine($"Found path {path}");
}
else if (obj.Type == PdfPageObjectType.XObject)
{
var paintedXObject = (PdfPaintedXObject)obj;
var nestedObjects = paintedXObject.XObject.GetObjects(options);
// ...
}
}
將 HTML 新增至 PDF 頁面
將 HTML 內容疊加到 PDF 文件上,對於新增動態元素,例如圖表或股價跑馬燈到您的 PDF,會很有用。
請閱讀將 HTML 插入 PDF以取得更多細節並下載範例程式碼。
編輯 PDF 文字
本節說明如何編輯 PDF 中的文字、如何變更 PDF 中的文字顏色,以及如何新增文字。

我們有一篇專門說明如何從 PDF 擷取文字的文章。請查看以取得更多相關資訊。
借助 Docotic.Pdf 也可以展平文字。
尋找與取代
若要修改 PDF 中的文字,您需要先找出包含該文字的區域,然後移除該區域中的文字。最後一步是在文件的相同區域加入新文字。
搜尋 PDF 可能很棘手,因為文件內部的字詞順序可以是任意的。文字也可能已旋轉。幸好,我們有一個範例程式碼示範如何在 PDF 中搜尋單字或片語。
當您取得要移除文字的座標後,就可以編輯其所在頁面的內容。此程式庫提供列舉與複製頁面物件的方法。因此,在複製物件時可以略過某些文字。這基本上就會移除那些文字。編輯 PDF 頁面內容 範例的程式碼說明了此流程的所有細節。您需要更新 ShouldRemoveText 方法,以使用找到的座標。
請閱讀下一節,了解如何將新文字新增到文件中。
如果您建立含有預留文字的文件,之後再以其他文字取代該預留文字,那麼也可以改用文字方塊。
做法是:在文件中加入一個無邊框、唯讀的文字方塊,並將預留文字放入其中。之後您可以開啟文件,依名稱找到該文字方塊,並透過簡單的 box.Text = "new text"; 呼叫取代預留文字。若不希望再進一步修改,請在取代後將文字方塊展平。
新增文字
若要在文件中新增文字,請使用 PdfCanvas 物件的 DrawString 與 DrawText 方法。這些方法會使用目前的畫布字型。字型必須包含文字中所有字元的字形。使用 PdfFont.ContainsGlyphsForText 方法檢查字型是否符合此要求。
var canvas = pdf.Pages[0].Canvas;
canvas.Font = pdf.CreateFont("NSimSun");
canvas.DrawString(10, 50, "Olá. 你好. Hello. This is some new text");
您可以使用 Type1、TrueType 與 OpenType 字型繪製 Unicode 文字。此程式庫可以使用系統已安裝的字型、14 種內建 Type1 字型,或從檔案載入所需字型。
變更文字顏色
若要變更 PDF 中文字的顏色,請使用與移除文字相同的方法。您至少需要變更範例程式碼中的 ReplaceColor 方法。
影像
Docotic.Pdf 提供編輯 PDF 影像所需的一切功能。以下是最常見操作的 C# 程式碼片段。
範例程式碼中的影像群組包含此節範例的完整測試專案。
新增影像至 PDF
此程式庫可匯入 GIF/TIFF/PNG/BMP/JPEG 格式的影像。您也可以從 System.Drawing.Image 物件新增影像。
var canvas = pdf.Pages[0].Canvas;
var image = pdf.CreateImage("image.jpg");
canvas.DrawImage(image, 10, 50);
您可以使用 DrawImage 方法的多載指定旋轉角度與輸出大小。若要在多個頁面上繪製相同影像,只需新增一次影像,並在多次呼叫 DrawImage 方法時使用同一個 PdfImage 物件。
將影像合併為 PDF
以下 C# 程式碼示範如何將多個影像合併為一份 PDF。
using var pdf = new PdfDocument();
var imagePaths = new string[] { "image.jpg", "another-image.png" };
foreach (var path in imagePaths)
{
var image = pdf.CreateImage(path);
var page = pdf.AddPage();
page.Width = image.Width;
page.Height = image.Height;
page.Canvas.DrawImage(image, 0, 0);
}
pdf.RemovePage(0);
pdf.Save("combined-images.pdf");
此程式碼會將多個影像新增到 PDF,並將每頁大小調整為對應的影像大小。在儲存結果之前,程式碼會移除最初隱含新增的空白頁。
擷取 PDF 影像
我們設計 Docotic.Pdf 的目的之一,是在不影響影像品質的情況下從 PDF 檔案擷取影像。此程式庫不會變更影像大小或壓縮方式。您會取得與 PDF 中相同品質的影像。
using var pdf = new PdfDocument("file-with-images.pdf");
int i = 0;
foreach (PdfImage image in pdf.GetImages())
{
var path = image.Save($"image{i++}");
Console.WriteLine($"Saved to {path}");
}
移除與取代影像
使用 PdfPage.RemovePaintedImages 方法可從 PDF 頁面中移除全部或特定影像。您可以依位置、大小、變換或其他參數篩選影像。
using var pdf = new PdfDocument("file-with-images.pdf");
pdf.Pages[0].RemovePaintedImages(
image =>
{
return image.Size.Width > 100;
}
);
pdf.RemoveUnusedResources();
pdf.Save("no-wide-images.pdf");
以上 C# 程式碼示範如何借助 Docotic.Pdf 移除影像。我建議在變更或移除影像後,移除未使用的資源。
使用 PdfImage.ReplaceWith 方法可取代 PDF 文件中該影像的所有出現位置。
using var pdf = new PdfDocument("file-with-images.pdf");
var firstImage = pdf.GetImages(false).FirstOrDefault()
?? throw new ArgumentException("No images found");
firstImage.ReplaceWith("another-image.png");
pdf.RemoveUnusedResources();
pdf.Save("replaced-image.pdf");
變更壓縮方案
Docotic.Pdf 提供變更 PDF 影像壓縮方式的方法。可以使用 JPEG、CCITT Group 3 與 4(fax)、JPEG 2000,以及 zip/deflate 壓縮演算法重新封裝影像。
依據初始壓縮與新壓縮方式的不同,此變更可能造成影像細節或品質損失。不過有損轉換通常有助於縮小文件大小。
firstImage.RecompressWithJpeg2000(25);
還有其他重新封裝影像的方法。請查看名稱以 RecompressWith 開頭的 PdfImage 方法。您可以使用 Uncompress 方法移除影像的任何壓縮。
調整影像大小
如果 PDF 文件中的某些影像比實際需要的大,程式庫可以為您調整其大小或縮小取樣。
firstImage.Scale(0.5, PdfImageCompression.Jpeg2000, 25);
以上程式碼會將第一張影像在兩個方向上縮小一半。程式庫會對結果影像使用 JPEG 2000 壓縮。
您可以使用其中一個 ResizeTo 方法指定結果寬度與高度的確切值。
調整影像大小通常比變更壓縮方式更能縮小 PDF 檔案大小(請參閱上方章節),但這是有損過程。
浮水印與背景

PDF 浮水印涉及以下步驟:
- 建立 XObject,作為浮水印內容的容器
- 以文字、影像與向量圖形填充該物件
- 使用該物件蓋印 PDF 頁面
以下 C# 程式碼會為 PDF 新增 Confidential 浮水印:
using var pdf = new PdfDocument("existing.pdf");
var watermark = pdf.CreateXObject();
watermark.DrawOnBackground = true;
var canvas = watermark.Canvas;
canvas.FontSize = 72;
canvas.Brush.Color = new PdfRgbColor(222, 35, 35);
canvas.Brush.Opacity = 45;
canvas.Pen.Color = canvas.Brush.Color;
canvas.Pen.Opacity = canvas.Brush.Opacity;
canvas.Pen.Width = 5;
var padding = 10;
var text = "CONFIDENTIAL";
canvas.DrawString(padding, padding, text);
var textSize = canvas.MeasureText(text);
var watermarkRect = new PdfRectangle(
padding, padding, textSize.Width, textSize.Height);
canvas.DrawRoundedRectangle(watermarkRect, new PdfSize(padding, padding));
foreach (var page in pdf.Pages)
{
page.Canvas.DrawXObject(
watermark,
(page.Width - watermarkRect.Width) / 2,
(page.Height - watermarkRect.Height) / 2);
}
pdf.Save("watermarked.pdf");
此程式碼設定了浮水印畫布的筆刷與畫筆屬性。筆刷用於繪製文字。為了取得文字大小,程式碼會測量文字。接著它會在文字周圍繪製一個圓角矩形。畫筆用於描邊該矩形。
浮水印內容準備好後,程式碼會將它繪製在每一頁的中央。
PDF 背景與浮水印非常相似。至少它們的建立方式幾乎相同。若要為 PDF 新增背景,做法與上方程式碼相同,但在 CreateXObject 呼叫之後新增 watermark.DrawOnBackground = true;。請注意,像影像這類不透明內容可能會遮住背景。
註解
Docotic.Pdf 為 PDF 註解提供了豐富的 API。您可以在 PDF 文件中建立、編輯與移除註解。也可以將註解展平。
若要為文字加註解,有以下幾種:
- 便利貼或文字註解。請參閱
PdfPage類別的AddTextAnnotation方法。 - 重點標示。請參閱
AddHighlightAnnotation方法。 - 刪除線。請參閱
AddStrikeoutAnnotation方法。 - 底線。請參閱
AddJaggedUnderlineAnnotation與AddUnderlineAnnotation方法。
使用連結可從一頁跳到另一頁或外部資源。您可以使用墨水註解在 PDF 頁面上自由手繪。也有適用於要從文件中移除部分內容的遮蔽註解。您還可以嵌入音訊、視訊或 3D 內容。
文字醒目標示
以下示範如何在 PDF 文件中醒目標示文字:
using var pdf = new PdfDocument();
var page = pdf.Pages[0];
var canvas = page.Canvas;
canvas.FontSize = 30;
var text = "Highlighted text.";
var position = new PdfPoint(10, 50);
canvas.DrawString(position, text);
canvas.DrawString(" Not highlighted.");
var size = canvas.MeasureText(text);
var bounds = new PdfRectangle(position, size);
var color = new PdfRgbColor(145, 209, 227);
var annotationText = "Please pay attention to this part.";
page.AddHighlightAnnotation(annotationText, bounds, color);
pdf.Save("highlighted.pdf");
連結
若要連結至 PDF 中的特定頁面,請使用如下程式碼:
using var pdf = new PdfDocument();
var secondPage = pdf.AddPage();
secondPage.Canvas.DrawString(10, 50, "Welcome to the second page.");
var firstPage = pdf.Pages[0];
var canvas = firstPage.Canvas;
var linkRect = new PdfRectangle(10, 50, 100, 60);
canvas.DrawRectangle(linkRect, PdfDrawMode.Stroke);
var options = new PdfTextDrawingOptions(linkRect)
{
HorizontalAlignment = PdfTextAlign.Center,
VerticalAlignment = PdfVerticalAlign.Center
};
canvas.DrawText("Go to 2nd page", options);
firstPage.AddLinkToPage(linkRect, 1);
pdf.Save("linked.pdf");
在程式碼中,動作區域註解會像內部超連結一樣運作。這類區域也可以導覽至外部資源,並執行非導覽性動作。
移除註解
若要從 PDF 移除註解:
- 使用
PdfPage.Widgets屬性或PdfDocument.GetWidgets方法存取 widgets 集合。 - 檢查型別、屬性,或以其他方式決定哪些註解已不再需要。
- 使用
PdfDocument.RemoveWidget方法或PdfWidgetCollection物件的方法移除註解。
若要從 PDF 移除附件,您需要同時移除檔案註解與共用附件。
遮蔽 PDF
作為 PDF 遮蔽程式庫,Docotic.Pdf 提供可永久移除或快速塗黑 PDF 文件中敏感資訊的方法。

遮蔽文字
以下示範如何只使用 C# 與 Docotic.Pdf,在沒有 Redact 工具的情況下將 PDF 中的文字塗黑。
int i = 0;
foreach (var page in pdf.Pages)
{
foreach (var word in page.GetWords())
{
if (i % 3 == 0)
{
page.Canvas.AppendRectangle(word.Bounds);
page.Canvas.FillPath(PdfFillMode.Winding);
}
i++;
}
}
此程式碼會在文件中每第三個字上方繪製黑色矩形。請注意,矩形下方的文字仍然留在文件中,之後仍可擷取。若要永久移除文字,請使用取代文字章節中的方法。
遮蔽影像
您也可以使用黑色矩形遮住影像。不過更簡單的方法是用黑色 1x1 像素影像取代影像。這不僅會在視覺上標示出被遮蔽的影像,也會移除原始影像資料。
請參閱移除與取代影像章節的程式碼範例。我也建議在取代後呼叫 PdfDocument.ReplaceDuplicateObjects 方法。
PDF 表單
Docotic.Pdf 可以使用各種互動式元素建立 Acroforms(即 PDF 表單),例如按鈕、核取方塊、下拉清單、清單方塊、單選按鈕與文字欄位。
通常只需要幾行程式碼就能新增並設定表單欄位。例如,您只要呼叫 PdfPage.AddTextBox 方法,就能在 PDF 中新增可編輯欄位。表單與註解群組中的範例程式碼提供了關於建立與使用表單的更多資訊。
如何填寫 PDF 表單
使用 PdfDocument.TryGetControl 方法可依完整或部分名稱擷取 PDF 控制項。或者,您也可以使用 GetControls 方法列舉文件中的所有控制項。在這兩種方法中,您都需要將結果轉型為預期的欄位型別。
using var pdf = new PdfDocument(@"example-form.pdf");
if (pdf.TryGetControl("txt-name", out var c) && c is PdfTextBox nameTextBox)
nameTextBox.Text = "Bit Miracle team";
if (pdf.TryGetControl("txt-email", out c) && c is PdfTextBox emailTextBox)
emailTextBox.Text = "support@bitmiracle.com";
if (pdf.TryGetControl("check-agree", out c) && c is PdfCheckBox agreeCheckBox)
agreeCheckBox.Checked = true;
pdf.Save("filled-form.pdf");
此程式碼使用這個 PDF 表單範例。在程式碼中,我為兩個文字欄位設定值,並勾選核取方塊。
當您完成表單填寫後,可以將其所有欄位展平。
在表單中使用 JavaScript
您可以將動作新增至控制項事件。PdfControl 類別可存取一組預先定義的事件。事件名稱以 "On" 開頭(例如 OnMouseDown)。
以下是將 JavaScript 用於 PDF 表單的範例:
using var pdf = new PdfDocument(@"example-form.pdf");
foreach (var field in pdf.GetControls())
field.OnChange = pdf.CreateJavaScriptAction($"app.alert('{field.Name} changed!',3)");
pdf.Save("javascript-events.pdf");
Forms Data Format
還有另一種電子填寫 PDF 的方式。使用程式庫的 FDF to PDF 功能,可自動從資料庫或其他來源填入 PDF 表單。
using var pdf = new PdfDocument(@"example-form.pdf");
pdf.ImportFdf("form-data.fdf");
pdf.Save("auto-populated.pdf");
此程式碼使用這個 FDF 檔案一次填入所有表單欄位。
展平 PDF
本節說明如何展平 PDF。

當您展平 PDF 時,會將表單與註解等互動式元素轉換為靜態內容,以防止進一步編輯。展平後的 PDF 在外觀相同的情況下,可能佔用顯著更少的位元組。
展平表單與註解
若要展平可填寫 PDF,請使用 PdfDocument.FlattenControls 方法。此方法會將所有表單欄位與其他控制項繪製到其父頁面上,並從文件中移除來源控制項。
當您展平 PDF 表單時,也適合將註解一併展平。使用 PdfDocument.FlattenWidgets 方法可同時展平控制項與註解。
如果您只想將某些控制項和/或註解轉換為其視覺表示,請使用 PdfWidget.Flatten 方法。您需要先找出所需的控制項或註解。
展平文字
您可以借助 Docotic.Pdf 將 PDF 文字轉換為外框。通常這麼做的原因是為了達到與字型無關的效果。不論是否安裝字型,展平後的文字在任何裝置上都會看起來相同。
不過,一旦您將文字轉換為外框,就無法再將其作為文字編輯。此外,在展平過程中,程式庫會把文字轉換為向量圖形。這可能增加檔案大小。
若要展平 PDF 文字,您需要將文字擷取為向量路徑,並將其複製到新頁面或同一頁面上。這裡有一個範例程式碼。
儲存選項
在上方的程式碼片段中,我使用了不帶額外引數的 PdfDocument.Save 方法。在這種情況下,程式庫會使用預設儲存選項。我們精心挑選了這些預設值,使其在一般情況下表現良好。
不過,有些情況下您需要覆寫預設選項。為此,請建立 PdfSaveOptions 物件、設定選項,並將其提供給其中一個儲存方法。接下來我將說明這些情況。
若要以密碼或憑證保護 PDF,請建立加密處理器並將其設定給 EncryptionHandler 屬性。
當您想要多次簽署同一份 PDF時,請將 WriteIncrementally 屬性設為 true 以啟用增量更新模式。當您要儲存先前已簽署的檔案並加入新註解或表單資料時,也請這麼做。
將 Linearize 屬性設為 true,即可產生線性化(或 Fast Web View 最佳化)的 PDF 檔案。可辨識此最佳化的檢視器能更快顯示這類檔案。
若要避免在儲存時變更某些中繼資料欄位,請將 UpdateProducer 與 UpdateModifiedDate 屬性設為 false。