如何在 PDF 中使用 Java 建立條碼簽章

在本教學中,您將學習如何使用 Java 及 GroupDocs.Signature 建立條碼簽章於 PDF 檔案。條碼簽章嵌入機器可讀的識別碼,具備防篡改且易於掃描的特性——非常適合合約、證書、發票以及任何需要可靠驗證的文件。

快速解答

  • 什麼是條碼簽章? 條碼嵌入於 PDF 中,儲存結構化資料,可由掃描器或軟件讀取。
  • 建議使用哪種條碼類型? Code128,因為它能緊湊地處理字母與數字資料。
  • 我需要授權嗎? 免費試用可用於測試;正式環境需購買完整授權。
  • 我可以在任何頁面尺寸上放置條碼嗎? 可以——使用百分比定位以自動縮放。
  • 條碼是向量圖形嗎? 是的,它只會在 PDF 中增加少量 KB,且在任何解析度下都保持清晰。

什麼是條碼簽章?

條碼簽章是一種向量條碼,直接嵌入於 PDF 頁面中,既作為視覺元素,又作為可稍後驗證的加密簽章。它儲存結構化資料,如 ID 或時間戳,確保文件完整性,同時提供機器可讀的參考。

為何條碼簽章對您的 PDF 重要

條碼簽章為 PDF 提供緊湊的機器可讀識別碼,可即時掃描,省去手動輸入資料並降低錯誤。由於以向量圖形嵌入,無論解析度如何都保持清晰,且僅增加少量 KB。這種可讀性、防篡改與小檔案大小的結合,使其非常適合合約、發票、證書以及任何需要可靠驗證的文件。

您可能曾遇到這樣的挑戰:需要在 PDF 中加入既機器可讀又防篡改的唯一識別碼。也許您正在開發文件管理系統、處理證書,或處理需要日後驗證的合約。

這正是條碼簽章發揮作用的地方。與簡單的文字印章不同,條碼可嵌入結構化資料,讓掃描器(以及您的軟件)即時讀取。此外,結合 GroupDocs.Signature for Java 的 PDF 簽署,您即可在不需複雜資料庫查詢的情況下,強力追蹤與驗證文件。

在本指南中,您將完整學會如何在 Java PDF 中實作條碼簽章——從基本設定到具彈性定位的生產就緒程式碼。無論您是構建發票系統、證書產生器或合約管理平台,最終都能掌握所需全部知識。

您將掌握:

  • 在數分鐘內設定 GroupDocs.Signature for Java
  • 建立 Code128 條碼簽章(以及為何它常是最佳選擇)
  • 使用百分比布局定位條碼,適用於任何 PDF 大小
  • 避免開發者常見的陷阱
  • 正確測試您的實作

如何在 Java 中建立條碼簽章

在 Java 中建立條碼簽章的流程包括載入目標 PDF、設定條碼選項(如資料、類型、尺寸與位置),然後套用簽章以產生新文件。GroupDocs.Signature 會處理渲染與加密綁定,您只需提供所需參數並管理檔案路徑。

前置條件與環境清單

在開始之前,請確認您已備妥以下項目:

  • Java Development Kit (JDK) 8 或更新版本 – 所有 GroupDocs Java 函式庫的必要條件。
  • Maven 或 Gradle – 用於管理 GroupDocs.Signature 相依性。
  • IDE(如 IntelliJ IDEA、Eclipse 或配有 Java 擴充功能的 VS Code)。
  • GroupDocs.Signature for Java(建議使用 23.12 或更新版本)。
  • 基本的 Java 知識 – 您應能熟練建立類別、處理例外以及使用檔案 I/O。

在專案中設定 GroupDocs.Signature

將函式庫加入專案相當簡單。選擇您的建置工具:

對於 Maven 使用者,在 pom.xml 中加入以下相依性:

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-signature</artifactId>
    <version>23.12</version>
</dependency>

使用 Gradle 嗎? 在 build.gradle 中加入此行:

implementation 'com.groupdocs:groupdocs-signature:23.12'

偏好手動設定? 直接從 GroupDocs.Signature for Java releases 下載 JAR,並加入至 classpath。

