如何使用 C# 移除 PDF 註解 – GroupDocs.Annotation 指南

簡介

如果您需要快速且可靠地 移除 PDF 註解 C#,您來對地方了。無論是清理面向客戶的報告、淨化法律文件,或是自動化大量已審閱的 PDF 批次,手動操作既繁瑣又容易出錯。本教學將帶您使用 GroupDocs.Annotation for .NET 完整流程,從安裝函式庫到處理密碼保護檔案等邊緣情況。完成後,您只需幾行 C# 程式碼,即可從 PDF 中剝除任何註解——包括標記、便利貼、印章或圖形。

您將掌握的內容:

  • 安裝與授權 GroupDocs.Annotation for .NET
  • 編寫簡潔的 C# 程式碼以 移除 PDF 註解 C#,適用於單檔與批次情境
  • 處理大型 PDF、記憶體限制與常見錯誤情況
  • 擴充解決方案以選擇性刪除特定註解類型(例如,只移除 PDF 便利貼)

讓我們開始,輕鬆完成註解清理。

快速答覆

  • 我可以一次刪除所有註解類型嗎? 是的——在使用 Get() 取得後,呼叫 annotator.Remove(allAnnotations)。
  • 生產環境需要授權嗎? 有效的 GroupDocs.Annotation 授權會移除浮水印並解鎖全部功能。
  • 支援哪些 .NET 版本? .NET Framework 4.6.2+、.NET Core 2.0+、.NET 5/6/7。
  • 如何處理受密碼保護的 PDF? 在建立 Annotator 時透過 LoadOptions 傳入密碼。
  • 我可以自動處理數百個檔案嗎? 當然可以——將單檔程式碼與 foreach 迴圈或平行處理結合,以執行批次作業。

什麼是移除 PDF 註解 C#?

remove pdf annotations c# 是使用 C# 程式化刪除 PDF 文件中所有嵌入的註解物件的過程。此操作僅影響註解層,保持底層文字、影像與版面不變。它會移除所有註解物件——例如標記、評論、印章與圖形——同時保留 PDF 的原始內容、版面與中繼資料,使文件乾淨且可供發布或存檔。此過程只有在移除前保留原始檔案備份時才可完全復原。

為何使用 GroupDocs.Annotation 進行 PDF 註解移除?

GroupDocs.Annotation 支援 30 多種註解類型(包括標記、便利貼、印章與自由繪圖),且可處理高達 500 MB 的 PDF 而無需將整個檔案載入記憶體。API 可在任何支援 .NET 的平台上執行,為桌面與 Web 應用提供一致且高效能的解決方案。

先決條件

  • GroupDocs.Annotation for .NET ≥ 25.4.0
  • Visual Studio 2017 或更新版本
  • 具備安裝 NuGet 套件的管理員權限
  • 基本的 C# 知識(變數、using 陳述式、例外處理)

如何使用 GroupDocs.Annotation 移除 PDF 註解?

工作流程包括使用 Annotator 類別載入 PDF、透過 Get() 取得完整的註解清單、對該集合呼叫 Remove(),最後儲存修改後的文件。此流程一次性處理所有註解類型,且適用於單檔與批次處理情境。

步驟 1:定義輸入與輸出路徑

首先,將程式指向來源 PDF,並決定清理後的版本要存放於何處。

Install-Package GroupDocs.Annotation -Version 25.4.0

步驟 2:初始化 Annotator 物件

Annotator 類別是所有註解操作的入口。

dotnet add package GroupDocs.Annotation --version 25.4.0

定義說明: Annotator 類別提供載入、查詢、修改與儲存 PDF 註解的方法。

步驟 3:取得所有註解

從文件中取得每個註解物件。

using System;
using GroupDocs.Annotation;

class Program
{
    static void Main()
    {
        // Initialize license if available
        License lic = new License();
        lic.SetLicense("path/to/your/license.lic");

        Console.WriteLine("GroupDocs.Annotation initialized successfully.");
    }
}

說明: Get() 會回傳 AnnotationBase 物件的集合,代表文件中所有存在的註解——包括標記、便利貼、印章、圖形等。

步驟 4:移除註解

一次呼叫即可刪除取得的註解。

string inputFilePath = Path.Combine("YOUR_DOCUMENT_DIRECTORY", "ANNOTATED_FILE_NAME");
string outputPath = Path.Combine("YOUR_OUTPUT_DIRECTORY", "result.pdf");

說明: Remove 方法接受該集合,將每個註解從 PDF 中剝除。若集合為空,該方法會安全地不執行任何操作。

步驟 5:儲存清理後的文件

將無註解的 PDF 寫回磁碟。

string inputFilePath = @"C:\Documents\Annotated\project_proposal_with_comments.pdf";
string outputPath = @"C:\Documents\Clean\project_proposal_final.pdf";

說明: Save 會永久保存變更。輸出檔案可放在相同資料夾或其他位置,視您的工作流程而定。

完整範例程式

以下是完整、可直接執行的程式碼,包含上述五個步驟。

using (Annotator annotator = new Annotator(inputFilePath))
{
    // All the magic happens inside this using block
}

常見問題與除錯

  • 找不到檔案: 在呼叫 new Annotator 前,使用 File.Exists(inputPath) 確認路徑正確。
  • 存取被拒: 確認程序具有讀寫權限,且 PDF 未在其他地方開啟。
  • 大型檔案記憶體壓力: 若 PDF 超過 100 MB,請提升程序的記憶體上限或將檔案分成較小批次處理。
  • 損毀的 PDF: 將邏輯包在 try‑catch 區塊中;GroupDocs.Annotation 會拋出 AnnotationException 以處理不支援或受損的檔案。

