Skip to content

Latest commit

 

History

History
494 lines (399 loc) · 15.9 KB

File metadata and controls

494 lines (399 loc) · 15.9 KB
categories
Java Development
date 2025-12-20
description 學習如何使用 GroupDocs.Comparison 在 Java 中比較 PDF 檔案。此一步一步的教學涵蓋文件比較的最佳實踐、程式碼範例、效能技巧與疑難排解。
keywords java compare documents programmatically, java document diff library, compare two files java, java text comparison, groupdocs comparison java, document version control java, compare pdf files java, document comparison best practices
lastmod 2025-12-20
linktitle Java Document Comparison Guide
tags
java
document-comparison
groupdocs
file-comparison
version-control
title 如何在 Java 中以程式方式比較 PDF 檔案
type docs
url /zh-hant/java/basic-comparison/java-document-comparison-groupdocs-comparison/
weight 1

如何在 Java 中以程式方式比較 PDF 檔案

介紹

有沒有曾經手動比較兩個文件版本,眯著眼在螢幕上找出差異?如果你是 Java 開發者,可能已經多次遇到這個挑戰。無論是建立內容管理系統、實作版本控制,或只是需要追蹤法律文件的變更,compare pdf files java 都能為你節省大量繁瑣的時間。

好消息是?使用 GroupDocs.Comparison for Java,你可以自動化整個流程。這份完整指南將帶你了解在 Java 應用程式中實作文件比較所需的一切。你將學會如何偵測變更、提取座標,甚至處理不同的檔案格式——全部以乾淨且高效的程式碼完成。

完成本教學後,你將對文件比較技術有扎實的了解,並能在自己的專案中實作。讓我們開始吧!

快速回答

  • 什麼函式庫可以在 Java 中比較 PDF 檔案? GroupDocs.Comparison for Java.
  • 我需要授權嗎? 免費試用可用於學習;正式環境需購買完整授權。
  • 需要哪個 Java 版本? 最低支援 Java 8,建議使用 Java 11 以上。
  • 可以在不寫入磁碟的情況下比較文件嗎? 可以,使用串流在記憶體中比較。
  • 如何取得變更座標?CompareOptions 中啟用 setCalculateCoordinates(true)

什麼是 “compare pdf files java”?

在 Java 中比較 PDF 檔案指的是以程式方式分析兩個 PDF(或其他)文件,找出新增、刪除與修改的部分。此過程會回傳結構化的變更清單,可用於報表、視覺標示或自動化工作流程。

為什麼使用 GroupDocs.Comparison for Java?

  • 速度與準確度: 支援超過 60 種格式,保持高度忠實度。
  • 內建文件比較最佳實踐,例如忽略樣式變更或偵測內容移動。
  • 可擴充性: 可處理大型檔案、串流與雲端儲存。
  • 可擴充性: 可自訂比較選項以符合任何業務規則。

前置條件與所需資源

技術需求

  • Java Development Kit (JDK) – 版本 8 或以上(建議使用 Java 11 以上以獲得更佳效能)
  • IDE – IntelliJ IDEA、Eclipse 或你喜愛的 Java IDE
  • Maven – 用於相依管理(大多數 IDE 內建)

知識前提

  • 基本的 Java 程式設計(類別、方法、try‑with‑resources)
  • 熟悉 Maven 相依(我們會一步步說明設定)
  • 了解檔案 I/O 操作(有助但非必須)

測試文件

準備好幾個範例文件——Word、PDF 或文字檔都很適合。若沒有,可自行建立兩個內容略有差異的簡易文字檔來測試。

設定 GroupDocs.Comparison for Java

Maven 設定

首先,將 GroupDocs 的儲存庫與相依加入你的 pom.xml。請保持區塊內容與示範完全相同:

<repositories>
   <repository>
      <id>repository.groupdocs.com</id>
      <name>GroupDocs Repository</name>
      <url>https://releases.groupdocs.com/comparison/java/</url>
   </repository>