取得授權設定

在正式投入生產前,您需要處理授權:

  • 免費試用: 適合測試——可從 GroupDocs 官方網站取得,以探索核心功能。
  • 臨時授權: 需要更多評估時間?可申請 30 天臨時授權。
  • 完整授權: 已準備好投入生產?購買授權以獲得無限制使用。

以下是一個快速檢查,以確保一切正常運作:

Signature signature = new Signature("sample.pdf");
System.out.println("Signature object created successfully.");

如果執行無錯誤,即表示已完成設定!

如何在 Java 中建立條碼簽章

現在進入有趣的部分——讓我們為 PDF 加上條碼簽章。我們會將流程拆解為一步步的小步驟,讓您清楚了解每個階段的運作。

步驟 1:初始化 Signature 物件

定義說明: Signature 類別是 GroupDocs.Signature 用於載入、修改與儲存 PDF 文件的入口點。

首先,您需要告訴 GroupDocs 您正在處理哪個 PDF:

Signature signature = new Signature("input.pdf");

此程式碼的作用: Signature 物件會將您的 PDF 載入記憶體,並為後續修改做好準備。請確保檔案路徑正確——常見問題是 Windows 上使用單斜線而未轉義(請使用 \\ 或直接使用正斜線,跨平台皆可)。

步驟 2:設定條碼選項(如何新增條碼)

定義說明: BarcodeSignOptions 包含在 PDF 中呈現條碼所需的所有設定。

現在讓我們使用您的資料建立條碼簽章:

BarcodeSignOptions options = new BarcodeSignOptions("12345678");
options.setEncodeType(BarcodeEncodeType.Code128);
  • "12345678" 為條碼資料——可作為訂單編號、證書號碼或任何您需要的識別碼。
  • Code128 為編碼類型(稍後會說明如何選擇合適的類型)。

專業提示: Code128 能同時處理數字與字母,適用於大多數情境。若僅需數字,Code39 可能較簡單,但 Code128 提供更高彈性。

步驟 3:定位條碼(如何以條碼簽署 PDF)

定義說明: SignatureOptions 提供版面屬性,如頁碼、尺寸與對齊方式。

這正是 GroupDocs 的優勢所在——使用百分比定位可確保條碼在任何 PDF 大小上皆顯示良好:

options.setLeft(10);   // 10% from the left edge
options.setTop(90);    // 90% from the bottom edge (near the footer)
options.setWidth(30);  // 30% of page width
options.setHeight(10); // 10% of page height
options.setPageNumber(1);

為何使用百分比重要: 想像您同時簽署 A4 文件與 legal 大小的表單。使用百分比定位,條碼會自動縮放,兩者外觀一致。若使用固定像素值,條碼在大文件上會過小,或在小文件上過大。

實務範例: 在 A4 頁面(595 × 842 點)上,30% 寬度的條碼約為 180 點寬;在 legal 頁面(612 × 1008 點)上,約為 184 點寬——自動成比例。

步驟 4:簽署並儲存文件(如何在 PDF 中加入條碼)

現在正式套用簽章並儲存檔案:

signature.sign(outputPath, options);

重要說明: 輸出目錄必須事先存在。GroupDocs 不會自動建立子目錄,請先自行建立或在程式碼中處理:

new File("output").mkdirs();

如果發生錯誤該怎麼辦? 請將此段落放入 try‑catch 區塊:

try {
    signature.sign("signed.pdf", options);
} catch (Exception e) {
    e.printStackTrace();
}

為您的需求選擇合適的條碼類型(產生 Code128 條碼)

GroupDocs 支援多種條碼格式,選擇合適的類型相當重要。以下是實用比較:

Code128(我們的預設選擇):

  • 適用情境: 混合字母與數字資料(如「INV2024-001」的 ID)
  • 容量: 最多 128 個 ASCII 字元
  • 為何優勝: 緊湊、廣泛支援,能同時處理字母與數字
  • 使用時機: 需要彈性且不確定要編碼的資料類型時

