如何在 Java 中向 PDF 添加条形码

介绍

你是否曾在 Java 应用中为文档真实性而苦恼?你并不孤单。无论是构建库存系统、管理合同,还是处理供应链文档,都很可能需要一种可靠的方式来自动签署和验证 PDF。

传统的数字签名固然优秀,但有时你需要更专业的方案——例如能够与扫描系统和自动化工作流无缝配合的条形码签名。这时 GS1DotCode 条形码就派上用场了。

你将学到的内容:

  • 如何在 Java 中使用 GS1DotCode 条形码签署 PDF 文档
  • 如何提取并保存条形码签名图像
  • 何时(以及为何)使用条形码签名而非传统方法
  • 常见陷阱及规避方法

阅读完本指南后,你将拥有一个可直接嵌入任何 Java 项目的即用解决方案。

快速答案

  • 哪个库可以在 Java 中向 PDF 添加条形码? GroupDocs.Signature for Java。
  • 支持哪种条形码格式? GS1DotCode,一种紧凑的 2‑D 点阵条码。
  • 是否需要付费许可证? 免费试用可用于测试;生产环境需要商业许可证。
  • 我可以将条形码提取为图像吗? 可以,使用 BarcodeSignature API。
  • 需要哪个 Java 版本? JDK 8 或更高。

什么是添加条形码?

添加条形码 指的是以编程方式将机器可读的条形码图形嵌入 PDF 文件,使条形码成为文档内容流的一部分。这涉及生成条形码图像、在页面上定位并保存修改后的 PDF,确保条形码可搜索且可打印。

为什么选择 GS1DotCode 条形码?

GS1DotCode 旨在空间受限的场景。不同于水平延伸的线性条码,DotCode 生成一个 2‑D 点阵矩阵,在小面积内承载大量信息。这使其非常适合:

  • 小型产品标签——每一毫米都很重要
  • 生产线高速打印(该格式专为此设计)
  • 供应链追踪——需要编码复杂数据结构

该格式在紧凑空间内可容纳多达 3,116 个字符,并且即使在高速或部分损坏的情况下也能可靠读取。如果你从事零售或物流,合作伙伴很可能已经使用 GS1 标准——这意味着大家使用相同的语言。

专业提示: 当需要在小于 1 英寸 × 1 英寸的标签上嵌入超过 20 个字符时,使用 GS1DotCode。

前置条件

在开始编码之前,请确认你的环境满足以下要求。

必需的库和依赖

  • GroupDocs.Signature for Java 23.12 或更高(支持 30+ 文档格式)
  • 用于依赖管理的 Maven 或 Gradle

环境搭建

  • 已安装并在 PATH 中配置 JDK 8 或更高版本
  • IntelliJ IDEA、Eclipse 或 NetBeans 等 IDE
  • 用于实验的示例 PDF 文件(任意未加密的 PDF 均可)

知识前提

  • 基本的 Java 语法(变量、方法、对象)
  • 熟悉 Maven 或 Gradle 的依赖声明方式
  • 了解 Java 中的文件 I/O(例如 FileInputStream)

如果缺少上述任意项目,请先暂停并安装;后续步骤默认它们已就绪。

设置 GroupDocs.Signature for Java

Maven

如果使用 Maven,在 pom.xml 中添加以下依赖:

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

Maven 将自动下载该库及所有必需的传递依赖。

Gradle

对于 Gradle 用户,将此行插入 build.gradle 文件:

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

Gradle 以同样的“一键式”方式解析该包。

直接下载

如果倾向手动管理,请从官方发布页面下载 JAR 文件:GroupDocs.Signature for Java releases。将 JAR 放入项目的 classpath 中。

专业提示: Maven 或 Gradle 可简化后续升级——只需更改版本号即可。

许可证获取

GroupDocs 提供三种授权方式:

  • 免费试用 – 无需信用卡,输出文件会加水印
  • 临时许可证 – 30 天完整功能评估
  • 商业许可证 – 移除试用限制并授予生产使用权