</repositories>

<dependencies>
   <dependency>
      <groupId>com.groupdocs</groupId>
      <artifactId>groupdocs-comparison</artifactId>
      <version>25.2</version>
   </dependency>
</dependencies>

小技巧:請隨時在 GroupDocs 官方網站確認最新版本。本文撰寫時的版本為 25.2,但更新的版本可能包含額外功能或錯誤修正。

常見設定問題與解決方案

  • 「找不到儲存庫」 – 確認 <repositories> 區塊位於 <dependencies> 之前。
  • 「ClassNotFoundException」 – 重新整理 Maven 相依(IntelliJ:Maven → Reload project)。

授權選項說明

  1. 免費試用 – 適合學習與小型專案。
  2. 暫時授權 – 申請 30 天金鑰以延長評估。
  3. 完整授權 – 正式環境必須使用。

基本專案結構

your-project/
├── src/main/java/
│   └── com/yourcompany/comparison/
│       └── DocumentComparison.java
├── src/test/resources/
│   ├── source.docx
│   └── target.docx
└── pom.xml

核心實作:逐步指南

了解 Comparer 類別

Comparer 類別是文件比較的主要介面:

import com.groupdocs.comparison.Comparer;

try (Comparer comparer = new Comparer("sourceFilePath")) {
    comparer.add("targetFilePath");
    // Your comparison logic goes here
}

為什麼使用 try‑with‑resources? Comparer 實作了 AutoCloseable,因此此寫法能確保記憶體與檔案句柄正確釋放——在處理大型 PDF 時非常重要。

功能 1:取得變更座標

此功能可精確告訴每筆變更發生的位置——就像文件編輯的 GPS 座標。

何時使用

  • 建構視覺差異檢視器
  • 實作精確的稽核報告
  • 在 PDF 檢視器中標示變更以供法律審查

實作細節

import com.groupdocs.comparison.Comparer;
import com.groupdocs.comparison.result.ChangeInfo;

String sourceFilePath = "path/to/source.docx";
String targetFilePath = "path/to/target.docx";

