Founded in 2004, Neodynamic designs and develops Barcode, Imaging, Labeling & Printing Tools for .NET & Web developers. We are experts in those fields with strong know-how on .NET, ASP.NET, SSRS, PHP & HTML/JS projects. More...
Convert raw EPL to PNG, JPG, PCX & PDF Print & Preview EPL commands without wasting real labels! High Quality & Accuracy EPL Rendering Forward EPL rendering to any other servers and services Rest HTTP POST & Raw TCP Socket
Zebra and EPL are registered trademarks of ZIH Corp. EPLServer is not made by or endorsed by Zebra.
EPLServer for Windows, macOS & Linux installs as a local service/daemon and allows you to Convert, Preview and Render raw EPL (Eltron/Zebra Programming Language) commands to well known image and document formats like PNG, JPG, PCX & PDF. It also can be configured to forward the EPL output rendering to any other server/services (webhook)!
EPLServer installs as a local service/daemon. You can send raw EPL commands from any software, application or service for file conversion or output forwarding.
HTTP POST
Through a JSON payload, you can specify the EPL commands, the DPI/Resolution, the Default Label Size, the Default Encoding (Code Page), and more... to the EPLServer REST endpoint. Ideal for application integration.
Raw TCP Socket
Just open a socket and write EPL or JSON directly and get the output rendering ready for printing redirection.
High Accuracy EPL Render
EPLServer renders EPL commands generating high quality output by reproducing built-in and resident EPL fonts for texts and barcodes with high accuracy. Custom Zebra Intellifont is also supported!
Convert EPL to Images & Docs
Use EPLServer to easily convert EPL commands to PNG, JPG, PCX & PDF. Just specify the Write To File action in the Settings web UI tab (eplserver --settings) or through a JSON payload.
Forward EPL Rendering
Use EPLServer to easily forward the EPL output rendering to any other server/service. Just specify the Forward action in the Settings web UI tab (eplserver --settings) or through a JSON payload.
Barcode Symbologies Support
EPLServer can generate most of the linear (1D), postal, composite, stacked and 2D barcodes shipped with real Zebra printer devices.
Colored Label Simulation
EPLServer can be configured to convert and print EPL to PNG, JPG & PDF formats simulating a color ribbon (for label items) and a background color label. Black & White 1bpp is also supported through PCX format.
On-Premise Licensing
EPLServer is licensed for Private On-Premise environments. License is available for individual Windows, macOS & Linux devices or for Corporate-wide.
Quick Developer Guide
EPLServer listens on a single TCP port 48321 and accepts EPL commands in two ways:
HTTP POST — Send a JSON payload to a REST endpoint. Best for application integration.
Raw TCP socket — Open a socket and write EPL or JSON directly. Best for printer emulation and legacy tools.
You can check the port currently in use under the Settings web UI tab (eplserver --settings), or run eplserver --port from the command line.
1 — Sending EPL via HTTP (REST API)
EPLServer exposes two HTTP endpoints on the same port used by the web interface.
Endpoint
Method
Body
Response
/render
POST
JSON payload (see below)
Rendered image/PDF binary (or ZIP for multi-label jobs)
/render
POST
JSON payload with "action": "writetofile"
Saves the output to disk; same binary response
/render
POST
JSON payload with "action": "forward"
Forwards output to the URL in forwardTo; same binary response
💡 The /render endpoint always returns the rendered bytes directly to the caller.
The action field controls whether the output is also saved to disk or forwarded — it does not suppress the HTTP response.
JSON Payload Reference
Send Content-Type: application/json with a body like the example below. All fields are optional and fall back to the values configured in the Settings web UI tab (eplserver --settings).
EPLServer listens on the same port for raw TCP connections. You can write either:
Plain EPL commands (e.g. ^XA...^XZ) — the server uses the settings from the Settings web UI tab (eplserver --settings).
A complete JSON payload — the server parses it and applies any overrides before rendering.
This mode is compatible with any tool or language that can open a TCP socket: Zebra printers, legacy applications, scripts, etc.
💡 This is the same mechanism used when you install EPLServer as a Standard TCP/IP printer port on Windows — the print spooler sends the raw EPL stream directly over this socket.
On Windows you can configure EPLServer as a Standard TCP/IP printer port.
Any application that prints to this virtual printer will have its EPL stream captured and processed by EPLServer automatically.
Open Devices and Printers:
Windows 11 / 10 Right-click Start → Settings → Bluetooth & devices → Printers & scanners
Windows 8 / 7 Start → Control Panel → Hardware and Sound → Devices and Printers
Click Add a printer → The printer that I want isn't listed.
Select Add a local printer or network printer with manual settings → Next.
Select Create a new port, choose Standard TCP/IP Port → Next.
Enter:
Host Name or IP Address:127.0.0.1
Port Name: any name you like, e.g. EPLServer_local
UncheckQuery the printer and automatically select the driver to use
When prompted for a driver, choose any Generic / Text Only driver.
After the port is created, open its Properties → Ports tab → select the port → Configure Port and set the Port Number to match the value returned by EPLServer.exe --port.
Click Finish. The new printer will now forward all print jobs to EPLServer.
3b — Linux: CUPS Virtual Printer Setup
On Linux you can add EPLServer as a raw CUPS printer. Any application that prints to it will have its EPL
stream sent directly to EPLServer over a socket connection.
Tip: CUPS must be installed and running.
Debian/Ubuntu:sudo apt install cups
Fedora/RHEL:sudo dnf install cups
Start:sudo systemctl start cups
Option A — Command line (recommended)
Run the following as a user with lpadmin privileges (or prefix with sudo):
Linux Terminal
# Add the printer — replace 48321 with the port shown by eplserver --port
lpadmin -p EPLServer \
-E \
-v socket://127.0.0.1:48321 \
-m raw \
-D "EPLServer virtual EPL printer" \
-L "localhost"
# Set it as the system default (optional)
lpoptions -d EPLServer
The -m raw flag tells CUPS to forward the print data unmodified — no driver translation occurs,
so EPL commands reach EPLServer exactly as sent by the application.
Under Make choose Raw, under Model choose Raw Queue (en).
Click . Done.
3c — macOS: Printers & Scanners Setup
macOS uses CUPS under the hood, so the same raw socket approach works. You can add EPLServer either through
the Printers & Scanners System Settings panel or from the Terminal.
Option A — Terminal (fastest)
macOS Terminal
# Replace 48321 with the port shown by eplserver --port
lpadmin -p EPLServer \
-E \
-v socket://127.0.0.1:48321 \
-m raw \
-D "EPLServer virtual EPL printer"
# Set as default printer (optional)
lpoptions -d EPLServer
Note: On macOS Ventura and later, lpadmin may require full disk access for the terminal app, or you can prefix with sudo.
If the command is not found, install the Xcode Command Line Tools: xcode-select --install.
Option B — System Settings GUI
Open System Settings (macOS Ventura 13+) or System Preferences
(macOS Monterey 12 and earlier) Printers & Scanners.
Click the (Add Printer) button.
In the Add Printer dialog, click the IP tab ( globe icon).
Fill in the fields:
Address:127.0.0.1
Protocol:HP Jetdirect - Socket
Queue:leave blank
Name:EPLServer (or any name you like)
Use / Driver: select Generic PostScript Printer or AirPrint — then immediately change it to Select Software… Generic Generic PostScript Printer. The driver is irrelevant because CUPS will use the raw queue.
Click . The printer appears in the list.
Important: right-click (or Control-click) the new printer in the list and choose
Show Printers in Finder to verify the queue name, then match it to the port configured
in EPLServer which can be obtained through eplserver --port.
Note: macOS may display a driver warning because it expects a PostScript or AirPrint device. This is harmless —
EPLServer receives the raw bytes before any driver conversion takes place when the queue is set to
raw via Terminal.
If you use the GUI-only route, test with a small EPL print job and check the
Logs tab to confirm EPLServer received the data.
4 — Redirect Print
Windows PowerShell — render to image → save to disk → file system watcher → printing
<#
.SYNOPSIS
Watches the EPLServer output folder (action: "writetofile", fileFormat: "PNG")
and prints each rendered label to a standard Windows-installed HP printer,
using System.Drawing.Printing on regular A4 or Letter paper.
.DESCRIPTION
EPLServer does not support "redirect printing, it can only save the rendered
output to disk ("writetofile") or forward it to a webhook ("forward").
This script bridges that gap:
it watches the folder EPLServer writes to, and as soon as a new label
image appears, it prints it on a regular office printer (A4 / Letter),
placing the label at its real physical size (in inches) rather than
stretching it to fill the whole page.
.NOTES
- EPLServer must be configured with fileFormat "PNG" or "JPG".
Do NOT use "PDF": System.Drawing.Image cannot load PDF files directly.
- Set $WatchFolder to match the "fileFolder" value used in EPLServer's
payload/Settings.
- Set $PrinterName to the EXACT name shown in Windows.
List available printers with: Get-Printer | Select-Object Name
- Set $PageSize to "A4" or "Letter" depending on the paper loaded
in the printer.
.EXAMPLE
powershell -ExecutionPolicy Bypass -File .\Watch-And-Print-EPL.ps1
#>
param(
[string]$WatchFolder = "C:\EPLServer\labels",
[string]$PrinterName = "HP LaserJet Pro M404-M405",
[ValidateSet("A4", "Letter")]
[string]$PageSize = "Letter",
[double]$LabelWidthIn = 4,
[double]$LabelHeightIn = 6,
[double]$OffsetXIn = 0.25, # horizontal position of the label on the page
[double]$OffsetYIn = 0.25, # vertical position of the label on the page
[switch]$DeleteAfterPrint = $true,
[string]$FailedFolder = "C:\EPLServer\labels\_failed"
)
Add-Type -AssemblyName System.Drawing
if (-not (Test-Path $WatchFolder)) {
New-Item -ItemType Directory -Path $WatchFolder -Force | Out-Null
}
if (-not (Test-Path $FailedFolder)) {
New-Item -ItemType Directory -Path $FailedFolder -Force | Out-Null
}
# -------------------------------------------------------------------------
# Waits until a file is fully written and no longer locked by another
# process (EPLServer may still be flushing it to disk when the Created
# event fires).
# -------------------------------------------------------------------------
function Wait-FileReady {
param([string]$Path, [int]$TimeoutMs = 5000)
$elapsed = 0
while ($elapsed -lt $TimeoutMs) {
try {
$stream = [System.IO.File]::Open($Path, 'Open', 'Read', 'None')
$stream.Close()
return $true
} catch {
Start-Sleep -Milliseconds 150
$elapsed += 150
}
}
return $false
}
# -------------------------------------------------------------------------
# Prints a label image (PNG/JPG) at its real physical size onto a standard
# sheet of paper (A4 or Letter), positioned at (OffsetXIn, OffsetYIn).
# -------------------------------------------------------------------------
function Print-LabelImage {
param(
[Parameter(Mandatory)][string]$ImagePath,
[Parameter(Mandatory)][string]$PrinterName,
[Parameter(Mandatory)][string]$PageSize,
[double]$LabelWidthIn,
[double]$LabelHeightIn,
[double]$OffsetXIn,
[double]$OffsetYIn
)
$img = [System.Drawing.Image]::FromFile($ImagePath)
try {
$pd = New-Object System.Drawing.Printing.PrintDocument
$pd.PrinterSettings.PrinterName = $PrinterName
if (-not $pd.PrinterSettings.IsValid) {
$available = (Get-Printer).Name -join ', '
throw "Printer '$PrinterName' was not found or is not available. Detected printers: $available"
}
# Select the requested standard paper size (A4 or Letter) from
# what the driver reports, instead of forcing a custom size.
$kindWanted = if ($PageSize -eq "A4") {
[System.Drawing.Printing.PaperKind]::A4
} else {
[System.Drawing.Printing.PaperKind]::Letter
}
$matchedPaper = $null
foreach ($ps in $pd.PrinterSettings.PaperSizes) {
if ($ps.Kind -eq $kindWanted) {
$matchedPaper = $ps
break
}
}
if ($matchedPaper) {
$pd.DefaultPageSettings.PaperSize = $matchedPaper
} else {
Write-Warning "Printer '$PrinterName' does not report a '$PageSize' paper size; falling back to its default paper size."
}
$pd.DefaultPageSettings.Margins = New-Object System.Drawing.Printing.Margins(0,0,0,0)
$pd.OriginAtMargins = $false
$handler = {
param($sender, $e)
# 100 units = 1 inch in GDI+ page units used by PrintDocument
$destRect = New-Object System.Drawing.RectangleF(
[float]($OffsetXIn * 100),
[float]($OffsetYIn * 100),
[float]($LabelWidthIn * 100),
[float]($LabelHeightIn * 100)
)
$e.Graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
$e.Graphics.DrawImage($img, $destRect)
$e.HasMorePages = $false
}
$pd.add_PrintPage($handler)
$pd.Print()
}
finally {
$img.Dispose()
}
}
# -------------------------------------------------------------------------
# FileSystemWatcher: triggers printing whenever a new label file appears
# -------------------------------------------------------------------------
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $WatchFolder
$watcher.Filter = "*.*" # extension is filtered below (png/jpg)
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
$action = {
$path = $Event.SourceEventArgs.FullPath
$ext = [System.IO.Path]::GetExtension($path).ToLowerInvariant()
if ($ext -notin @(".png", ".jpg", ".jpeg")) { return }
if (-not (Wait-FileReady -Path $path)) {
Write-Warning "Timed out waiting for '$path' to become ready."
return
}
try {
Print-LabelImage -ImagePath $path `
-PrinterName $using:PrinterName `
-PageSize $using:PageSize `
-LabelWidthIn $using:LabelWidthIn `
-LabelHeightIn $using:LabelHeightIn `
-OffsetXIn $using:OffsetXIn `
-OffsetYIn $using:OffsetYIn
Write-Host "$(Get-Date -Format 'HH:mm:ss') Printed: $path"
if ($using:DeleteAfterPrint) {
Remove-Item -LiteralPath $path -Force
}
}
catch {
Write-Warning "Failed to print '$path': $($_.Exception.Message)"
try {
Move-Item -LiteralPath $path -Destination $using:FailedFolder -Force
} catch {}
}
}
Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action | Out-Null
Write-Host "Watching '$WatchFolder' -> printing to '$PrinterName' on $PageSize paper. Press Ctrl+C to stop." -ForegroundColor Cyan
# Keeps the script alive
try {
while ($true) { Start-Sleep -Seconds 1 }
}
finally {
Get-EventSubscriber | Unregister-Event
$watcher.Dispose()
}
Windows PowerShell — render to image → forward to a listener → printing
#------------------------------------------------------------------------
# In EPLServer, instead of "action": "writetofile", use:
# "action": "forward",
# "forwardTo": "http://127.0.0.1:9191/print"
#
# Then run a local listener that receives the POST body and prints it
# immediately, without touching disk. Minimal example:
#------------------------------------------------------------------------
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://127.0.0.1:9191/print/")
$listener.Start()
Write-Host "Listening for EPLServer forwardTo requests on http://127.0.0.1:9191/print/"
while ($listener.IsListening) {
$context = $listener.GetContext()
$req = $context.Request
$ms = New-Object System.IO.MemoryStream
$req.InputStream.CopyTo($ms)
$bytes = $ms.ToArray()
$tmp = [System.IO.Path]::GetTempFileName() + ".png"
[System.IO.File]::WriteAllBytes($tmp, $bytes)
try {
Print-LabelImage -ImagePath $tmp -PrinterName $PrinterName -PageSize $PageSize `
-LabelWidthIn $LabelWidthIn -LabelHeightIn $LabelHeightIn `
-OffsetXIn $OffsetXIn -OffsetYIn $OffsetYIn
} finally {
Remove-Item $tmp -Force -ErrorAction SilentlyContinue
}
$context.Response.StatusCode = 200
$context.Response.Close()
}
macOS / Linux — render to image → save to disk → file system watcher → printing
#!/usr/bin/env bash
#
# Watch-And-Print-EPL.sh
#
# Watches the EPLServer output folder (action: "writetofile", fileFormat: "PDF")
# and prints each rendered label to a standard HP printer installed on
# macOS/Linux, using CUPS (lp) on regular A4 or Letter paper.
#
# EPLServer does not support "redirect printing", it can only save the rendered
# output to disk ("writetofile") # or forward it to a webhook ("forward").
# This script bridges that gap by watching the folder EPLServer writes to and
# printing each new label as soon as it appears.
#
# REQUIREMENTS
# - EPLServer configured with fileFormat "PDF".
# - CUPS client tools (`lp`, `lpstat`) available:
# macOS -> included by default.
# Linux -> install with: sudo apt-get install cups-client
# - The target printer must already be added/shared in CUPS
# (System Settings > Printers & Scanners on macOS, or `lpadmin`/
# CUPS web UI on Linux). List installed printers with: lpstat -p
# - (Optional, recommended) fswatch for real-time folder monitoring:
# macOS -> brew install fswatch
# Linux -> sudo apt-get install fswatch
# If fswatch is not installed, the script falls back to polling.
#
# USAGE
# chmod +x Watch-And-Print-EPL.sh
# PRINTER_NAME="HP_LaserJet_Pro_M404" WATCH_FOLDER="/usr/local/eplserver/labels" \
# ./Watch-And-Print-EPL.sh
#
# All settings can also be edited directly below instead of passed as
# environment variables.
set -euo pipefail
# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
WATCH_FOLDER="${WATCH_FOLDER:-/usr/local/eplserver/labels}"
FAILED_FOLDER="${FAILED_FOLDER:-$WATCH_FOLDER/_failed}"
PRINTER_NAME="${PRINTER_NAME:-HP_LaserJet_Pro_M404}" # exact CUPS queue name, see: lpstat -p
PAGE_SIZE="${PAGE_SIZE:-Letter}" # Letter or A4
FIT_MODE="${FIT_MODE:-fit-to-page}" # fit-to-page | natural
DELETE_AFTER_PRINT="${DELETE_AFTER_PRINT:-true}"
POLL_INTERVAL="${POLL_INTERVAL:-1}" # seconds, only used by the polling fallback
mkdir -p "$WATCH_FOLDER" "$FAILED_FOLDER"
log() {
printf '%s %s\n' "$(date '+%H:%M:%S')" "$*"
}
# ---------------------------------------------------------------------------
# Waits until a file's size is stable across two checks, meaning EPLServer
# has finished writing it to disk (avoids printing a half-written PDF).
# ---------------------------------------------------------------------------
wait_file_ready() {
local file="$1"
local timeout_ticks=20 # ~ timeout_ticks * 0.3s = 6s max wait
local tick=0
local prev_size=-1
while [ "$tick" -lt "$timeout_ticks" ]; do
[ -f "$file" ] || return 1
local size
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null || echo -1)
if [ "$size" != "-1" ] && [ "$size" != "0" ] && [ "$size" = "$prev_size" ]; then
return 0
fi
prev_size="$size"
sleep 0.3
tick=$((tick + 1))
done
return 1
}
# ---------------------------------------------------------------------------
# Prints a single PDF label file to the configured HP printer via CUPS.
# ---------------------------------------------------------------------------
print_label() {
local file="$1"
if ! command -v lp >/dev/null 2>&1; then
log "ERROR: 'lp' command not found. Install CUPS client tools (cups-client on Linux; CUPS ships with macOS)."
return 1
fi
local fit_opts
if [ "$FIT_MODE" = "fit-to-page" ]; then
# Scales the label PDF to fit within the printable area of the page.
fit_opts="-o fit-to-page"
else
# Prints the label at its real physical size, anchored top-left,# instead of scaling it to fill the page.
fit_opts="-o natural-scaling=100 -o position=top-left"
fi
local lp_log
lp_log="$(mktemp)"
# shellcheck disable=SC2086
if lp -d "$PRINTER_NAME" -o media="$PAGE_SIZE" $fit_opts "$file" >"$lp_log" 2>&1; then
log "Printed: $file"
rm -f "$lp_log"
return 0
else
log "ERROR printing '$file': $(cat "$lp_log")"
rm -f "$lp_log"
return 1
fi
}
# ---------------------------------------------------------------------------
# Handles a newly detected file: waits for it to be ready, prints it, then
# either deletes it or moves it to the failed folder.
# ---------------------------------------------------------------------------
handle_file() {
local file="$1"
local ext="${file##*.}"
case "$ext" in
pdf|PDF) ;;
*) return 0 ;; # ignore anything that isn't a PDF
esac
if ! wait_file_ready "$file"; then
log "WARNING: timed out waiting for '$file' to become ready."
return
fi
if print_label "$file"; then
if [ "$DELETE_AFTER_PRINT" = "true" ]; then
rm -f "$file"
fi
else
mv -f "$file" "$FAILED_FOLDER/" 2>/dev/null || true
fi
}
log "Watching '$WATCH_FOLDER' -> printing to '$PRINTER_NAME' on $PAGE_SIZE paper (mode: $FIT_MODE)."
# ---------------------------------------------------------------------------
# Preferred: fswatch for real-time, event-driven monitoring.
# Fallback: simple polling loop, works everywhere with no extra dependencies.
# ---------------------------------------------------------------------------
if command -v fswatch >/dev/null 2>&1; then
log "Using fswatch for real-time folder monitoring."
fswatch -0 "$WATCH_FOLDER" | while IFS= read -r -d "" changed_file; do
[ -f "$changed_file" ] && handle_file "$changed_file"
done
else
log "fswatch not found; falling back to polling every ${POLL_INTERVAL}s."
log "Tip: install fswatch for lower latency (brew install fswatch / apt-get install fswatch)."
declare -A seen
while true; do
shopt -s nullglob
for f in "$WATCH_FOLDER"/*.pdf "$WATCH_FOLDER"/*.PDF; do
if [ -z "${seen[$f]:-}" ]; then
seen[$f]=1
handle_file "$f"
fi
done
shopt -u nullglob
sleep "$POLL_INTERVAL"
done
fi
macOS / Linux — render to image → forward to a listener → printing
# In EPLServer, instead of "action": "writetofile", use:
# "action": "forward",
# "forwardTo": "http://127.0.0.1:9191/print"
#
# Then run a small local HTTP listener that receives the POST body and
# prints it immediately, without touching disk. Minimal Python 3 example
# (Python 3 ships by default on macOS and most Linux distributions):
# Run it with: python3 forward_listener.py
#!/usr/bin/env python3
import subprocess, tempfile
from http.server import BaseHTTPRequestHandler, HTTPServer
PRINTER_NAME = "HP_LaserJet_Pro_M404"
PAGE_SIZE = "Letter"
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.get("Content-Length", 0))
body = self.rfile.read(length)
with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as f:
f.write(body)
tmp_path = f.name
result = subprocess.run(
["lp", "-d", PRINTER_NAME, "-o", f"media={PAGE_SIZE}",
"-o", "fit-to-page", tmp_path],
capture_output=True, text=True,
)
if result.returncode == 0:
print(f"Printed: {tmp_path}")
self.send_response(200)
else:
print(f"ERROR printing: {result.stderr}")
self.send_response(500)
self.end_headers()
HTTPServer(("127.0.0.1", 9191), Handler).serve_forever()
5 — Command-Line Interface (CLI)
Run eplserver from a terminal with the following flags:
Command
Description
eplserver
Start the background service (normal mode).
eplserver --settings
Open the Settings page in the default browser.
eplserver --logs
Open the Logs page in the default browser.
eplserver --port
Print the port EPLServer is currently listening on.
eplserver --device-id
Print the unique Device ID for this installation (used for licensing).
eplserver --health
Check whether the service is running. Exits with code 0 (OK) or 1 (FAIL).
eplserver --set-port <port>
Change the listening port (hot-reload if running)
eplserver --set-license <key>
Set the license key (hot-reload if running)
eplserver --doc
Show the doc page in the default browser.
eplserver --help
Show this summary in the console.
On Windows the service can be registered as a Windows Service via sc or the Services MMC snap-in, so it starts automatically at boot without any user logged in.
On macOS / Linux use launchd or systemd respectively — EPLServer natively supports UseSystemd().
EPL Commands Support
EPLServer rendering engine supports most of the EPL formatting and control commands. The following table lists the supported commands. Not listed or unsupported commands will be skipped in the parsing stage.
IMPORTANT NOTE Barcode symbols, particularly 2D-type like QR Code, Data Matrix, Aztec Code, Maxicode..., might look different to the one printed by a real printer because Virtual EPL Printer Driver leverages on its own barcode encoder. However, this does not mean that the rendered barcodes will not be readable at all.
Status
EPL Command
Notes
A - ASCII Text
Latin resident fonts 1, 2, 3, 4, 5, 6, and 7
B - Linear Bar Code
Code 39, Code 93, Code 128, UCC Serial Shipping Container, Codabar, EAN 8-13, German Post Code, Interleaved 2 of 5, Postnet, Planet, UCC/EAN 128, UPC A-E, Plessey, MSI