获取许可证文件后,将其放入项目的 resources 文件夹,并在创建任何 Signature 对象之前加载。

License.setLicense 加载 GroupDocs 许可证文件,启用完整功能且不受试用限制。

运行以下代码片段以验证库是否正确加载:

import com.groupdocs.signature.Signature;

public class InitializeGroupDocs {
    public static void main(String[] args) {
        // Create an instance of Signature
        Signature signature = new Signature("path/to/your/document.pdf");
        
        System.out.println("Initialization successful!");
    }
}

如果看到 “Initialization successful!” 则说明设置完成。否则,请检查 classpath 与许可证路径。

实现指南

我们将覆盖两个核心功能:(1) 使用 GS1DotCode 条形码签署 PDF;(2) 将该条形码提取为图像文件。

功能 1:使用 GS1DotCode 条形码签署文档

如何在 Java 中使用 GS1DotCode 条形码签署 PDF?

使用 new Signature("source.pdf") 加载目标 PDF,配置包含 GS1 格式数据的 BarcodeSignOptions 对象,然后调用 sign() 生成嵌入条形码的新 PDF。此操作直接将条形码写入 PDF 内容流,保证其在打印和重新扫描时保持完整。

整个过程分为三步:创建 Signature 实例、设置 BarcodeSignOptions、调用 sign()。下面的代码演示了每一步。

1. 初始化签名对象

Signature 类是 GroupDocs.Signature 中所有文档处理操作的入口。

import com.groupdocs.signature.Signature;

String sourceFilePath = "YOUR_DOCUMENT_DIRECTORY/document.pdf";
final Signature signature = new Signature(sourceFilePath);

为什么重要: Signature 对象抽象了文件处理,能够在不将整个 PDF 加载到内存的情况下高效流式处理大型 PDF。

2. 配置条形码选项

BarcodeSignOptions 允许指定条形码类型、编码数据、位置和尺寸。

import com.groupdocs.signature.domain.signatures.BarcodeSignature;
import com.groupdocs.signature.options.sign.BarcodeSignOptions;
import com.groupdocs.signature.domain.barcodes.BarcodeTypes;

BarcodeSignOptions gs1DotCodeOptions = new BarcodeSignOptions("(01)04912345123459(15)970331(30)128(10)ABC123", BarcodeTypes.GS1DotCode);
gs1DotCodeOptions.setLeft(100); // Set barcode position
gs1DotCodeOptions.setTop(100);
gs1DotCodeOptions.setHeight(150);
gs1DotCodeOptions.setWidth(200);

关键要点:

  • 编码字符串遵循 GS1 应用标识符(AI),如 (01) 表示 GTIN,(15) 表示有效期等。
  • setLeft() 和 setTop() 使用点(72 pts = 1 in)。
  • 为了可靠扫描,推荐的最小尺寸为 108 pt × 108 pt(1.5 in × 1.5 in)。
3. 签署文档

将配置好的选项加入列表(可组合多种签名类型),然后调用 sign()。

import java.util.ArrayList;
import java.util.List;

List<com.groupdocs.signature.options.sign.SignOptions> listOptions = new ArrayList<>();
listOptions.add(gs1DotCodeOptions);
signature.sign("YOUR_OUTPUT_DIRECTORY/signed_document_with_gs1dotcode.pdf", listOptions);

性能提示: 在批量操作中复用同一个 Signature 实例可减少对象创建开销,提高吞吐量。

功能 2:将条形码签名内容保存为文件

如何在 Java 中从已签署的 PDF 中提取条形码图像?

BarcodeSignature 表示从已签署文档中提取的条形码签名对象,提供对其数据和图像内容的访问。

创建 BarcodeSignature 实例(或通过 search() 获取),使用 getContent() 读取 Base64 编码的图像数据,解码后写入 PNG 文件。这样即可得到可在 UI 中显示或发送至标签打印机的独立图像。

1. 模拟条形码签名创建

在真实场景中你会从搜索结果中获取 BarcodeSignature;这里为了演示手动实例化。

