ZPL2PDF(1)

NAME

ZPL2PDFConvert ZPL (Zebra Programming Language) labels to PDF easily and for free.

SYNOPSIS

$sudo apt-get install -f

INFO

24 stars
6 forks
0 views

DESCRIPTION

Convert ZPL (Zebra Programming Language) labels to PDF easily and for free.

README

ZPL2PDF - ZPL to PDF Converter

Version GitHub all releases .NET Platform License Docker Hub WinGet Package

English | Português-BR | Español | Français | Deutsch | Italiano | 日本語 | 中文

A powerful, cross-platform command-line tool that converts ZPL (Zebra Programming Language) files to high-quality PDF documents. Perfect for label printing workflows, automated document generation, and enterprise label management systems.

ZPL2PDF Demo


🚀 What's New in v3.1.1

🔧 Changed

  • Release tooling: Scripts under release/scripts/; Linux packaging assets under scripts/release/packages/ (documentation and contributor paths updated).
  • Internals: Single Labelary PDF fallback path in ConversionService across CLI, API, TCP server, and daemon; dimension/value-object consolidation and daemon PID handling without reflection.

🛠️ Maintenance

  • Installer pipeline: More reliable cleanup in 08-build-installer.ps1; optional cleanup-installer-output.ps1 for installer/Output.
  • Docker: Leaner default build context via .dockerignore.
  • Repo hygiene: .github/prompts/ and .github/skills/ remain untracked; the rest of .github (workflows, templates) stays versioned.

Recent highlights (v3.1.1)

  • --stdout, smarter default PDF naming, BinaryKits/PDFsharp bumps, dimension validation fix, Aztec ^B0^BO preprocessing.
  • Thanks to Jacques Caruso (jacques.caruso@exhibitgroup.fr) for contributions that landed in v3.1.0.

Key Features

🎯 Three Operation Modes

Conversion Mode - Convert individual files

ZPL2PDF -i label.txt -o output/ -n mylabel.pdf

Daemon Mode - Auto-monitor folders

ZPL2PDF start -l "C:\Labels"

TCP Server Mode - Virtual printer

ZPL2PDF server start --port 9101 -o output/

📐 Intelligent Dimension Handling

  • ✅ Extract dimensions from ZPL commands (^PW, ^LL)
  • ✅ Support for multiple units (mm, cm, inches, points)
  • ✅ Automatic fallback to sensible defaults
  • ✅ Priority-based dimension resolution

🌍 Multi-Language Interface

Set your preferred language:

# Temporary (current session)
ZPL2PDF status --language pt-BR

Permanent (all sessions)

ZPL2PDF --set-language pt-BR

Check configuration

ZPL2PDF --show-language

Supported Languages:

  • 🇺🇸 English (en-US)
  • 🇧🇷 Português (pt-BR)
  • 🇪🇸 Español (es-ES)
  • 🇫🇷 Français (fr-FR)
  • 🇩🇪 Deutsch (de-DE)
  • 🇮🇹 Italiano (it-IT)
  • 🇯🇵 日本語 (ja-JP)
  • 🇨🇳 中文 (zh-CN)

📦 Installation

Windows

Option 1: WinGet (Recommended)

winget install brunoleocam.ZPL2PDF

Option 2: Installer

  1. Download ZPL2PDF-Setup.exe
  2. Run installer
  3. Choose your language during installation
  4. Done! ✅

Linux

Ubuntu/Debian (.deb package)

# Download .deb package from releases
wget https://github.com/brunoleocam/ZPL2PDF/releases/download/v3.1.1/ZPL2PDF-v3.1.1-linux-amd64.deb

Install package

sudo dpkg -i ZPL2PDF-v3.1.1-linux-amd64.deb

Fix dependencies if needed

sudo apt-get install -f

Verify installation

zpl2pdf -help

Fedora/CentOS/RHEL (.tar.gz)