Code39:

  • 適用情境: 簡單的字母與數字碼
  • 容量: 43 個字元(A‑Z、0‑9 以及部分符號)
  • 考慮原因: 舊式掃描器通常較好支援
  • 使用時機: 與舊系統整合或簡潔性比資料密度更重要時

QR Code:

  • 適用情境: 大量資料(URL、JSON 內容)
  • 容量: 最多 3 KB 資料
  • 為何強大: 可儲存複雜資料結構,內建錯誤更正
  • 使用時機: 需要嵌入結構化資料或 URL 時

EAN/UPC:

  • 適用情境: 商品識別
  • 容量: 固定長度數字碼(8‑13 位)
  • 使用時機: 零售或庫存系統

快速決策指南:

  • 需要字母與數字? → Code128
  • 只需數字,保持簡單? → Code39
  • 大量資料或 URL? → QR Code
  • 零售/商品編碼? → EAN/UPC

常見陷阱與避免方法(防篡改條碼)

以下是開發者最常遇到的問題(讓您免於踩雷):

問題 1:條碼定位不正確

徵兆: 條碼出現在意外位置或被截斷。
常見原因:

  • 在不同頁面尺寸上使用像素值
  • 忘記 PDF 座標系統是從左下角開始,而非左上角
  • 邊距將內容推至可視區域之外
    解決方案: 為保持一致,請始終使用百分比定位:
options.setLeft(5);
options.setTop(95);
options.setWidth(40);
options.setHeight(12);

問題 2:條碼文字無法辨識

徵兆: 雖然條碼文字顯示,但掃描器無法讀取。
原因:

  • 條碼尺寸對資料量而言過小
  • 資料使用了錯誤的編碼類型
  • 條與背景之間對比度不足
    解決方案: 將條碼尺寸與資料長度匹配。對於 10‑15 個字元的 Code128,建議寬度至少佔頁面寬度的 8‑10%。

問題 3:檔案路徑例外

徵兆: FileNotFoundException 或類似錯誤。
原因:

  • 使用單斜線的硬編碼 Windows 路徑
  • 輸出目錄不存在
  • 檔案權限問題
    解決方案: 使用正斜線(跨平台皆可),並先建立目錄:
Path output = Paths.get("output/signed.pdf");
Files.createDirectories(output.getParent());

問題 4:大型 PDF 記憶體問題

徵兆: 處理大型文件時發生記憶體不足錯誤。
解決方案: 完成後關閉 Signature 物件以釋放資源:

signature.close();

測試您的條碼實作

部署前,請確保條碼實際可用。以下是實用測試清單:

1. 目視檢查測試

開啟已簽署的 PDF,檢查:

  • 條碼是否可見且定位正確?
  • 是否清晰(非模糊或像素化)?
  • 周圍是否有足夠的留白?

2. 掃描測試

使用手機上的條碼掃描應用程式(如「Barcode Scanner」或「QR & Barcode Reader」)驗證:

  • 掃描器能讀取條碼
  • 解碼後的資料與您編碼的相符
  • 能在不同角度與距離下讀取

3. 跨平台測試

在不同裝置上開啟您的 PDF:

  • Windows(Adobe Reader、Chrome)
  • Mac(Preview、Chrome)
  • 行動裝置(iOS、Android)
    確保條碼在所有平台上皆正確呈現。

4. 自動化測試程式碼

以下是一段簡易測試程式碼:

Signature testSignature = new Signature("signed.pdf");
List<BarcodeSignature> signatures = testSignature.search(BarcodeSignature.class);
if (signatures.size() > 0) {
    System.out.println("Barcode found: " + signatures.get(0).getText());
}

條碼簽章的實務應用案例

讓我們看看此技術在實務系統中的亮點:

1. 證書產生與驗證

情境: 您正在建置一個發放結業證書的培訓平台。
實作方式: 產生唯一的證書 ID(例如「CERT‑2024‑00123」),並以 Code128 條碼嵌入右下角。掃描條碼即可讓 API 即時取得證書細節,省去手動輸入。

2. 發票追蹤系統