import com.groupdocs.signature.domain.signatures.BarcodeSignature;
import java.io.FileOutputStream;

String base64String = "SampleBase64EncodedData";
BarcodeSignature barcodeSignature = new BarcodeSignature(base64String);
2. 将内容保存为文件

使用 try‑with‑resources 块解码 Base64 字符串并将字节写入磁盘。

int imageNumber = 1;
String formatExtension = ".png";  // Assume PNG format

try (FileOutputStream outputStream = new FileOutputStream("YOUR_OUTPUT_DIRECTORY/barcode_image" + imageNumber + formatExtension)) {
    byte[] byteArray = barcodeSignature.getContent();
    if (byteArray != null) {
        outputStream.write(byteArray);
    }
}

注意事项: 如果签名创建时未嵌入图像,getContent() 可能返回 null。写入前务必检查 null。

常见问题及解决方案

问题:条形码无法扫描

症状: 条形码在 PDF 查看器中显示正常,但扫描仪报错。

解决方案:

  • 将条形码尺寸至少提升至 108 pt × 108 pt。
  • 确保打印机分辨率 ≥ 300 dpi。
  • 检查 GS1 数据字符串是否符合正确的 AI 语法;缺少括号会导致扫描仪报错。

问题:大 PDF 导致 OutOfMemoryError

症状: 处理超过 50 MB 的文档时出现堆内存溢出。

解决方案:

  • 使用更大的堆启动 JVM,例如 -Xmx2g。
  • 将文档拆分为更小的批次处理。
  • 在每个文件处理完毕后显式释放 Signature 对象:signature.dispose()。

问题:条形码显示模糊

症状: 输出 PDF 中的条形码像素化。

解决方案:

  • 使用更大的尺寸;库在可能时渲染矢量图形,缩小后会产生伪影。
  • 避免先将矢量转为栅格再渲染,直接让 GroupDocs 从矢量定义生成图形。

问题:许可证异常

症状: 出现 “License not found” 或 “Trial limitations exceeded” 等错误。

解决方案:

  • 将许可证文件放在 classpath 根目录(src/main/resources)。
  • 在任何 Signature 实例化之前调用 License.setLicense("GroupDocs.Signature.lic")。
  • 对于临时许可证,确认其自发行日起 30 天内未过期。

何时使用此方案

适用场景

  • 供应链追踪——在运输单据上嵌入产品 ID、批次号和有效期。
  • 自动标签打印——为每张 PDF 发票即时生成条形码。
  • 受监管行业——许多零售和医疗环境强制使用 GS1 标准。

何时考虑替代方案

  • 若仅需加密完整性,标准 PKI 数字签名更合适。
  • 对于简单的可视注释,文本签名或图像印章即可满足需求。
  • 当文档大小受严格限制时,避免使用高分辨率条形码图像;可改用 QR 码,其在相同数据密度下体积更小。

安全最佳实践

数据校验

在将用户提供的数据编码为条形码前进行清洗。错误的 GS1 字符串会导致下游扫描错误,甚至在旧版扫描器固件中触发缓冲区溢出。

访问控制

实现基于角色的访问控制(RBAC),仅授权用户可调用签名 API。安全存放许可证文件并限制文件系统权限。

审计日志

记录每一次签名操作,包括用户 ID、时间戳、源文件路径以及完整的 GS1 负载。示例日志代码片段:

// Simple logging example (use a proper logging framework in production)
System.out.println("Document signed by: " + userId + " at " + new Date());
System.out.println("Barcode data: " + barcodeData);

防篡改检测

将条形码签名与加密数字签名结合使用。条形码提供机器可读数据,数字签名保证完整性和不可否认性。

实际应用

1. 供应链管理

每张装箱单都附加一个 GS1DotCode 条形码,编码发货的 GTIN、批次和目的地。各检查点的扫描仪自动更新 ERP 系统,将人工录入错误降低 98 %。

2. 库存控制

货物到达时,接收的 PDF 会签入包含采购单号和数量的条形码。仓库人员扫描后,库存数据库实时更新。