# Download tarball from releases
wget https://github.com/brunoleocam/ZPL2PDF/releases/download/v3.1.1/ZPL2PDF-v3.1.1-linux-x64-rpm.tar.gz

Extract to system

sudo tar -xzf ZPL2PDF-v3.1.1-linux-x64-rpm.tar.gz -C /

Make executable

sudo chmod +x /usr/bin/ZPL2PDF

Create symbolic link

sudo ln -s /usr/bin/ZPL2PDF /usr/bin/zpl2pdf

Verify installation

zpl2pdf -help

Docker (All Linux distributions)

docker pull brunoleocam/zpl2pdf:latest
docker run -v ./watch:/app/watch -v ./output:/app/output brunoleocam/zpl2pdf:latest

macOS

Intel Macs

# Download
curl -L https://github.com/brunoleocam/ZPL2PDF/releases/download/v3.1.1/ZPL2PDF-v3.1.1-osx-x64.tar.gz -o zpl2pdf.tar.gz

Extract and run

tar -xzf zpl2pdf.tar.gz ./ZPL2PDF -help

Apple Silicon (M1/M2/M3)

curl -L https://github.com/brunoleocam/ZPL2PDF/releases/download/v3.1.1/ZPL2PDF-v3.1.1-osx-arm64.tar.gz -o zpl2pdf.tar.gz
tar -xzf zpl2pdf.tar.gz
./ZPL2PDF -help

🚀 Quick Start

Convert a Single File

ZPL2PDF -i label.txt -o output_folder -n my_label.pdf

Convert with Custom Dimensions

ZPL2PDF -i label.txt -o output_folder -w 10 -h 5 -u cm

Convert ZPL String Directly

ZPL2PDF -z "^XA^FO50,50^A0N,50,50^FDHello World^FS^XZ" -o output_folder

Start Daemon Mode (Auto-Conversion)

# Start with default settings
ZPL2PDF start

Start with custom folder

ZPL2PDF start -l "C:\Labels" -w 7.5 -h 15 -u in

Check status

ZPL2PDF status

Stop daemon

ZPL2PDF stop


📖 Usage Guide

Conversion Mode Parameters

ZPL2PDF -i <input_file> (-o <output_folder> | --stdout) [options]
ZPL2PDF -z <zpl_content> (-o <output_folder> | --stdout) [options]
ParameterDescriptionExample
-i <file>Input ZPL file (.txt, .prn, .zpl, .imp)-i label.zpl
-z <content>ZPL content as string-z "^XA...^XZ"
-o <folder>Output folder for PDF (required unless --stdout)-o C:\Output
--stdoutWrite PDF bytes to stdout only (no file)--stdout
-n <name>Output PDF filename (optional; default: input basename or timestamp for -z)-n result.pdf
-w <width>Label width-w 10
-h <height>Label height-h 5
-u <unit>Unit (mm, cm, in)-u cm
-d <dpi>Print density (default: 203)-d 300
--rendererRendering engine (offline/labelary/auto)--renderer labelary
--fonts-dirCustom fonts directory--fonts-dir C:\Fonts
--fontMap specific font--font "A=arial.ttf"

Custom fonts (offline renderer): ZPL font IDs (^A0N, ^AAN, ^ABN, …) are mapped to TTF/OTF files. Use --font "A=arial.ttf" to map font A; use multiple --font for B, 0, etc. If you set --fonts-dir ./fonts, relative paths in --font are resolved under that directory (e.g. --font "A=arial.ttf"./fonts/arial.ttf). Example:

ZPL2PDF -i zpl_teste.txt -o output -n label1.pdf -d 600 -w 10.0 -h 8.0 -u cm --fonts-dir ./fonts --font "A=arial.ttf" --font "B=another.ttf"

Daemon Mode Commands