情境: 您的公司每月處理數千張發票。
實作方式: 將發票號碼與到期日以 QR code 形式加入,放置於掃描設備易於讀取的位置。自動分揀系統即可在無需人工介入的情況下處理發票,將處理時間從數小時縮短至數分鐘。

3. 法律合約管理

情境: 律師事務所需要追蹤合約版本與修訂。
實作方式: 每個合約版本皆附加包含合約 ID、版本號與簽署日期的唯一條碼識別碼。審核時掃描即可自動取得完整版本歷史。

4. 醫療紀錄安全

情境: 醫院希望防止未授權的紀錄存取。
實作方式: 在條碼中嵌入患者 ID 與紀錄建立時間戳。只有經驗證的裝置才能解碼並存取完整紀錄,且每次掃描都會產生合規審計日誌。

效能優化技巧(Java 文件安全)

簽署大量 PDF 時,效能相當重要。以下提供幾項讓系統順暢運作的技巧:

批次處理策略

與其一次簽署單一文件,不如批次處理:

for (String filePath : pdfList) {
    Signature batchSignature = new Signature(filePath);
    batchSignature.sign(outputPath, options);
    batchSignature.close();
}

此做法的好處: 重複使用 options 物件並正確關閉資源,可防止記憶體洩漏。

大型 PDF 記憶體管理

針對大於 50 MB 的 PDF:

  • 依序處理,而非一次載入多個。
  • 使用 try‑with‑resources 確保資源釋放。
  • 監控堆積大小,必要時調整 JVM 參數,例如 -Xmx2g。

快取常用條碼

若大量文件使用相同條碼,請快取 BarcodeSignOptions 實例:

BarcodeSignOptions cachedOptions = new BarcodeSignOptions("STATIC_ID");
cachedOptions.setEncodeType(BarcodeEncodeType.Code128);

何時使用條碼簽章(以及何時不適合)

理想情境:

  • 需要機器可讀的文件識別碼。
  • 文件將被自動掃描或處理。
  • 想要防篡改追蹤,且不使用數位憑證。
  • 需要與現有條碼基礎設施整合。

不適合的情況:

  • 需要具法律效力的數位簽章(應改用數位憑證)。
  • 文件僅供人類閱讀(簡單文字浮水印即可)。
  • 文件極小,條碼會佔據過多版面。
  • 安全需求要求加密——條碼是可見且任何人皆可掃描的。

可以結合兩種方式嗎? 當然可以!許多系統同時使用條碼簽章進行追蹤,並以數位簽章確保法律效力。

常見問答

Q: 我可以在同一個 PDF 中使用不同的條碼類型嗎?
A: 可以!對每種條碼類型呼叫 signature.sign() 多次,使用不同的 BarcodeSignOptions。只要確保它們不重疊即可。

Q: 如何處理包含特殊字元的條碼?
A: Code128 能良好處理大多數 ASCII 字元。若需 Unicode 或複雜資料,請改用 QR code——支援 UTF‑8 編碼。

Q: Code128 條碼最多能儲存多少資料?
A: 理論上可達 128 個字元,但超過 30‑40 個字元可讀性會顯著下降。若資料較大,請使用 QR code。

Q: 加入條碼會顯著增加 PDF 檔案大小嗎?
A: 不會明顯增加——條碼為向量圖形,通常僅增加 5‑20 KB(視尺寸與複雜度而定)。

Q: 我可以旋轉條碼或垂直放置嗎?
A: 可以!使用 options.setRotationAngle(90) 旋轉條碼,適合放置於邊緣。

Q: 如何讓條碼出現在多頁 PDF 的每一頁?
A: 迭代頁面,對每頁套用簽章。請參考 GroupDocs 文件中的 PagesSetup 類別,以控制簽署的頁面。

Q: 若條碼掃描器無法讀取產生的條碼該怎麼辦?
A: 首先確認掃描器支援所選條碼類型。接著增大條碼尺寸——大多數掃描問題源於條碼過小。建議寬度至少 1 吋(2.54 cm)以確保可靠讀取。

其他資源

文件說明:

下載與授權:

社群與支援:

