在 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 指標標示,沒有重製任何標準原文。