跳過到頁腳內容
使用IRONPDF

如何使用IronPDF在C#中比較兩個PDF文件

IronPDF 為 C# 開發人員提供了一種簡單的方法來以程式設計方式比較 PDF 文件——只需幾行程式碼即可提取文字內容並逐頁分析差異。本教學課程將透過 .NET 10 中的基本比較、多重文件分析、密碼保護文件處理以及產生格式化比較報告的實用程式碼範例,逐步講解相關功能。

為什麼需要以程式設計方式比較 PDF 文件?

手動比較 PDF 文件速度慢、容易出錯,而且無法擴充。 在法律、金融和醫療保健等文件密集型行業中,文件不斷變化——合約會修訂,發票會重新開具,監管文件需要版本驗證。 自動比較消除了人為瓶頸,每次都能提供一致、可審核的結果。

IronPDF為您提供了一種可用於生產環境的 C# 方法來比較兩個 PDF 檔案。 該庫使用 Chrome 渲染引擎從複雜的佈局中精確提取文本,其完整的 API 公開了用於加載、讀取和分析 PDF 內容的直觀方法。 無論您是追蹤合約變更、驗證產生的輸出,還是建立文件審核系統,IronPDF 都能幫您輕鬆搞定。

對於已經在多個平台上使用 .NET 的團隊來說,該程式庫也是一個不錯的選擇。 它支援 Windows、Linux、macOS、Docker、Azure 和 AWS,無需為每個目標平台編寫不同的程式碼路徑。 這使得建立可在 CI/CD 管道和桌面應用程式中運行的比較工具變得切實可行。

IronPDF C# 庫主頁橫幅展示了主要功能,包括 HTML 轉 PDF、PDF 編輯功能、部署選項和免費試用資訊。

何時應該使用自動 PDF 比較?

在處理文件繁多的工作流程中的版本控制時,自動比較變得至關重要。 每天處理數百個文件或對精確度要求極高時,人工審核是不切實際的。 常見情境包括:比較不同計費週期的發票、根據核准的範本驗證監管文件、追蹤不同版本技術規範的變更以及審核法律工作流程中的合約修改。

準確率提升顯著。 人工審閱者掃描兩份 50 頁的文件時,可能會遺漏財務表格中一個更改的數字。 自動比較功能可以立即發現差異,標記頁面,並產生差異報告,不會出現疲勞或不一致的情況。

主要應用場景有哪些?

PDF比較功能在許多行業和工作流程中都有應用:

-法律:追蹤合約修改,核實草案和最終版本之間的一致性,並確認簽署前只進行了已批准的更改。 -財務:驗證銀行對帳單,發現發票中的未經授權的更改,並確認產生的報告與預期輸出相符。 -醫療保健:核實監管文件是否與批准的文件相符,並確認患者記錄未被篡改。 -品質保證:將軟體產生的 PDF 與黃金主文件進行比較,以發現自動化測試套件中的渲染回歸問題。 -文件:確認在地化版本使用者手冊的一致性,並確保翻譯沒有改變技術內容。

IronPDF 的跨平台支援使得這些解決方案無需修改即可部署在 Windows、Linux 和雲端環境中。

如何在 .NET 專案中安裝 IronPDF?

使用 NuGet,透過套件管理器控制台或 .NET CLI 安裝 IronPDF:

Install-Package IronPdf
dotnet add package IronPdf
Install-Package IronPdf
dotnet add package IronPdf
SHELL

套件管理器控制台顯示 IronPDF 套件的安裝進度,該套件正在從 NuGet 下載多個相依性

對於Linux 部署基於 Docker 的環境,請參閱特定於平台的文件。 安裝完成後,如果您有許可證密鑰,請配置您的許可證密鑰:

IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY";
IronPdf.License.LicenseKey = "YOUR-LICENSE-KEY"
$vbLabelText   $csharpLabel

無需許可證金鑰即可進行開發和測試,但產生的 PDF 上會出現浮水印。 生產環境部署需要從許可證頁面取得有效的許可證。 免費試用版提供 30 天的完整功能評估,無需信用卡。

IronPDF 功能概述,主要分為四大類:建立 PDF、轉換 PDF、編輯 PDF 以及簽名和保護 PDF,每類下方都有詳細的功能清單。

IronPDF 支援 .NET Framework 4.6.2+、.NET Core 3.1+ 以及 .NET 5 至 .NET 10。對於 macOS,它同時支援 Intel 和 Apple Silicon 處理器。 該程式庫會自動處理 Chrome 渲染引擎的安裝,因此無需手動設定瀏覽器。