最後更新: 2026-07-20
測試環境: GroupDocs.Signature 23.12(Java)
作者: GroupDocs

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-signature</artifactId>
    <version>23.12</version>
</dependency>
implementation 'com.groupdocs:groupdocs-signature:23.12'
import com.groupdocs.signature.Signature;

public class QuickTest {
    public static void main(String[] args) {
        try {
            Signature signature = new Signature("test-document.pdf");
            System.out.println("GroupDocs.Signature is ready to go!");
        } catch (Exception e) {
            System.err.println("Setup issue: " + e.getMessage());
        }
    }
}
String filePath = "YOUR_DOCUMENT_DIRECTORY/sample.pdf";
Signature signature = new Signature(filePath);
import com.groupdocs.signature.options.sign.BarcodeSignOptions;
import com.groupdocs.signature.domain.barcodes.BarcodeTypes;

BarcodeSignOptions options = new BarcodeSignOptions("12345678");
options.setEncodeType(BarcodeTypes.Code128);
import com.groupdocs.signature.domain.enums.MeasureType;
import com.groupdocs.signature.domain.Padding;

// Use percentages instead of fixed pixels
options.setLocationMeasureType(MeasureType.Percents);
options.setLeft(5);  // 5% from the left edge
options.setTop(5);   // 5% from the top

// Size it proportionally too
options.setSizeMeasureType(MeasureType.Percents);
options.setWidth(10);  // 10% of page width
options.setHeight(5);  // 5% of page height

// Add some breathing room with margins
Padding margins = new Padding();
margins.setLeft(1);
margins.setTop(1);
margins.setRight(1);
options.setMargin(margins);
String outputFilePath = "YOUR_OUTPUT_DIRECTORY/SignWithPercents/sample_signed.pdf";
signature.sign(outputFilePath, options);
Path outputPath = Paths.get(outputFilePath);
Files.createDirectories(outputPath.getParent());
signature.sign(outputFilePath, options);
try {
    signature.sign(outputFilePath, options);
    System.out.println("PDF signed successfully at: " + outputFilePath);
} catch (Exception e) {
    System.err.println("Signing failed: " + e.getMessage());
    e.printStackTrace();
}
options.setLocationMeasureType(MeasureType.Percents);
options.setLeft(5);  // 5% from left works on any page width
options.setWidth(10);  // Give it room to breathe
options.setHeight(5);  // Maintain proper aspect ratio
String filePath = "documents/sample.pdf";  // Works on Windows, Mac, Linux
Files.createDirectories(Paths.get("output/signed"));
try (Signature signature = new Signature(filePath)) {
    signature.sign(outputFilePath, options);
} // Automatically closes and releases memory
import org.junit.Test;
import static org.junit.Assert.*;

public class BarcodeSignatureTest {
    
    @Test
    public void testBarcodeSigning() {
        String testPdf = "test-data/sample.pdf";
        String output = "test-output/signed.pdf";
        
        try (Signature signature = new Signature(testPdf)) {
            BarcodeSignOptions options = new BarcodeSignOptions("TEST123");
            options.setEncodeType(BarcodeTypes.Code128);
            
            signature.sign(output, options);
            
            // Verify output file exists
            assertTrue(new File(output).exists());
            
            // Verify file size increased (signature was added)
            long originalSize = new File(testPdf).length();
            long signedSize = new File(output).length();
            assertTrue(signedSize > originalSize);
            
        } catch (Exception e) {
            fail("Signing should not throw exception: " + e.getMessage());
        }
    }
}
List<String> pdfFiles = Arrays.asList("doc1.pdf", "doc2.pdf", "doc3.pdf");

for (String pdfFile : pdfFiles) {
    try (Signature signature = new Signature(pdfFile)) {
        BarcodeSignOptions options = createBarcodeOptions(); // Reuse options
        signature.sign(getOutputPath(pdfFile), options);
    }
}
// Create options once, reuse many times
BarcodeSignOptions templateOptions = createStandardBarcodeOptions();

// For each document, clone and customize
BarcodeSignOptions documentOptions = templateOptions.clone();
documentOptions.setText(uniqueDocumentId);

相關教學