ZPL2PDF start [options]    # Start daemon in background
ZPL2PDF stop               # Stop daemon
ZPL2PDF status             # Check daemon status
ZPL2PDF run [options]      # Run daemon in foreground (testing)
OptionDescriptionDefault
-l <folder>Folder to monitorDocuments/ZPL2PDF Auto Converter
-w <width>Fixed width for all conversionsExtract from ZPL
-h <height>Fixed height for all conversionsExtract from ZPL
-u <unit>Unit of measurementmm
-d <dpi>Print density203

TCP Server Commands

ZPL2PDF server start [options]    # Start TCP server (virtual printer)
ZPL2PDF server stop               # Stop TCP server
ZPL2PDF server status             # Check TCP server status
OptionDescriptionDefault
--port <port>TCP port to listen on9101
-o <folder>Output folder for PDFsDocuments/ZPL2PDF TCP Output
--foregroundRun in foreground (not background)Background
--rendererRendering engineoffline

Language Commands

--language <code>           # Temporary language override
--set-language <code>       # Set language permanently
--reset-language            # Reset to system default
--show-language             # Show current configuration

🎨 Rendering Engines

Offline (BinaryKits) - Default

ZPL2PDF -i label.txt -o output/ --renderer offline
  • ✅ Works without internet
  • ✅ Fast processing
  • ⚠️ Some ZPL commands may render differently

Labelary (API) - High Fidelity

ZPL2PDF -i label.txt -o output/ --renderer labelary
  • ✅ Exact Zebra printer emulation
  • ✅ High-fidelity rendering via Labelary (uses Labelary to generate PNGs)
  • ✅ Works for multi-label ZPL inputs
  • ⚠️ Requires internet connection

Auto (Fallback)

ZPL2PDF -i label.txt -o output/ --renderer auto
  • ✅ Tries Labelary first
  • ✅ Falls back to BinaryKits if offline

🌐 REST API

Start the API server:

ZPL2PDF --api --host localhost --port 5000

Health check

curl -s http://localhost:5000/api/health
{
  "status": "ok",
  "service": "ZPL2PDF API"
}

Convert (ZPL to PDF/PNG)

Endpoint: POST /api/convert

Request body

{
  "zpl": "^XA...^XZ",
  "zplArray": ["^XA...^XZ"],
  "format": "pdf",
  "width": 7.5,
  "height": 15,
  "unit": "in",
  "dpi": 203,
  "renderer": "offline"
}

Notes:

  • You must provide either zpl or zplArray (at least one non-empty ZPL string).
  • renderer supports offline (BinaryKits), labelary (Labelary online API), or auto (try Labelary then fall back).
  • If width/height are not set or are 0, dimensions are extracted from ZPL (^PW / ^LL) by default.

Example: PDF (offline renderer)

curl -s -X POST http://localhost:5000/api/convert -H "Content-Type: application/json" -d '{
  "zpl": "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ",
  "format": "pdf",
  "renderer": "offline",
  "width": 7.5,
  "height": 3,
  "unit": "in",
  "dpi": 203
}'
{
  "success": true,
  "format": "pdf",
  "pdf": "JVBERi0xLjQKJc...base64...",
  "pages": 1,
  "message": "Conversion successful"
}

Example: PDF (Labelary renderer - direct PDF)

curl -s -X POST http://localhost:5000/api/convert -H "Content-Type: application/json" -d '{
  "zpl": "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ",
  "format": "pdf",
  "renderer": "labelary",
  "width": 7.5,
  "height": 3,
  "unit": "in",
  "dpi": 203
}'
{
  "success": true,
  "format": "pdf",
  "pdf": "JVBERi0xLjQKJc...base64...",
  "pages": 1,
  "message": "Conversion successful"
}

Example: PNG (Labelary renderer)

curl -s -X POST http://localhost:5000/api/convert -H "Content-Type: application/json" -d '{
  "zpl": "^XA^FO50,50^A0N,50,50^FDHello^FS^XZ",
  "format": "png",
  "renderer": "labelary",
  "width": 7.5,
  "height": 3,
  "unit": "in",
  "dpi": 203
}'
{
  "success": true,
  "format": "png",
  "image": "iVBORw0KGgo...base64...",
  "pages": 1,
  "message": "Conversion successful"
}

