Imagine a warehouse processing 300 orders a day. Each label is manually printed from a Word template: copying the address, product name, weight. One label takes 2–3 seconds. On a daily scale — that's over 2 hours of monotonous work plus inevitable errors (about 5% of orders with wrong addresses). When volumes increase to 500 orders, manual labeling becomes a critical bottleneck: employees get distracted, the percentage of returns due to incorrect addresses grows. Setting up label generation and printing from 1C-Bitrix automates this process: generation with one button from the order card or batch from the list. Our engineers have over 10 years of Bitrix development experience, so we solve the task "turnkey" considering your equipment.
Supported Formats: PDF and ZPL
Labels are generated in two main formats: PDF — for thermal printing and standard printers — we use the mPDF library (best for Cyrillic and CSS styling); ZPL (Zebra Programming Language) — for industrial printers Zebra, TSC, Honeywell. We send ZPL commands directly to the printer via TCP/IP without generating a PDF — maximum printing speed (up to 4 labels per second). The choice of format depends on the available equipment: PDF suits office printers, ZPL is for conveyor printing.
Install mPDF and barcode generator via Composer:
composer require mpdf/mpdf
composer require picqer/php-barcode-generator
Format comparison:
| Parameter | ZPL | |
|---|---|---|
| Compatibility | Any printers | Zebra, TSC, Honeywell |
| Speed | Medium (HTML→PDF conversion) | Maximum (direct sending) |
| Customization | Via HTML/CSS | Via ZPL commands |
| Barcodes | Embedded as PNG | Generated with ^BC commands |
Label Templates
The label is an HTML template with data substitution. Stored in /local/templates/.default/labels/:
<!-- shipping_label.html -->
<div class="label" style="width:100mm; height:150mm; font-family: Arial;">
<div class="sender">
<strong>OOO Magazin</strong><br>
Moscow, ul. Lenina, 1
</div>
<div class="barcode">
<img src="barcode_{ORDER_ID}.png" width="200">
</div>
<div class="recipient">
<strong>{RECIPIENT_NAME}</strong><br>
{RECIPIENT_ADDRESS}<br>
{RECIPIENT_PHONE}
</div>
<div class="order-info">
Order #{ORDER_ID} | {ORDER_DATE}<br>
Weight: {WEIGHT} kg | Items: {ITEMS_COUNT}
</div>
</div>
Label Generator
Generator code (click to expand)
namespace Custom\Warehouse;
class LabelGenerator {
public function generateShippingLabel(int $orderId): string {
$order = \Bitrix\Sale\Order::load($orderId);
if (!$order) throw new \Exception("Order $orderId not found");
$shipment = $this->getMainShipment($order);
$propertyCollection = $order->getPropertyCollection();
$data = [
'{ORDER_ID}' => $order->getId(),
'{ORDER_DATE}' => $order->getDateInsert()->format('d.m.Y'),
'{RECIPIENT_NAME}' => $propertyCollection->getPayerName()->getValue(),
'{RECIPIENT_PHONE}' => $propertyCollection->getPhone()->getValue(),
'{RECIPIENT_ADDRESS}' => $this->buildAddress($propertyCollection),
'{WEIGHT}' => $this->calculateWeight($order),
'{ITEMS_COUNT}' => $order->getBasket()->count(),
];
$template = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/local/templates/.default/labels/shipping_label.html');
$html = str_replace(array_keys($data), array_values($data), $template);
// Generate barcode
$this->generateBarcode($orderId);
return $this->htmlToPdf($html, $orderId);
}
private function generateBarcode(int $orderId): void {
$generator = new \Picqer\Barcode\BarcodeGeneratorPNG();
$barcode = $generator->getBarcode((string)$orderId, $generator::TYPE_CODE_128);
file_put_contents($_SERVER['DOCUMENT_ROOT'] . '/upload/labels/barcode_' . $orderId . '.png', $barcode);
}
private function htmlToPdf(string $html, int $orderId): string {
$mpdf = new \Mpdf\Mpdf([
'mode' => 'utf-8',
'format' => [100, 150], // 100mm x 150mm
'margin_top' => 5,
'margin_bottom' => 5,
'margin_left' => 5,
'margin_right' => 5,
]);
$mpdf->WriteHTML($html);
$outputPath = '/upload/labels/label-' . $orderId . '.pdf';
$mpdf->Output($_SERVER['DOCUMENT_ROOT'] . $outputPath, 'F');
return $outputPath;
}
}
How to Add a Print Button to the Bitrix Admin Panel?
The "Print Label" button is added to the order card via the OnAdminContextMenuShow handler or via a custom action in sale/order_detail.php. On click, a PDF is generated and opened in a new browser tab.
For batch printing (multiple orders from the list) — an action "Print Labels" via checkbox-selection in sale/order_list.php. A single multi-page PDF is generated. Example code for adding the action:
// event OnAdminSaleOrderListMenu
function addPrintLabelsAction(\Bitrix\Main\Event $event) {
$items = &$event->getParameter('items');
$items[] = [
'TEXT' => 'Print Labels',
'ACTION' => 'printLabels()',
'ICON' => 'adm-btn-print',
];
}
Direct Printing without PDF (ZPL)
For Zebra printers, the label is formed in ZPL and sent directly:
function printZebraLabel(int $orderId, string $printerIp, int $printerPort = 9100): void {
$zpl = "^XA\n^FO50,50^A0N,30,30^FD Order #$orderId ^FS\n^XZ";
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, $printerIp, $printerPort);
socket_send($socket, $zpl, strlen($zpl), 0);
socket_close($socket);
}
How is the Barcode Generated?
The barcode is generated based on the order ID using the picqer/php-barcode-generator library. Supports Code 128, QR, and other formats. The PNG file is saved in /upload/labels/ and inserted into the HTML template. In ZPL, the barcode is formed with ^BC commands, which does not require image generation.
Why Does Label Printing Automation Save Money?
Errors in manual label filling are costly: wrong address — return of goods, lost customer, re-shipment. Our case: an online store with 300 orders per day before automation spent 2 hours on labeling and had 5% defects. After implementation, time dropped to 5 minutes, errors to 0.5%. Logistics savings amounted to 18% due to reduced returns. The average cost of a return (logistics + lost revenue) was significant — after implementation, this amount dropped several times. Label printing automation pays for itself in an average of 2 months.
Step-by-Step Setup for Your Project
- Gather requirements: order volumes, printer types, label format, barcode necessity.
- Develop an HTML label template according to your design (layout or example required).
- Implement PDF and/or ZPL generator, integrate with your printers.
- Add a print button to the order card and/or batch printing.
- Test on 50-100 orders, train employees.
Implementation Timeline
| Scope of Work | Timeline |
|---|---|
| HTML template + PDF generation + button in order | 1–2 days |
| Barcodes + batch printing | +1 day |
| ZPL for Zebra + network printing | +1 day |
| Integration with shipping labels for SDEK/Russian Post | separate task |
What's Included in the Work
- Development of HTML label template according to your design
- PDF and/or ZPL generation
- Barcodes (Code 128, QR)
- Print button in order card
- Batch printing from order list
- Integration with network printers (Zebra, TSC, etc.)
- Documentation for setup and support
- Employee training (remote or on-site)
We guarantee stable operation of the solution after implementation. Finalize the project within 3–5 days depending on complexity. Contact us for an assessment of your project — we'll find the optimal solution for your warehouse. Request a consultation, and we'll send a commercial proposal within 24 hours.