!{--01001100010010010100001001010010010000010101001001011001010111110100011101000101010101 01000101111101010011010101000100000101010010010101000100010101000100010111110101011101001000110 1010101000100100001011111010100000101001001001111010001000101010101010000110101010100101010101011 10101010001010010010010010010000010100110001011111010000100100110001001111101000011010010111111010000110100101110--

如何進行基本的PDF比較?

PDF比較的基礎是提取和比較文字內容。 IronPDF 的文字擷取功能可以從幾乎任何 PDF 版面配置中準確擷取內容,包括多列文件、表格、表單和具有嵌入式文字圖層的掃描 PDF。 以下範例載入兩個文件,提取它們的文本,併計算相似度得分:

using IronPdf;
using System;

// Load two PDF documents
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");

// Extract text from both PDFs
string text1 = pdf1.ExtractAllText();
string text2 = pdf2.ExtractAllText();

// Compare the two documents
if (text1 == text2)
{
    Console.WriteLine("PDF files are identical");
}
else
{
    Console.WriteLine("PDFs have differences");

    // Calculate character-level similarity
    int maxLength = Math.Max(text1.Length, text2.Length);
    if (maxLength > 0)
    {
        int differences = 0;
        int minLength = Math.Min(text1.Length, text2.Length);

        for (int i = 0; i < minLength; i++)
        {
            if (text1[i] != text2[i]) differences++;
        }

        differences += Math.Abs(text1.Length - text2.Length);
        double similarity = 1.0 - (double)differences / maxLength;

        Console.WriteLine($"Similarity: {similarity:P}");
        Console.WriteLine($"Character differences: {Math.Abs(text1.Length - text2.Length)}");
    }
}
using IronPdf;
using System;

// Load two PDF documents
var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");

// Extract text from both PDFs
string text1 = pdf1.ExtractAllText();
string text2 = pdf2.ExtractAllText();

// Compare the two documents
if (text1 == text2)
{
    Console.WriteLine("PDF files are identical");
}
else
{
    Console.WriteLine("PDFs have differences");

    // Calculate character-level similarity
    int maxLength = Math.Max(text1.Length, text2.Length);
    if (maxLength > 0)
    {
        int differences = 0;
        int minLength = Math.Min(text1.Length, text2.Length);

        for (int i = 0; i < minLength; i++)
        {
            if (text1[i] != text2[i]) differences++;
        }

        differences += Math.Abs(text1.Length - text2.Length);
        double similarity = 1.0 - (double)differences / maxLength;

        Console.WriteLine($"Similarity: {similarity:P}");
        Console.WriteLine($"Character differences: {Math.Abs(text1.Length - text2.Length)}");
    }
}
Imports IronPdf
Imports System

' Load two PDF documents
Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")

' Extract text from both PDFs
Dim text1 As String = pdf1.ExtractAllText()
Dim text2 As String = pdf2.ExtractAllText()

' Compare the two documents
If text1 = text2 Then
    Console.WriteLine("PDF files are identical")
Else
    Console.WriteLine("PDFs have differences")

    ' Calculate character-level similarity
    Dim maxLength As Integer = Math.Max(text1.Length, text2.Length)
    If maxLength > 0 Then
        Dim differences As Integer = 0
        Dim minLength As Integer = Math.Min(text1.Length, text2.Length)

        For i As Integer = 0 To minLength - 1
            If text1(i) <> text2(i) Then differences += 1
        Next

        differences += Math.Abs(text1.Length - text2.Length)
        Dim similarity As Double = 1.0 - CDbl(differences) / maxLength

        Console.WriteLine($"Similarity: {similarity:P}")
        Console.WriteLine($"Character differences: {Math.Abs(text1.Length - text2.Length)}")
    End If
End If
$vbLabelText   $csharpLabel

這段程式碼使用頂級語句和 IronPDF 的 ExtractAllText() 方法從兩個檔案中提取全文,然後執行字元級比較來計算相似度百分比。 此分數可以快速、量化地衡量文件之間的差異程度。

字元級方法的設計初衷是簡單快速。當您需要快速判斷兩個文件是否有差異時,例如偵測意外覆寫或確認轉換流程是否產生了預期輸出,這種方法非常有效。 對於需要更細緻分析的場景(例如識別哪些句子發生了變化或追蹤語義差異),您可以在提取的文字字串之上疊加萊文斯坦距離差異演算法

輸入的PDF檔案是什麼樣的?

! PDF 檢視器顯示編號為 INV-2025-001、日期為 2025-10-21、客戶為 John Doe、總金額為 1250.00 美元的發票文件。

這是一份客戶調查表 PDF 文件,包含姓名、電子郵件、滿意度下拉式選單(顯示"優秀")和評論等字段,在 PDF 檢視器中以 100% 縮放比例顯示。

對比結果顯示什麼?

Visual Studio 偵錯控制台顯示 PDF 比較輸出,分析文件之間的相似度結果為 2.60%

控制台輸出顯示文件之間的相似度百分比。 如上所示,2.60% 的相似度得分錶明這兩個文件的內容幾乎完全不同。 此指標可協助您快速評估差異程度並決定下一步措施。

純文字比較的限制是什麼?

僅文字比較無法捕捉格式、圖像或佈局差異。 兩個 PDF 檔案即使文字內容完全相同,但如果字體、頁面大小或圖像位置不同,看起來也會完全不同。 為了進行全面的視覺比較,可以考慮將 IronPDF 的影像擷取功能與影像比較庫結合使用。 IronPDF 的柵格化功能可以將頁面轉換為影像,以便在視覺精確度比文字內容更重要時進行逐像素比較。

如何逐頁比較PDF文件?

全文比較可以告訴你兩個 PDF 檔案是否不同,但逐頁比較可以告訴你它們究竟在哪些地方不同。 這對於報告、發票和表格等結構化文件尤其有價值,因為這些文件的內容在各個頁面上都遵循可預測的佈局:

using IronPdf;
using System;
using System.Collections.Generic;

var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");

int maxPages = Math.Max(pdf1.PageCount, pdf2.PageCount);
var pageResults = new List<(int Page, double Similarity)>();

for (int i = 0; i < maxPages; i++)
{
    string page1Text = i < pdf1.PageCount ? pdf1.ExtractTextFromPage(i) : "";
    string page2Text = i < pdf2.PageCount ? pdf2.ExtractTextFromPage(i) : "";

    if (page1Text != page2Text)
    {
        int maxLen = Math.Max(page1Text.Length, page2Text.Length);
        double sim = maxLen == 0 ? 1.0
            : 1.0 - (double)Math.Abs(page1Text.Length - page2Text.Length) / maxLen;

        Console.WriteLine($"Page {i + 1} differs -- similarity: {sim:P}");
        pageResults.Add((i + 1, sim));
    }
}

Console.WriteLine($"\nTotal pages with differences: {pageResults.Count}");
using IronPdf;
using System;
using System.Collections.Generic;

var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");

int maxPages = Math.Max(pdf1.PageCount, pdf2.PageCount);
var pageResults = new List<(int Page, double Similarity)>();

for (int i = 0; i < maxPages; i++)
{
    string page1Text = i < pdf1.PageCount ? pdf1.ExtractTextFromPage(i) : "";
    string page2Text = i < pdf2.PageCount ? pdf2.ExtractTextFromPage(i) : "";

    if (page1Text != page2Text)
    {
        int maxLen = Math.Max(page1Text.Length, page2Text.Length);
        double sim = maxLen == 0 ? 1.0
            : 1.0 - (double)Math.Abs(page1Text.Length - page2Text.Length) / maxLen;

        Console.WriteLine($"Page {i + 1} differs -- similarity: {sim:P}");
        pageResults.Add((i + 1, sim));
    }
}

Console.WriteLine($"\nTotal pages with differences: {pageResults.Count}");
Imports IronPdf
Imports System
Imports System.Collections.Generic

Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")

Dim maxPages As Integer = Math.Max(pdf1.PageCount, pdf2.PageCount)
Dim pageResults = New List(Of (Page As Integer, Similarity As Double))()

For i As Integer = 0 To maxPages - 1
    Dim page1Text As String = If(i < pdf1.PageCount, pdf1.ExtractTextFromPage(i), "")
    Dim page2Text As String = If(i < pdf2.PageCount, pdf2.ExtractTextFromPage(i), "")

    If page1Text <> page2Text Then
        Dim maxLen As Integer = Math.Max(page1Text.Length, page2Text.Length)
        Dim sim As Double = If(maxLen = 0, 1.0, 1.0 - CDbl(Math.Abs(page1Text.Length - page2Text.Length)) / maxLen)

        Console.WriteLine($"Page {i + 1} differs -- similarity: {sim:P}")
        pageResults.Add((i + 1, sim))
    End If
Next

Console.WriteLine($"\nTotal pages with differences: {pageResults.Count}")
$vbLabelText   $csharpLabel

此方法使用 ExtractTextFromPage() 遍歷每個頁面,逐一比較內容。 該方法能夠無錯誤地處理頁數不同的 PDF 文件——在一個文件中存在但在另一個文件中不存在的頁面被視為空字串,從而正確地將它們註冊為不同的文件。

逐頁比較在需要精確定位大型文件中的修改位置時特別有用。 與其審閱整份 200 頁的法律協議,不如直接查看實際發生變更的五頁內容。 這大大縮短了審核時間,並使比較結果具有可操作性。

為了提高處理大型 PDF 的效能,IronPDF 支援非同步處理和平行操作,以有效率地處理批次比較。 效能最佳化指南涵蓋了大規模操作的其他技術,包括按順序處理多個大檔案的記憶體管理策略。

如何同時比較多個PDF文件?

使用 IronPDF,可以輕鬆地將多個 PDF 文件與單一參考文件進行比較。 以下範例將任意數量的文件與提供的第一個文件進行比較,並收集結果以產生報告:

using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;

string[] pdfPaths = { "reference.pdf", "version1.pdf", "version2.pdf", "version3.pdf" };

if (pdfPaths.Length < 2)
{
    Console.WriteLine("At least 2 PDFs required for comparison");
    return;
}

var referencePdf = PdfDocument.FromFile(pdfPaths[0]);
string referenceText = referencePdf.ExtractAllText();

var results = new List<(string File, double Similarity, bool Identical)>();

for (int i = 1; i < pdfPaths.Length; i++)
{
    try
    {
        var currentPdf = PdfDocument.FromFile(pdfPaths[i]);
        string currentText = currentPdf.ExtractAllText();

        bool identical = referenceText == currentText;
        int maxLen = Math.Max(referenceText.Length, currentText.Length);
        double similarity = maxLen == 0 ? 1.0
            : 1.0 - (double)Math.Abs(referenceText.Length - currentText.Length) / maxLen;

        results.Add((Path.GetFileName(pdfPaths[i]), similarity, identical));

        string status = identical ? "identical to reference" : $"differs -- similarity: {similarity:P}";
        Console.WriteLine($"{Path.GetFileName(pdfPaths[i])}: {status}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error processing {pdfPaths[i]}: {ex.Message}");
    }
}

Console.WriteLine($"\nBatch complete: {results.Count} files compared");
Console.WriteLine($"Identical: {results.FindAll(r => r.Identical).Count}");
Console.WriteLine($"Different: {results.FindAll(r => !r.Identical).Count}");
using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;

string[] pdfPaths = { "reference.pdf", "version1.pdf", "version2.pdf", "version3.pdf" };

if (pdfPaths.Length < 2)
{
    Console.WriteLine("At least 2 PDFs required for comparison");
    return;
}

var referencePdf = PdfDocument.FromFile(pdfPaths[0]);
string referenceText = referencePdf.ExtractAllText();

var results = new List<(string File, double Similarity, bool Identical)>();

for (int i = 1; i < pdfPaths.Length; i++)
{
    try
    {
        var currentPdf = PdfDocument.FromFile(pdfPaths[i]);
        string currentText = currentPdf.ExtractAllText();

        bool identical = referenceText == currentText;
        int maxLen = Math.Max(referenceText.Length, currentText.Length);
        double similarity = maxLen == 0 ? 1.0
            : 1.0 - (double)Math.Abs(referenceText.Length - currentText.Length) / maxLen;

        results.Add((Path.GetFileName(pdfPaths[i]), similarity, identical));

        string status = identical ? "identical to reference" : $"differs -- similarity: {similarity:P}";
        Console.WriteLine($"{Path.GetFileName(pdfPaths[i])}: {status}");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Error processing {pdfPaths[i]}: {ex.Message}");
    }
}

Console.WriteLine($"\nBatch complete: {results.Count} files compared");
Console.WriteLine($"Identical: {results.FindAll(r => r.Identical).Count}");
Console.WriteLine($"Different: {results.FindAll(r => !r.Identical).Count}");
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.IO

Module Module1
    Sub Main()
        Dim pdfPaths As String() = {"reference.pdf", "version1.pdf", "version2.pdf", "version3.pdf"}

        If pdfPaths.Length < 2 Then
            Console.WriteLine("At least 2 PDFs required for comparison")
            Return
        End If

        Dim referencePdf = PdfDocument.FromFile(pdfPaths(0))
        Dim referenceText As String = referencePdf.ExtractAllText()

        Dim results As New List(Of (File As String, Similarity As Double, Identical As Boolean))()

        For i As Integer = 1 To pdfPaths.Length - 1
            Try
                Dim currentPdf = PdfDocument.FromFile(pdfPaths(i))
                Dim currentText As String = currentPdf.ExtractAllText()

                Dim identical As Boolean = (referenceText = currentText)
                Dim maxLen As Integer = Math.Max(referenceText.Length, currentText.Length)
                Dim similarity As Double = If(maxLen = 0, 1.0, 1.0 - CDbl(Math.Abs(referenceText.Length - currentText.Length)) / maxLen)

                results.Add((Path.GetFileName(pdfPaths(i)), similarity, identical))

                Dim status As String = If(identical, "identical to reference", $"differs -- similarity: {similarity:P}")
                Console.WriteLine($"{Path.GetFileName(pdfPaths(i))}: {status}")
            Catch ex As Exception
                Console.WriteLine($"Error processing {pdfPaths(i)}: {ex.Message}")
            End Try
        Next

        Console.WriteLine($"\nBatch complete: {results.Count} files compared")
        Console.WriteLine($"Identical: {results.FindAll(Function(r) r.Identical).Count}")
        Console.WriteLine($"Different: {results.FindAll(Function(r) Not r.Identical).Count}")
    End Sub
End Module
$vbLabelText   $csharpLabel

這種方法會載入一次參考文檔,然後循環遍歷所有其他文件並與之進行比較。 try/catch 區塊確保一個損壞或無法存取的檔案不會導致整個批次中止-錯誤會被記錄下來,然後處理下一個檔案。

比較 PDF 檔案後,Visual Studio 偵錯控制台輸出顯示"PDF 1 與參考檔案不同"訊息

對於非常大的批量,可以考慮使用非同步任務模式並行加載和提取多個 PDF 中的文本,而不是順序加載和提取。 在選擇參考文件時,對於版本控制場景,請使用最新批准的版本;對於品質保證工作流程,請使用預期輸出範本。 您也可以透過讀取PDF 元資料(例如文件本身嵌入的建立日期和版本號)來自動選擇參考文獻。

如何比較受密碼保護的PDF檔案?

IronPDF 透過在 FromFile 呼叫中直接接受密碼來處理加密的 PDF。 載入檔案前無需在外部進行解密-該程式庫會在內部處理身份驗證。 該庫支援 40 位元 RC4、128 位元 RC4 和 128 位元 AES 加密標準:

using IronPdf;
using System;

try
{
    // Load password-protected PDFs
    var pdf1 = PdfDocument.FromFile("secure-document1.pdf", "password1");
    var pdf2 = PdfDocument.FromFile("secure-document2.pdf", "password2");

    Console.WriteLine($"PDF 1 loaded: {pdf1.PageCount} pages");
    Console.WriteLine($"PDF 2 loaded: {pdf2.PageCount} pages");

    string text1 = pdf1.ExtractAllText();
    string text2 = pdf2.ExtractAllText();

    bool identical = text1.Equals(text2);
    int maxLen = Math.Max(text1.Length, text2.Length);
    double similarity = maxLen == 0 ? 1.0
        : 1.0 - (double)Math.Abs(text1.Length - text2.Length) / maxLen;

    Console.WriteLine($"Documents are {(identical ? "identical" : "different")}");
    Console.WriteLine($"Similarity: {similarity:P}");

    // Optionally save a secured comparison report
    if (!identical)
    {
        var renderer = new ChromePdfRenderer();
        var reportPdf = renderer.RenderHtmlAsPdf(
            $"<h1>Comparison Result</h1><p>Similarity: {similarity:P}</p>");

        reportPdf.SecuritySettings.OwnerPassword = "report-owner-password";
        reportPdf.SecuritySettings.UserPassword = "report-user-password";
        reportPdf.SecuritySettings.AllowUserPrinting = true;
        reportPdf.SecuritySettings.AllowUserCopyPasteContent = false;

        reportPdf.SaveAs("comparison-report.pdf");
        Console.WriteLine("Secured report saved.");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Error handling secured PDFs: {ex.Message}");
}
using IronPdf;
using System;

try
{
    // Load password-protected PDFs
    var pdf1 = PdfDocument.FromFile("secure-document1.pdf", "password1");
    var pdf2 = PdfDocument.FromFile("secure-document2.pdf", "password2");

    Console.WriteLine($"PDF 1 loaded: {pdf1.PageCount} pages");
    Console.WriteLine($"PDF 2 loaded: {pdf2.PageCount} pages");

    string text1 = pdf1.ExtractAllText();
    string text2 = pdf2.ExtractAllText();

    bool identical = text1.Equals(text2);
    int maxLen = Math.Max(text1.Length, text2.Length);
    double similarity = maxLen == 0 ? 1.0
        : 1.0 - (double)Math.Abs(text1.Length - text2.Length) / maxLen;

    Console.WriteLine($"Documents are {(identical ? "identical" : "different")}");
    Console.WriteLine($"Similarity: {similarity:P}");

    // Optionally save a secured comparison report
    if (!identical)
    {
        var renderer = new ChromePdfRenderer();
        var reportPdf = renderer.RenderHtmlAsPdf(
            $"<h1>Comparison Result</h1><p>Similarity: {similarity:P}</p>");

        reportPdf.SecuritySettings.OwnerPassword = "report-owner-password";
        reportPdf.SecuritySettings.UserPassword = "report-user-password";
        reportPdf.SecuritySettings.AllowUserPrinting = true;
        reportPdf.SecuritySettings.AllowUserCopyPasteContent = false;

        reportPdf.SaveAs("comparison-report.pdf");
        Console.WriteLine("Secured report saved.");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Error handling secured PDFs: {ex.Message}");
}
Imports IronPdf
Imports System

Try
    ' Load password-protected PDFs
    Dim pdf1 = PdfDocument.FromFile("secure-document1.pdf", "password1")
    Dim pdf2 = PdfDocument.FromFile("secure-document2.pdf", "password2")

    Console.WriteLine($"PDF 1 loaded: {pdf1.PageCount} pages")
    Console.WriteLine($"PDF 2 loaded: {pdf2.PageCount} pages")

    Dim text1 As String = pdf1.ExtractAllText()
    Dim text2 As String = pdf2.ExtractAllText()

    Dim identical As Boolean = text1.Equals(text2)
    Dim maxLen As Integer = Math.Max(text1.Length, text2.Length)
    Dim similarity As Double = If(maxLen = 0, 1.0, 1.0 - CDbl(Math.Abs(text1.Length - text2.Length)) / maxLen)

    Console.WriteLine($"Documents are {(If(identical, "identical", "different"))}")
    Console.WriteLine($"Similarity: {similarity:P}")

    ' Optionally save a secured comparison report
    If Not identical Then
        Dim renderer = New ChromePdfRenderer()
        Dim reportPdf = renderer.RenderHtmlAsPdf($"<h1>Comparison Result</h1><p>Similarity: {similarity:P}</p>")

        reportPdf.SecuritySettings.OwnerPassword = "report-owner-password"
        reportPdf.SecuritySettings.UserPassword = "report-user-password"
        reportPdf.SecuritySettings.AllowUserPrinting = True
        reportPdf.SecuritySettings.AllowUserCopyPasteContent = False

        reportPdf.SaveAs("comparison-report.pdf")
        Console.WriteLine("Secured report saved.")
    End If
Catch ex As Exception
    Console.WriteLine($"Error handling secured PDFs: {ex.Message}")
End Try
$vbLabelText   $csharpLabel

透過將密碼傳遞給 FromFile,您可以直接比較加密的 PDF 文件,無需任何預解密步驟。 IronPDF 的安全功能可確保對受保護內容的妥善處理,而數位簽章則進一步增強了文件的真實性驗證。

處理受密碼保護的 PDF 檔案時,應將憑證儲存在環境變數或金鑰管理器中,而不是將其硬編碼到原始程式碼中。 實施排除敏感資訊的日誌記錄措施,並新增重試邏輯和嘗試次數限制,以防止暴力破解的情況。 對於進階加密需求, PDF/UA 合規性指南涵蓋了符合無障礙標準的安全性配置。

如何產生PDF對比報告?

格式化的報告可以讓利害關係人清楚了解兩份文件之間的變化。 以下範例使用 IronPDF 的 HTML 轉 PDF 功能產生帶有每頁差異指標的樣式報告:

using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");

var differences = new List<(int Page, double Similarity, int Len1, int Len2, int CharDiff)>();
int totalPages = Math.Max(pdf1.PageCount, pdf2.PageCount);

for (int i = 0; i < totalPages; i++)
{
    string p1 = i < pdf1.PageCount ? pdf1.ExtractTextFromPage(i) ?? "" : "";
    string p2 = i < pdf2.PageCount ? pdf2.ExtractTextFromPage(i) ?? "" : "";

    if (p1 == p2) continue;

    int maxLen = Math.Max(p1.Length, p2.Length);
    double sim = maxLen == 0 ? 1.0 : 1.0 - (double)Math.Abs(p1.Length - p2.Length) / maxLen;
    int charDiff = Math.Abs(p1.Length - p2.Length);

    differences.Add((i + 1, sim, p1.Length, p2.Length, charDiff));
}

// Build HTML report
var sb = new StringBuilder();
sb.Append(@"<html><head><style>
    body { font-family: Arial, sans-serif; margin: 20px; }
    h1 { color: #333; border-bottom: 2px solid #4CAF50; }
    .summary { background: #f0f0f0; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background: #4CAF50; color: white; }
    .ok { background: #c8e6c9; padding: 15px; border-radius: 5px; }
</style></head><body>");

sb.Append("<h1>PDF Comparison Report</h1>");
sb.Append("<div class='summary'>");
sb.Append($"<p><strong>File 1:</strong> {Path.GetFileName("document1.pdf")}</p>");
sb.Append($"<p><strong>File 2:</strong> {Path.GetFileName("document2.pdf")}</p>");
sb.Append($"<p><strong>Pages with differences:</strong> {differences.Count} of {totalPages}</p>");
sb.Append($"<p><strong>Generated:</strong> {DateTime.Now:yyyy-MM-dd HH:mm:ss}</p>");
sb.Append("</div>");

if (differences.Count > 0)
{
    sb.Append("<table><thead><tr><th>Page</th><th>Similarity</th><th>File 1 Length</th><th>File 2 Length</th><th>Char Diff</th></tr></thead><tbody>");
    foreach (var d in differences)
    {
        sb.Append($"<tr><td>{d.Page}</td><td>{d.Similarity:P}</td><td>{d.Len1}</td><td>{d.Len2}</td><td>{d.CharDiff}</td></tr>");
    }
    sb.Append("</tbody></table>");
}
else
{
    sb.Append("<p class='ok'>No differences detected -- files are identical.</p>");
}

sb.Append("</body></html>");

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;

var reportPdf = renderer.RenderHtmlAsPdf(sb.ToString());
reportPdf.MetaData.Author = "PDF Comparison Tool";
reportPdf.MetaData.Title = "PDF Comparison Report";
reportPdf.MetaData.CreationDate = DateTime.Now;

reportPdf.SaveAs("comparison-report.pdf");
Console.WriteLine("Report saved to comparison-report.pdf");
using IronPdf;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;

var pdf1 = PdfDocument.FromFile("document1.pdf");
var pdf2 = PdfDocument.FromFile("document2.pdf");

var differences = new List<(int Page, double Similarity, int Len1, int Len2, int CharDiff)>();
int totalPages = Math.Max(pdf1.PageCount, pdf2.PageCount);

for (int i = 0; i < totalPages; i++)
{
    string p1 = i < pdf1.PageCount ? pdf1.ExtractTextFromPage(i) ?? "" : "";
    string p2 = i < pdf2.PageCount ? pdf2.ExtractTextFromPage(i) ?? "" : "";

    if (p1 == p2) continue;

    int maxLen = Math.Max(p1.Length, p2.Length);
    double sim = maxLen == 0 ? 1.0 : 1.0 - (double)Math.Abs(p1.Length - p2.Length) / maxLen;
    int charDiff = Math.Abs(p1.Length - p2.Length);

    differences.Add((i + 1, sim, p1.Length, p2.Length, charDiff));
}

// Build HTML report
var sb = new StringBuilder();
sb.Append(@"<html><head><style>
    body { font-family: Arial, sans-serif; margin: 20px; }
    h1 { color: #333; border-bottom: 2px solid #4CAF50; }
    .summary { background: #f0f0f0; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background: #4CAF50; color: white; }
    .ok { background: #c8e6c9; padding: 15px; border-radius: 5px; }
</style></head><body>");

sb.Append("<h1>PDF Comparison Report</h1>");
sb.Append("<div class='summary'>");
sb.Append($"<p><strong>File 1:</strong> {Path.GetFileName("document1.pdf")}</p>");
sb.Append($"<p><strong>File 2:</strong> {Path.GetFileName("document2.pdf")}</p>");
sb.Append($"<p><strong>Pages with differences:</strong> {differences.Count} of {totalPages}</p>");
sb.Append($"<p><strong>Generated:</strong> {DateTime.Now:yyyy-MM-dd HH:mm:ss}</p>");
sb.Append("</div>");

if (differences.Count > 0)
{
    sb.Append("<table><thead><tr><th>Page</th><th>Similarity</th><th>File 1 Length</th><th>File 2 Length</th><th>Char Diff</th></tr></thead><tbody>");
    foreach (var d in differences)
    {
        sb.Append($"<tr><td>{d.Page}</td><td>{d.Similarity:P}</td><td>{d.Len1}</td><td>{d.Len2}</td><td>{d.CharDiff}</td></tr>");
    }
    sb.Append("</tbody></table>");
}
else
{
    sb.Append("<p class='ok'>No differences detected -- files are identical.</p>");
}

sb.Append("</body></html>");

var renderer = new ChromePdfRenderer();
renderer.RenderingOptions.MarginTop = 25;
renderer.RenderingOptions.MarginBottom = 25;
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print;

var reportPdf = renderer.RenderHtmlAsPdf(sb.ToString());
reportPdf.MetaData.Author = "PDF Comparison Tool";
reportPdf.MetaData.Title = "PDF Comparison Report";
reportPdf.MetaData.CreationDate = DateTime.Now;

reportPdf.SaveAs("comparison-report.pdf");
Console.WriteLine("Report saved to comparison-report.pdf");
Imports IronPdf
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Text

Dim pdf1 = PdfDocument.FromFile("document1.pdf")
Dim pdf2 = PdfDocument.FromFile("document2.pdf")

Dim differences = New List(Of (Page As Integer, Similarity As Double, Len1 As Integer, Len2 As Integer, CharDiff As Integer))()
Dim totalPages As Integer = Math.Max(pdf1.PageCount, pdf2.PageCount)

For i As Integer = 0 To totalPages - 1
    Dim p1 As String = If(i < pdf1.PageCount, pdf1.ExtractTextFromPage(i), "")
    Dim p2 As String = If(i < pdf2.PageCount, pdf2.ExtractTextFromPage(i), "")

    If p1 = p2 Then Continue For

    Dim maxLen As Integer = Math.Max(p1.Length, p2.Length)
    Dim sim As Double = If(maxLen = 0, 1.0, 1.0 - CDbl(Math.Abs(p1.Length - p2.Length)) / maxLen)
    Dim charDiff As Integer = Math.Abs(p1.Length - p2.Length)

    differences.Add((i + 1, sim, p1.Length, p2.Length, charDiff))
Next

' Build HTML report
Dim sb = New StringBuilder()
sb.Append("<html><head><style>
    body { font-family: Arial, sans-serif; margin: 20px; }
    h1 { color: #333; border-bottom: 2px solid #4CAF50; }
    .summary { background: #f0f0f0; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
    table { border-collapse: collapse; width: 100%; }
    th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
    th { background: #4CAF50; color: white; }
    .ok { background: #c8e6c9; padding: 15px; border-radius: 5px; }
</style></head><body>")

sb.Append("<h1>PDF Comparison Report</h1>")
sb.Append("<div class='summary'>")
sb.Append($"<p><strong>File 1:</strong> {Path.GetFileName("document1.pdf")}</p>")
sb.Append($"<p><strong>File 2:</strong> {Path.GetFileName("document2.pdf")}</p>")
sb.Append($"<p><strong>Pages with differences:</strong> {differences.Count} of {totalPages}</p>")
sb.Append($"<p><strong>Generated:</strong> {DateTime.Now:yyyy-MM-dd HH:mm:ss}</p>")
sb.Append("</div>")

If differences.Count > 0 Then
    sb.Append("<table><thead><tr><th>Page</th><th>Similarity</th><th>File 1 Length</th><th>File 2 Length</th><th>Char Diff</th></tr></thead><tbody>")
    For Each d In differences
        sb.Append($"<tr><td>{d.Page}</td><td>{d.Similarity:P}</td><td>{d.Len1}</td><td>{d.Len2}</td><td>{d.CharDiff}</td></tr>")
    Next
    sb.Append("</tbody></table>")
Else
    sb.Append("<p class='ok'>No differences detected -- files are identical.</p>")
End If

sb.Append("</body></html>")

Dim renderer = New ChromePdfRenderer()
renderer.RenderingOptions.MarginTop = 25
renderer.RenderingOptions.MarginBottom = 25
renderer.RenderingOptions.CssMediaType = IronPdf.Rendering.PdfCssMediaType.Print

Dim reportPdf = renderer.RenderHtmlAsPdf(sb.ToString())
reportPdf.MetaData.Author = "PDF Comparison Tool"
reportPdf.MetaData.Title = "PDF Comparison Report"
reportPdf.MetaData.CreationDate = DateTime.Now

reportPdf.SaveAs("comparison-report.pdf")
Console.WriteLine("Report saved to comparison-report.pdf")
$vbLabelText   $csharpLabel

此方案採用HTML 渲染技術,建立具有自訂樣式的專業報告。 IronPDF 的 CSS 支援允許完全自訂——調整字體、顏色和佈局以匹配企業品牌。 在正式文件工作流程中新增帶有頁碼和時間戳記的頁首和頁尾

PDF對比報告顯示,第一頁列出了兩個相似度為2.60%的文件之間的一個差異,並以結構化格式呈現詳細指標

產生的報告提供了差異的清晰摘要,以及詳細的每頁指標。 您可以擴展報告,使其包含相似度得分的可視化圖表、顯示已更改區域的頁面縮圖以及便於在冗長報告中導航的書籤。 對於存檔級報告,IronPDF 支援PDF/A 格式,以確保長期可讀性並符合文件保存規定。

在 .NET 中進行 PDF 比較的最佳實踐是什麼?

在將 PDF 對比功能投入生產之前,一些模式決定了最終產品是脆弱的原型還是可靠的工具:

妥善處理空值和空白文字。對於僅包含圖像的 PDF 或不包含文字圖層的掃描文檔,ExtractAllText() 可能會返回空字串。 在執行比較邏輯之前,請務必檢查結果是否為空,並決定空對空是否算作"相同"或"不確定"。

比較前請先對文本進行規範化處理。不同的 PDF 產生器對於相同的視覺內容可能會產生略有不同的空白模式、行尾符或 Unicode 規範化結果。 在比較之前執行 text.Trim().Replace("\r\n", "\n") 可以防止純粹的表面差異造成的誤報。

在業務流程中,應使用相似度閾值而非完全匹配。 98 % 的相似度得分很可能意味著兩份文件在功能上完全相同,即使其中一個文件的時間戳記或自動產生的 ID 略有不同。 定義一個適合您領域的閾值,而不是要求字元完全相等。

將比較結果與文件元資料記錄下來。將檔案名稱、大小、修改日期和相似度分數儲存在結構化日誌中。 這樣就產生了審計追蹤記錄,合規團隊無需重新運行比較即可進行審查。

考慮編碼和字體問題。有些 PDF 檔案對其文字層使用自訂編碼表。 IronPDF 以 Chrome 為基礎的引擎可以正確處理大多數情況,但如果您看到亂碼文字輸出,請檢查來源 PDF 是否使用了非標準字型編碼。 故障排除指南涵蓋了常見的提取問題及其解決方法。

對於建立生產文件比較管道的團隊來說, Microsoft 關於 .NET 中非同步模式的文件為建置平行文件處理提供了有用的指導。 如果您需要了解給定文件的文字圖層中可以或不可以出現哪些類型的內容,那麼也值得查閱PDF 規範(ISO 32000)

如何立即開始使用 PDF 比對功能?

C# 中的 PDF 對比是一項實用技能,它能為數十個行業的文件自動化鋪平道路——而 IronPDF 讓任何 .NET 開發人員都能輕鬆上手。您可以從基本的文本提取範例入手,根據需要擴展到逐頁分析,並使用 HTML 報告產生器向利害關係人提供專業的輸出結果。

IronPDF PDF 功能對比總結
情境 方法 關鍵方法
基本文本比較 從兩份文件中提取全文並比較字串。 ExtractAllText()
逐頁分析 逐頁比較,以確定更改位置。 ExtractTextFromPage()
批次比較 將多個文件與單一參考文件進行比較 PdfDocument.FromFile()
受密碼保護的文件 直接將密碼傳遞給檔案載入器-無需預先解密 PdfDocument.FromFile(path, password)
報告生成 將 HTML 對比摘要轉換為樣式化的 PDF 報告 ChromePdfRenderer.RenderHtmlAsPdf()

IronPDF 功能概述,展示了像素級完美渲染、5 分鐘快速設定以及與支援技術的跨平台相容性

下載免費試用版,即可立即開始使用 IronPDF 進行構建——30 天免費試用無需信用卡。 快速入門指南可在五分鐘內引導您完成初始設定。 準備投入生產時,請查看許可頁面,選擇適合您團隊規模和部署要求的選項。

如需更深入學習,請探索涵蓋 PDF 建立、編輯和操作的完整教學系列API 參考提供了詳細的方法文檔,範例部分演示了實際應用,包括表單處理浮水印

IronPDF 許可頁面顯示四個定價等級(Lite、Plus、Professional 和 Unlimited),每個等級對開發者、地點和項目數量都有不同的限制,此外還提供促銷優惠和 30 天退款保證。

常見問題解答

如何使用C#比較兩個PDF檔案?

您可以使用 C# 透過 IronPDF 強大的 PDF 比較功能來比較兩個 PDF 文件,該功能可讓您識別兩個 PDF 文件之間的文字、圖像和佈局差異。

使用 IronPDF 進行 PDF 比對有哪些好處?

IronPDF 提供了一種簡單且有效率的 PDF 檔案比較方法,確保差異檢測的準確性。它支援多種比較模式,並可與 C# 專案無縫整合。

IronPDF 能夠處理用於比較的大型 PDF 文件嗎?

是的,IronPDF 的設計宗旨是高效處理大型 PDF 文件,因此非常適合比較內容豐富的文檔,而不會影響效能。

IronPDF是否支援PDF文件的視覺化比較?

IronPDF 可以透過突出顯示佈局和圖像的差異來對 PDF 進行視覺化比較,從而提供文件之間變化的全面視圖。

可以使用 IronPDF 自動化 PDF 比較嗎?

是的,您可以使用 IronPDF 在 C# 應用程式中自動執行 PDF 比較過程,這對於需要頻繁或批次比較的場景來說非常理想。

IronPDF 可以偵測 PDF 檔案中的哪些類型差異?

IronPDF 可以偵測文字、圖形和佈局差異,確保對 PDF 檔案的全部內容進行徹底比較。

IronPDF如何確保PDF比對的準確性?

IronPDF 使用先進的演算法仔細比較 PDF 內容,從而確保準確性,最大限度地降低忽略細微差異的風險。

我能否將 IronPDF 與其他 .NET 應用程式集成,以進行 PDF 對比?

是的,IronPDF 旨在與 .NET 應用程式無縫集成,使開發人員能夠將 PDF 比較功能整合到他們現有的軟體解決方案中。

使用 IronPDF 是否需要有 PDF 比對的經驗?

無需任何經驗。 IronPDF 提供使用者友善的工具和全面的文檔,即使您是 PDF 操作新手,也能引導您完成 PDF 比較流程。

IronPDF的PDF對比功能是否有試用版或試用版?

是的,IronPDF 提供免費試用版,讓您在購買前可以探索並測試其 PDF 比較功能。

Curtis Chau
技術作家

Curtis Chau 擁有卡爾頓大學計算機科學學士學位,專注於前端開發,擅長於 Node.js、TypeScript、JavaScript 和 React。Curtis 熱衷於創建直觀且美觀的用戶界面,喜歡使用現代框架並打造結構良好、視覺吸引人的手冊。

除了開發之外,Curtis 對物聯網 (IoT) 有著濃厚的興趣,探索將硬體和軟體結合的創新方式。在閒暇時間,他喜愛遊戲並構建 Discord 機器人,結合科技與創意的樂趣。

鋼鐵支援團隊

我們每週 5 天,每天 24 小時在線上。
聊天
電子郵件
打電話給我