If more than one label/image is produced, the response uses images (array) instead of image (single string).


🐳 Docker Usage

Quick Start with Docker

# Pull image
docker pull brunoleocam/zpl2pdf:latest

Run daemon mode

docker run -d
--name zpl2pdf
-v ./watch:/app/watch
-v ./output:/app/output
-e ZPL2PDF_LANGUAGE=en-US
brunoleocam/zpl2pdf:latest

Docker Compose

Create docker-compose.yml:

version: '3.8'

services: zpl2pdf: image: brunoleocam/zpl2pdf:latest container_name: zpl2pdf-daemon volumes: - ./watch:/app/watch - ./output:/app/output environment: - ZPL2PDF_LANGUAGE=pt-BR restart: unless-stopped

Run:

docker-compose up -d

📘 Full Docker Guide: docs/guides/DOCKER_GUIDE.md


🔧 Configuration

Configuration File (zpl2pdf.json)

Create a zpl2pdf.json file in the application directory:

{
  "language": "en-US",
  "defaultListenFolder": "C:\\Users\\user\\Documents\\ZPL2PDF Auto Converter",
  "labelWidth": 10,
  "labelHeight": 5,
  "unit": "cm",
  "dpi": 203,
  "logLevel": "Info",
  "retryDelay": 2000,
  "maxRetries": 3
}

See zpl2pdf.json.example for full configuration options.

Environment Variables

VariableDescriptionExample
ZPL2PDF_LANGUAGEApplication languagept-BR

📘 Language Configuration Guide: docs/guides/LANGUAGE_CONFIGURATION.md


📐 ZPL Support

Supported ZPL Commands

  • ^XA / ^XZ - Label start/end
  • ^PW<width> - Print width in points
  • ^LL<length> - Label length in points
  • ✅ All standard ZPL text, graphics, and barcode commands

Dimension Extraction

ZPL2PDF automatically extracts dimensions:

^XA
^PW800        ← Width: 800 points
^LL1200       ← Height: 1200 points
^FO50,50^A0N,50,50^FDHello^FS
^XZ

Conversion: mm = (points / 203) * 25.4

Priority Logic

  1. Explicit Parameters (-w, -h) - Highest priority
  2. ⭐⭐ ZPL Commands (^PW, ^LL) - If no parameters
  3. ⭐⭐⭐ Default Values (100mm × 150mm) - Fallback

🏗️ Architecture

ZPL2PDF follows Clean Architecture principles:

src/
├── Application/          # Use Cases & Services
│   ├── Services/         # Business logic
│   └── Interfaces/       # Service contracts
├── Domain/              # Business entities & rules
│   ├── ValueObjects/    # Value objects
│   └── Services/        # Domain interfaces
├── Infrastructure/      # External concerns
│   ├── FileSystem/      # File operations
│   ├── Rendering/       # PDF generation
│   └── Processing/      # Queue management
├── Presentation/        # CLI & user interface
│   └── Handlers/        # Mode handlers
└── Shared/             # Common utilities
    ├── Localization/   # Multi-language
    └── Constants/      # Configuration

🧪 Testing

Run Tests

# All tests
dotnet test

Unit tests only

dotnet test tests/ZPL2PDF.Unit/

Integration tests

dotnet test tests/ZPL2PDF.Integration/

With coverage

dotnet test --collect:"XPlat Code Coverage"

Test Coverage

  • ✅ Unit Tests: 90%+ coverage
  • ✅ Integration Tests: End-to-end workflows
  • ✅ Cross-Platform: Windows, Linux, macOS

📚 Documentation

User Guides

Developer Guides

Build & Deployment


💡 Use Cases

1. ERP Integration

