Generate 1D and 2D barcodes in a PDF
At a glance
Section titled “At a glance”This recipe draws one-dimensional (1D) and two-dimensional (2D) barcodes
directly on a Portable Document Format (PDF) page. The Core HasBarcodes trait
gives you write1DBarcode() and write2DBarcode(). Both methods draw the
symbol as native PDF path operators on the current page, so the output is plain,
deterministic vector content. The recipe follows examples/10-barcodes.php.
Install
Section titled “Install”composer require nextpdf/core:^3You do not need an extra extension. The barcode encoders are pure PHP, and NextPDF draws the symbols with the standard PDF rectangle operator (ISO 32000-2 §8.5).
Conceptual overview
Section titled “Conceptual overview”A barcode is drawn, not embedded as an image. The payload is the data you encode, such as a product number or a web address.
write1DBarcode() encodes the payload into a bar/space pattern for the chosen
BarcodeType, then emits a sequence of filled rectangles. write2DBarcode()
builds a module matrix for the chosen Barcode2DType and emits one filled
rectangle for each dark module. Data Matrix and QR Code use Reed-Solomon error
correction, so a scanner can recover the data even when part of the symbol is
damaged.
Every module is a deterministic re … f path with no entropy source, so the
barcode content itself is fully reproducible. The reproducibility profile is
structural because the surrounding document still carries per-save atoms: the
trailer /ID, plus the /CreationDate and /ModDate timestamps. The harness
compares the qpdf-normalised structure with those atoms stripped.
API surface
Section titled “API surface”NextPDF\Core\Concerns\HasBarcodes (mixed into 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
A symbology is a barcode standard that defines how data becomes bars or
modules. BarcodeType lists the 1D symbologies (C128, EAN13, UPCA,
I25, CODABAR, ISBN, GS1_128, …), and Barcode2DType lists the 2D
symbologies (QRCode, DataMatrix, PDF417, HanXin, MicroQR, …).
Code sample — Quick start
Section titled “Code sample — Quick start”<?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";Code sample — Production
Section titled “Code sample — Production”The complete, harness-runnable example below mirrors
examples/10-barcodes.php. It writes the PDF to the path the harness supplies
through NEXTPDF_COOKBOOK_OUTPUT, and falls back to a local file when you run
it manually. The reproducibility harness can then run it twice and assert
structural identity. The structure is qpdf-normalised, with the per-save /ID
and timestamp atoms stripped.
<?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";Expected output:
Wrote barcodes PDF (Code 128, EAN-13, QR Code, DataMatrix)Edge cases & gotchas
Section titled “Edge cases & gotchas”- Payload validity is symbology-specific.
EAN13expects 12 or 13 digits. An invalid payload throws before NextPDF writes any content.UPCA,ISBN, andISSNhave their own length and check-digit rules. x/yare optional. When you omit them, the barcode is placed at the current cursor position. Pass explicit coordinates for predictable layout.w = 0auto-sizes. A zero width lets the encoder pick a natural module width. Pass a positive width to fit a fixed box.- 2D error-correction level.
write2DBarcode()defaults toecLevel: 'L', the lowest level. Raise it ('M','Q','H') for QR Codes that must survive print damage. Higher levels enlarge the matrix. - GS1 application identifiers. Pass
gs1: truetowrite2DBarcode(), or useBarcodeType::GS1_128, for GS1-structured data with the FNC1 prefix. - A page is created implicitly. When you call a barcode method before
addPage(), NextPDF adds a page first. That is convenient, but calladdPage()explicitly when page geometry matters.
Performance
Section titled “Performance”Encoding is O(payload length) for 1D and O(matrix area) for 2D, and both run at
microsecond scale. Each module is one re … f path operator, so a dense QR Code
adds a few kilobytes of content stream. There is no rasterisation step, so
memory stays flat regardless of symbol size. The recipe stays well inside the
1500 ms / 64 MB budget.
Security notes
Section titled “Security notes”A barcode carries whatever payload you pass, so treat the barcode value like any other untrusted input on the consuming side. The library does not sign or authenticate the payload. A 2D symbol is not encryption: anyone with a scanner can read it.
Conformance
Section titled “Conformance”| Statement | Spec | Clause | reference_id |
|---|---|---|---|
| Barcode modules are drawn with the rectangle path-construction operator. | ISO 32000-2 | §8.5 | |
| Code 128 symbol characters use the defined bar/space element structure. | ISO/IEC 15417 | §4.3.1 | |
| Data Matrix symbols employ Reed-Solomon error correction. | ISO/IEC 16022 | §7.6.1 | |
| QR Code data is split into error-correction blocks. | ISO/IEC 18004 | §7.5.2 |
NextPDF implements the cited symbology encodings, but does not assert formal
certification against the barcode standards. The barcode-symbology corpus
documents are licence-capped at Tier C. Citations use clause-id and
reference_id pointers only, and no standard text is reproduced.