在 PDF 中生成 1D 与 2D 条码
本 recipe(示例)会将 1D 与 2D 条码直接绘制到 PDF 页面上。核心的 HasBarcodes trait 提供 write1DBarcode() 与 write2DBarcode()。两者都会在当前页面上使用原生 PDF 路径运算符绘制符号,因此输出是简洁且确定性的矢量内容。本 recipe 取材自 examples/10-barcodes.php。
composer require nextpdf/core:^3你不需要安装额外扩展。条码编码器由纯 PHP 实现,符号则使用标准的 PDF 矩形运算符绘制(ISO 32000-2 §8.5)。
概念说明
标题为“概念说明”的章节条码是绘制出来的,而不是以图像形式嵌入。payload 是你要编码的数据,例如产品编号或网址。
write1DBarcode() 会将 payload 编码成所选 BarcodeType 的 bar/space 样式,再输出一连串填充矩形。write2DBarcode() 会根据所选 Barcode2DType 构造一个模块矩阵,并为每个暗模块输出一个填充矩形。Data Matrix 与 QR Code 采用 Reed-Solomon 纠错,因此即使符号的一部分受损,扫描器仍能还原数据。
每个模块都对应一条确定性的 re … f 路径,不引入任何熵源,因此条码内容本身可以完全重现。可重现性级别为 structural,因为外围文档仍带有每次保存时才会变化的原子值:trailer 的 /ID,以及 /CreationDate 与 /ModDate 时间戳。测试夹具会先剥除这些原子值,再比对经 qpdf 规范化后的结构。
API 接口
标题为“API 接口”的章节NextPDF\Core\Concerns\HasBarcodes(混入 Document):
write1DBarcode(string $code, BarcodeType $type, ?float $x = null, ?float $y = null, float $w = 0, float $h = 30, float $barWidth = 0.4, bool $skipZeroWidthBars = true): staticwrite2DBarcode(string $code, Barcode2DType $type, ?float $x = null, ?float $y = null, float $w = 0, float $h = 0, float $moduleSize = 1.0, string $ecLevel = 'L', ?int $mask = null, ?int $version = null, bool $gs1 = false, bool $dmre = false, bool $rectangular = false): static
symbology(条码编码规格)是一类条码标准,用于定义数据如何转换成条或模块。BarcodeType 列出 1D symbology(C128、EAN13、UPCA、I25、CODABAR、ISBN、GS1_128 等),Barcode2DType 则列出 2D symbology(QRCode、DataMatrix、PDF417、HanXin、MicroQR 等)。
代码示例 — 快速上手
标题为“代码示例 — 快速上手”的章节<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Barcode\Barcode2DType;use NextPDF\Barcode\BarcodeType;use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Barcode Quick Start');$doc->addPage();
$doc->write1DBarcode('NEXTPDF-2026', BarcodeType::C128, x: 15, y: 30, w: 80, h: 20);$doc->write2DBarcode('https://nextpdf.dev', Barcode2DType::QRCode, x: 15, y: 60, w: 40, h: 40);
$doc->save(__DIR__ . '/barcodes.pdf');echo "Wrote barcodes.pdf\n";代码示例 — 生产环境
标题为“代码示例 — 生产环境”的章节下面这个完整且可由测试夹具执行的示例,对应 examples/10-barcodes.php。它会将 PDF 写入测试夹具通过 NEXTPDF_COOKBOOK_OUTPUT 提供的路径;手动执行时,则回退为写入本地文件。随后,可重现性测试夹具可以运行两次,并断言结构完全相同。该结构经过 qpdf 规范化,并剥除了每次保存时才会变化的 /ID 与时间戳原子值。
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Barcode\Barcode2DType;use NextPDF\Barcode\BarcodeType;use NextPDF\Core\Document;
$doc = Document::createStandalone();$doc->setTitle('Barcode Examples');$doc->addPage();
$doc->setFont('helvetica', 'B', 18);$doc->cell(0, 12, 'Barcode Examples', newLine: true);$doc->ln(5);
// --- 1D barcodes ---$doc->setFont('helvetica', 'B', 14);$doc->cell(0, 10, '1D Barcodes', newLine: true);$doc->ln(3);
$doc->setFont('helvetica', '', 10);$doc->cell(0, 6, 'Code 128:', newLine: true);$doc->write1DBarcode('NEXTPDF-2026', BarcodeType::C128, x: 15, y: null, w: 80, h: 20);$doc->ln(28);
$doc->cell(0, 6, 'EAN-13:', newLine: true);$doc->write1DBarcode('4006381333931', BarcodeType::EAN13, x: 15, y: null, w: 60, h: 20);$doc->ln(28);
// --- 2D barcodes ---$doc->setFont('helvetica', 'B', 14);$doc->cell(0, 10, '2D Barcodes', newLine: true);$doc->ln(3);
$doc->setFont('helvetica', '', 10);$doc->cell(0, 6, 'QR Code (URL):', newLine: true);$doc->write2DBarcode('https://nextpdf.dev', Barcode2DType::QRCode, x: 15, y: null, w: 40, h: 40);$doc->ln(48);
$doc->cell(0, 6, 'DataMatrix:', newLine: true);$doc->write2DBarcode('NextPDF-DM-2026', Barcode2DType::DataMatrix, x: 15, y: null, w: 30, h: 30);
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');$doc->save($out !== false ? $out : __DIR__ . '/barcodes.pdf');
echo "Wrote barcodes PDF (Code 128, EAN-13, QR Code, DataMatrix)\n";预期输出:
Wrote barcodes PDF (Code 128, EAN-13, QR Code, DataMatrix)边界情况与陷阱
标题为“边界情况与陷阱”的章节- payload 的有效性因 symbology 而异。
EAN13需要 12 或 13 位数字。无效的 payload 会在写入任何内容之前先抛出异常。UPCA、ISBN与ISSN各有自己的长度与校验位规则。 x/y是可选的。 省略它们时,条码会放在当前光标位置。传入明确的坐标,可以获得可预测的布局。w = 0会自动调整尺寸。 宽度设为零时,编码器会选择自然的模块宽度。传入正的宽度,即可适配到固定方框中。- 2D 纠错级别。
write2DBarcode()默认为ecLevel: 'L',也就是最低级别。对于必须经受打印损伤的 QR Code,可以提高该级别('M'、'Q'、'H')。级别越高,矩阵也会越大。 - GS1 应用标识符。 将
gs1: true传入write2DBarcode(),或改用BarcodeType::GS1_128,即可处理带有 FNC1 前缀的 GS1 结构化数据。 - 会隐式创建一个页面。 当你在
addPage()之前调用条码方法时,NextPDF 会先补上一个页面。这虽然方便,但当页面几何很重要时,请明确调用addPage()。
编码复杂度方面,1D 为 O(payload 长度)、2D 为 O(矩阵面积),两者都在微秒级别。每个模块都是一个 re … f 路径运算符,因此密集的 QR Code 会让内容流增加几 KB。过程中没有栅格化步骤,因此无论符号多大,内存用量都保持平稳。本 recipe 仍稳定保持在 1500 ms / 64 MB 的预算之内。
安全性注意事项
标题为“安全性注意事项”的章节条码会承载你传入的任何 payload,因此在使用端应把条码值视同其他任何不可信的输入来处理。这个库不会对 payload 签名,也不会验证其真实性。2D 符号并不是加密:任何拥有扫描器的人都能读取它。
符合性
标题为“符合性”的章节| 陈述 | 规格 | 条款 | 参考 ID |
|---|---|---|---|
| 条码模块使用矩形路径构造运算符绘制。 | ISO 32000-2 | §8.5 | |
| Code 128 符号字符使用已定义的 bar/space 元素结构。 | ISO/IEC 15417 | §4.3.1 | |
| Data Matrix 符号采用 Reed-Solomon 纠错。 | ISO/IEC 16022 | §7.6.1 | |
| QR Code 数据会切分成多个纠错块。 | ISO/IEC 18004 | §7.5.2 |
NextPDF 实现了所引用的 symbology 编码,但并未声称已通过条码标准的正式认证。条码 symbology 语料库文档在授权上受限于 Tier C。引用仅以 clause-id 与 reference_id 指针标示,并未复制任何标准原文。