// C# example
Process.Start("ZPL2PDF.exe", "-i label.txt -o output/ -w 10 -h 5 -u cm");

2. Batch Processing

# Process all ZPL files in a folder
for file in *.txt; do
    ZPL2PDF -i "$file" -o output/
done

3. Automated Workflow

# Start daemon on system startup
ZPL2PDF start -l "C:\Labels\Incoming"

4. Docker Deployment

# Deploy to server
docker run -d \
  -v /srv/labels:/app/watch \
  -v /srv/pdfs:/app/output \
  --restart always \
  brunoleocam/zpl2pdf:latest

📊 Performance

Benchmarks

MetricValue
Single Label~50ms
Batch Processing100+ labels/minute
Memory Usage<50MB typical
PDF File Size~100KB per label
Startup Time<1 second

Optimization Features

  • ✅ Async processing with configurable concurrency
  • ✅ Retry mechanisms for locked files
  • ✅ Memory-efficient image processing
  • ✅ Optimized PDF generation with compression

🛠️ Development

Prerequisites

  • .NET 9.0 SDK or later
  • Git
  • Visual Studio 2022 or VS Code
  • Docker (for cross-platform testing)

Build from Source

# Clone repository
git clone https://github.com/brunoleocam/ZPL2PDF.git
cd ZPL2PDF

Restore dependencies

dotnet restore

Build solution

dotnet build

Run tests

dotnet test

Build for your platform

dotnet publish -c Release -r win-x64 --self-contained true

Build all platforms

.\scripts\build-all-platforms.ps1 # Windows ./scripts/build-all-platforms.sh # Linux/macOS

Project Structure

ZPL2PDF/
├── src/                    # Source code (Clean Architecture)
├── tests/                  # Unit & integration tests
├── docs/                   # Documentation
│   ├── i18n/              # Translated documentation
│   ├── Image/             # Screenshots & icons
│   └── Sample/            # Sample ZPL files
├── installer/              # Windows installer (Inno Setup)
├── scripts/                # Build & release scripts
├── .github/workflows/      # GitHub Actions CI/CD
├── docker-compose.yml      # Docker orchestration
└── Dockerfile              # Docker image definition

🐛 Troubleshooting

Common Issues

IssueSolution
File Locked ErrorWait for the process writing the file to complete
Invalid ZPL ContentEnsure file contains valid ZPL commands (^XA...^XZ)
Permission DeniedRun with appropriate permissions or check folder access
Docker: libgdiplus not foundUse official image: brunoleocam/zpl2pdf:alpine

Debug Mode

# Enable verbose logging by setting "logLevel": "Debug" in `zpl2pdf.json`
# (then re-run your command)
ZPL2PDF -i label.txt -o output/

Get Help


🤝 Contributing

We welcome contributions! See CONTRIBUTING.md for details.

Quick Start

# 1. Fork and clone
git clone https://github.com/YOUR_USERNAME/ZPL2PDF.git

2. Create feature branch

git checkout -b feature/amazing-feature

3. Make changes and test

dotnet test

4. Commit and push

git commit -m "feat: add amazing feature" git push origin feature/amazing-feature

5. Create Pull Request


📄 License

This project is licensed under the MIT License - see the LICENSE file for details.


🙏 Acknowledgments

Built with amazing open-source libraries:


📞 Support


💝 Support the Project

If ZPL2PDF helps you, consider supporting its development:

Your support helps maintain and improve ZPL2PDF for everyone!


🌟 Star History

If ZPL2PDF helps you, please ⭐ star the repository!


👥 Contributors

Thanks to all contributors who have helped make ZPL2PDF better!

Special thanks to Jacques Caruso (jacques.caruso@exhibitgroup.fr) for sending the solutions for version 3.1.0.

Contributors

Image may be cached; see full list on GitHub.


ZPL2PDF - Convert ZPL labels to PDF easily and efficiently.

SEE ALSO

clihub4/4/2026ZPL2PDF(1)