3. 零售收银

带有条形码的发票允许收银员通过扫描发票完成退货,而无需手动输入交易号,平均每笔退货可节省 30 秒。

4. 医疗文档

签署的处方中嵌入 GS1DotCode 条形码,包含患者 ID、药品代码和剂量说明。药房扫描后即可避免手工录入错误,从而降低不良药物事件。

性能考量

内存管理

GroupDocs.Signature 会流式处理 PDF 数据,但仍需及时关闭资源:

try (Signature signature = new Signature(sourceFilePath)) {
    // Do your signing operations here
} // Signature automatically disposed here

使用 try‑with‑resources 可确保即使抛出异常,Signature 对象也会释放文件句柄。

批量处理技巧

  • 当多个文档的负载相同,复用同一个 BarcodeSignOptions 实例。
  • 使用 ExecutorService 并行签署 CPU 密集型任务;一台典型的 8 核服务器在每个文件小于 5 MB 时可实现 ≈ 150 份 PDF/分钟。
  • 对外部许可证验证调用进行限流,以避免触发速率限制。

文件格式优化

  • 优先使用 PDF/A‑1b 进行归档;它会压缩流并将文件大小降低最多 40 %。
  • 将条形码尺寸控制在必要范围内;一个 1.5 in × 1.5 in 的条形码大约会给 2 MB 的 PDF 增加 15 KB。

结论

现在,你已经掌握了在 Java 中向 PDF 文件添加 GS1DotCode 条形码签名、提取条形码图像并将该流程集成到更大的文档管理管道中的完整、可投入生产的工作流。请记住:

  1. 在编码前验证 GS1 负载。
  2. 选择兼顾扫描可靠性与布局约束的条形码尺寸。
  3. 将条形码签名与加密数字签名结合,以实现全方位安全防护。

后续可探索 GroupDocs.Signature 提供的其他签名类型——QR 码、文本印章以及数字证书,它们共享一致的 API。


常见问题

问:GS1DotCode 是什么,为什么它不同于 QR 码?
答:GS1DotCode 是一种紧凑的 2‑D 点阵,可在比 QR 码更小的占位面积内存储多达 3,116 个字符,非常适合微小标签和高速打印。

问:我可以在生产环境中使用免费试用吗?
答:免费试用仅限评估,并会在输出文件中添加水印。生产使用必须购买或使用 30 天的临时许可证。

问:如何在特定页面上定位条形码?
答:在 BarcodeSignOptions 对象上调用 setPageNumber(pageIndex),然后使用 setLeft() 和 setTop() 精确定位。

问:GroupDocs.Signature 支持受密码保护的 PDF 吗?
答:支持。在构造 Signature 对象时提供密码,例如 new Signature("file.pdf", "password")。

问:我如何验证条形码签名是否正确添加?
Signature.search() 可在文档中搜索签名,返回匹配的签名对象集合。使用 BarcodeSearchOptions 调用 Signature.search(),返回的 BarcodeSignature 对象包含编码数据和图像内容,可用于验证。

问:可靠扫描的最小条形码尺寸是多少?
答:建议至少 108 pt × 108 pt(1.5 in × 1.5 in)。尺寸越大,可读性越好,尤其在低分辨率打印机上。

问:我可以并发签署多个 PDF 吗?
答:可以。创建线程池并为每个线程实例化独立的 Signature 对象;库在每个线程处理各自文档时是线程安全的。

问:单个 PDF 能嵌入多少条形码?
答:没有硬性限制,但每个条形码大约会增加 15 KB 的数据。对于超过 100 MB 的 PDF,建议采用批处理以管理内存使用。

问:该库能在非 Windows 平台上运行吗?
答:GroupDocs.Signature for Java 与平台无关,可在任何兼容 JRE 的操作系统上运行,包括 Linux 和 macOS。


最后更新: 2026-08-25
测试环境: GroupDocs.Signature 23.12 for Java
作者: GroupDocs

相关教程