實務應用案例

  • 法律文件準備: 律師事務所使用此腳本在向法院提交合約前清除內部評論。
  • 學術出版: 研究人員清除同行評審意見,以產生乾淨的手稿提交期刊。
  • 企業報告: 財務部門在內部審核後自動產生無浮水印的季報,供投資者使用。
  • 文件歸檔: 政府機關批次處理數千份帶註解的公共紀錄,僅保存最終的無註解版本以供長期保存。

效能最佳實踐

記憶體管理

  • 始終在 using 陳述式中包裹 Annotator,以確保釋放資源。
  • 將檔案分批(10–20 個)處理,以保持記憶體使用可預測。

最佳化技巧

List<AnnotationBase> annotations = annotator.Get();
Console.WriteLine($"Found {annotations.Count} annotations to remove.");

平行處理

在高吞吐量環境下,平行執行多個檔案:

if (annotations.Count > 0)
{
    annotator.Remove(annotations);
    Console.WriteLine("All annotations removed successfully.");
}
else
{
    Console.WriteLine("No annotations found in the document.");
}

警告: 平行處理會提升 CPU 與 I/O 負載;請監控系統資源以避免節流。

進階情境

選擇性註解移除

如果只需要刪除便利貼,可在呼叫 Remove 前以 AnnotationType.StickyNote 進行過濾。

annotator.Save(outputPath);
Console.WriteLine($"Clean document saved to: {outputPath}");

批次處理多個檔案

遍歷 PDF 目錄,對每個檔案套用相同的移除邏輯。

using System;
using System.Collections.Generic;
using System.IO;
using GroupDocs.Annotation;
using GroupDocs.Annotation.Models.AnnotationModels;

class Program
{
    static void Main()
    {
        try
        {
            string inputFilePath = Path.Combine("YOUR_DOCUMENT_DIRECTORY", "ANNOTATED_FILE_NAME");
            string outputPath = Path.Combine("YOUR_OUTPUT_DIRECTORY", "result.pdf");

            using (Annotator annotator = new Annotator(inputFilePath))
            {
                List<AnnotationBase> annotations = annotator.Get();
                Console.WriteLine($"Found {annotations.Count} annotations to remove.");

                if (annotations.Count > 0)
                {
                    annotator.Remove(annotations);
                    Console.WriteLine("All annotations removed successfully.");
                }
                else
                {
                    Console.WriteLine("No annotations found in the document.");
                }

                annotator.Save(outputPath);
                Console.WriteLine($"Clean document saved to: {outputPath}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error processing document: {ex.Message}");
        }
    }
}

常見問答

Q: 此程式碼能移除所有類型的 PDF 註解嗎?
A: 是的——GroupDocs.Annotation 處理所有標準註解類型,包括標記、便利貼、印章、自由繪圖與文字標記。

Q: 支援哪些 PDF 版本?
A: 此函式庫支援從 1.2 版到最新的 2.0 版規範的 PDF,幾乎涵蓋您會遇到的所有檔案。

Q: 同時刪除的註解數量有上限嗎?
A: 沒有硬性上限;效能會隨文件大小與系統記憶體而變化。對於非常大的檔案,建議分塊處理。

Q: 儲存後我可以復原移除的註解嗎?
A: 儲存後,註解會永久移除。如需日後恢復,請保留原始 PDF 的備份。

Q: 如何處理受密碼保護的 PDF?
A: 在建立 Annotator 時透過 LoadOptions 提供密碼,例如 new Annotator(path, new LoadOptions { Password = "pwd" })。

Q: 若輸入的 PDF 損毀會發生什麼情況?
A: API 會拋出例外。請將操作包在 try‑catch 區塊中,以記錄錯誤並繼續處理其他檔案。

Q: 我可以在 ASP.NET 網站應用中使用嗎?
A: 當然可以——GroupDocs.Annotation 為執行緒安全,支援 ASP.NET Core、MVC 與 Web API 專案。

Q: 商業使用需要授權嗎?
A: 需要——正式授權會移除浮水印並解鎖全部功能。可取得試用授權以進行評估。

Q: 我如何驗證所有註解已被移除?
A: 呼叫 Remove 後,再次執行 annotator.Get();應回傳空集合。

Q: 移除註解會影響 PDF 版面嗎?
A: 不會——文字、影像與頁面結構保持不變,僅剝除註解層。

其他資源

最後更新: 2026-06-01
測試環境: GroupDocs.Annotation 25.4.0 for .NET
作者: GroupDocs

// For batch processing, consider this pattern:
public static void ProcessDocumentBatch(List<string> filePaths)
{
    foreach (string filePath in filePaths)
    {
        using (Annotator annotator = new Annotator(filePath))
        {
            // Process each file individually
            var annotations = annotator.Get();
            if (annotations.Count > 0)
            {
                annotator.Remove(annotations);
                annotator.Save(GetOutputPath(filePath));
            }
        }
        // Force garbage collection periodically for large batches
        if (filePaths.IndexOf(filePath) % 20 == 0)
        {
            GC.Collect();
        }
    }
}
Parallel.ForEach(filePaths, filePath =>
{
    using (Annotator annotator = new Annotator(filePath))
    {
        var annotations = annotator.Get();
        if (annotations.Count > 0)
        {
            annotator.Remove(annotations);
            annotator.Save(GetOutputPath(filePath));
        }
    }
});
// Remove only highlight annotations
var annotations = annotator.Get();
var highlightAnnotations = annotations.Where(a => a.Type == AnnotationType.Highlight).ToList();
annotator.Remove(highlightAnnotations);
string[] pdfFiles = Directory.GetFiles(@"C:\AnnotatedPDFs", "*.pdf");
foreach (string file in pdfFiles)
{
    ProcessSingleFile(file);
}

相關教學