try (Comparer comparer = new Comparer(sourceFilePath)) {
    // Add the target document for comparison.
    comparer.add(targetFilePath);

啟用座標計算:

import com.groupdocs.comparison.options.CompareOptions;

final Path resultPath = comparer.compare(
        new CompareOptions.Builder()
                .setCalculateCoordinates(true)
                .build());

提取並處理變更資訊:

ChangeInfo[] changes = comparer.getChanges();
for (ChangeInfo change : changes) {
    System.out.printf("Change Type: %s, X: %f, Y: %f, Text: %s%n",
            change.getType(), change.getBox().getX(), change.getBox().getY(), change.getText());
}

效能說明:計算座標會增加額外負擔,僅在需要時才啟用。

功能 2:從檔案路徑取得變更

若只需要簡單的變更清單,這是首選方法。

適用情境

  • 快速變更摘要
  • 簡易差異報告
  • 批次處理多組文件對比

實作

try (Comparer comparer = new Comparer(sourceFilePath)) {
    comparer.add(targetFilePath);

執行比較而不使用額外選項:

final Path resultPath = comparer.compare();
ChangeInfo[] changes = comparer.getChanges();
System.out.println("\nCount of changes: " + changes.length);
}

最佳實踐:務必檢查 changes 陣列的長度——若為空陣列表示文件完全相同。

功能 3:使用串流

適用於 Web 應用、微服務,或任何檔案位於記憶體或雲端的情境。

常見使用情境

  • 在 Spring Boot 控制器中處理檔案上傳
  • 從 AWS S3 或 Azure Blob Storage 取得文件
  • 處理儲存在資料庫 BLOB 欄位的 PDF

串流實作

import java.io.FileInputStream;
import java.io.InputStream;

try (InputStream sourceStream = new FileInputStream(sourceFilePath);
     InputStream targetStream = new FileInputStream(targetFilePath);
     Comparer comparer = new Comparer(sourceStream)) {
    comparer.add(targetStream);

以相同的比較呼叫繼續:

final Path resultPath = comparer.compare();
ChangeInfo[] changes = comparer.getChanges();
System.out.println("\nCount of changes: " + Arrays.toString(changes).length);
}

記憶體提示:try‑with‑resources 區塊會自動關閉串流,避免大型 PDF 產生記憶體洩漏。

功能 4:擷取目標文字

有時需要取得變更的精確文字——非常適合變更日誌或通知。

實務應用

  • 建構變更日誌 UI
  • 以插入/刪除的文字發送電子郵件警示
  • 進行內容合規稽核

實作

try (Comparer comparer = new Comparer(sourceFilePath)) {
    comparer.add(targetFilePath);
    
    final Path resultPath = comparer.compare();
    ChangeInfo[] changes = comparer.getChanges();

    for (ChangeInfo change : changes) {
        String text = change.getText();
        System.out.println(text);
    }
}

篩選提示:聚焦特定變更類型:

for (ChangeInfo change : changes) {
    if (change.getType() == ComparisonAction.INSERT) {
        System.out.println("Added: " + change.getText());
    }
}

常見陷阱與避免方法

1. 檔案路徑問題

問題:即使檔案存在仍出現「File not found」。
解決方案:開發時使用絕對路徑或確認工作目錄。Windows 上請對反斜線做跳脫或改用正斜線。

// Good
String path = "C:/Users/yourname/documents/test.docx";
// Or
String path = "C:\\Users\\yourname\\documents\\test.docx";

2. 大檔案記憶體洩漏

問題:大型 PDF 產生 OutOfMemoryError
解決方案:始終使用 try‑with‑resources,並考慮使用串流 API 或分塊處理文件。

3. 不支援的檔案格式

問題:某些格式拋出例外。
解決方案:先檢查支援的格式清單。GroupDocs 支援超過 60 種格式,實作前請先確認。

4. 效能問題

問題:比較耗時過長。
解決方案

  • 除非必要,請停用座標計算。
  • 使用適當的 CompareOptions
  • 盡可能將批次作業平行化。

效能優化技巧

選擇適當的選項

CompareOptions options = new CompareOptions.Builder()
    .setCalculateCoordinates(false) // Only enable when needed
    .setDetectStyleChanges(false)   // Skip formatting if you only care about content
    .build();

記憶體管理

  • 以批次方式處理文件,避免一次載入全部。
  • 大檔案使用串流 API。
  • finally 區塊中正確清理,或依賴 try‑with‑resources。

快取策略

對於頻繁比較的文件,快取比較結果:

// Pseudo-code for caching concept
String cacheKey = generateCacheKey(sourceFile, targetFile);
if (cache.contains(cacheKey)) {
    return cache.get(cacheKey);
}

真實案例與解決方案

情境 1:內容管理系統

public class ArticleVersionComparison {
    public List<ChangeInfo> compareVersions(String oldVersion, String newVersion) {
        try (Comparer comparer = new Comparer(oldVersion)) {
            comparer.add(newVersion);
            final Path result = comparer.compare();
            return Arrays.asList(comparer.getChanges());
        } catch (Exception e) {
            log.error("Failed to compare article versions", e);
            return Collections.emptyList();
        }
    }
}

情境 2:自動化品質保證

public boolean validateReportAgainstTemplate(InputStream report, InputStream template) {
    try (Comparer comparer = new Comparer(template)) {
        comparer.add(report);
        comparer.compare();
        ChangeInfo[] changes = comparer.getChanges();
        
        // Only allow certain types of changes
        return Arrays.stream(changes)
                .allMatch(change -> isAllowedChange(change));
    } catch (Exception e) {
        return false;
    }
}

情境 3:批次文件處理

public void processBatchComparison(List<DocumentPair> documents) {
    documents.parallelStream().forEach(pair -> {
        try (Comparer comparer = new Comparer(pair.getSource())) {
            comparer.add(pair.getTarget());
            Path result = comparer.compare();
            // Process results...
        } catch (Exception e) {
            log.error("Failed to process document pair: " + pair, e);
        }
    });
}

疑難排解常見問題

比較結果似乎不正確

  • 檢查文件編碼(UTF‑8 與其他編碼)。
  • 留意隱藏字元或格式差異。

效能下降

  • 使用效能分析找出瓶頸。
  • 調整 CompareOptions,跳過不必要的功能。

生產環境整合問題

  • 檢查 classpath 與相依版本。
  • 確認授權檔正確放置於伺服器上。
  • 檢查檔案權限與網路存取。

進階功能與最佳實踐

處理不同檔案格式

public boolean isFormatSupported(String filePath) {
    String extension = getFileExtension(filePath);
    List<String> supportedFormats = Arrays.asList(
        ".docx", ".pdf", ".txt", ".rtf", ".odt", // Add more as needed
    );
    return supportedFormats.contains(extension.toLowerCase());
}

處理大型文件

CompareOptions largeDocOptions = new CompareOptions.Builder()
    .setCalculateCoordinates(false)  // Saves memory
    .setDetectStyleChanges(false)    // Focuses on content only
    .setWordsLimit(1000)             // Limits processing scope
    .build();

錯誤處理模式

public ComparisonResult compareDocuments(String source, String target) {
    try (Comparer comparer = new Comparer(source)) {
        comparer.add(target);
        Path result = comparer.compare();
        
        return ComparisonResult.success(comparer.getChanges());
        
    } catch (SecurityException e) {
        log.error("Access denied when comparing documents", e);
        return ComparisonResult.failure("Access denied");
    } catch (IOException e) {
        log.error("IO error during document comparison", e);
        return ComparisonResult.failure("File access error");
    } catch (Exception e) {
        log.error("Unexpected error during comparison", e);
        return ComparisonResult.failure("Comparison failed");
    }
}

常見問答

Q: GroupDocs.Comparison 最低需要哪個 Java 版本?
A: 最低支援 Java 8,但建議使用 Java 11 以上以獲得更佳效能與安全性。

Q: 可以同時比較超過兩個文件嗎?
A:

try (Comparer comparer = new Comparer(sourceDocument)) {
    comparer.add(targetDocument1);
    comparer.add(targetDocument2);
    comparer.add(targetDocument3);
    // Now compare against all targets
}

Q: 如何處理非常大的文件(100 MB 以上)?
A:

  • 除非必要,停用座標計算。
  • 使用串流 API。
  • 以區塊或頁面方式處理文件。
  • 密切監控記憶體使用情況。

Q: 是否有方式在輸出中視覺化標示變更?
A:

CompareOptions options = new CompareOptions.Builder()
    .setShowInsertedContent(true)
    .setShowDeletedContent(true)
    .setGenerateOutputDocument(true)
    .build();

Q: 如何處理受密碼保護的文件?
A:

LoadOptions loadOptions = new LoadOptions();
loadOptions.setPassword("your-password");

try (Comparer comparer = new Comparer(protectedDocument, loadOptions)) {
    // Comparison logic here
}

Q: 能自訂變更偵測的方式嗎?
A:

CompareOptions options = new CompareOptions.Builder()
    .setDetectStyleChanges(false)     // Ignore formatting changes
    .setSensitivityOfComparison(100)  // Adjust sensitivity (0‑100)
    .build();

Q: 與 Spring Boot 整合的最佳方式是什麼?
A:

@Service
public class DocumentComparisonService {
    
    public ComparisonResult compare(MultipartFile source, MultipartFile target) {
        // Implementation using the techniques from this guide
    }
}

其他資源

最後更新: 2025-12-20
測試環境: GroupDocs.Comparison 25.2 for Java
作者: GroupDocs