Setting up label generation and printing from 1C-Bitrix

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages

Label Generation and Printing Setup from 1C-Bitrix

A warehouse processes 200 orders per day, and every label a manager prints manually from Word template. That's 2–3 seconds per label plus errors copying addresses. Automatic label generation directly from order card in Bitrix reduces this to zero and eliminates mistakes.

Label Formats and Libraries

Labels are generated in two main formats:

PDF — for thermal and standard printers. TCPDF or mPDF libraries. mPDF is preferred: better Cyrillic support and CSS styling.

ZPL (Zebra Programming Language) — for industrial Zebra, TSC, Honeywell printers. Sent directly to printer without PDF generation. Maximum print speed.

mPDF installation via Composer:

composer require mpdf/mpdf

Label Templates

Label is 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>LLC Shop</strong><br>
        Moscow, Lenin St., 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 | Pieces: {ITEMS_COUNT}
    </div>
</div>

Label Generator

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);

        return $this->htmlToPdf($html, $orderId);
    }

    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;
    }
}

Barcodes on Labels

For barcode generation (Code 128, QR) use picqer/php-barcode-generator:

composer require picqer/php-barcode-generator
$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);

Integration into Admin

"Print label" button added to order card via OnAdminContextMenuShow handler or custom action in sale/order_detail.php. On click, PDF generates and opens in new browser tab.

For batch printing (multiple orders from list) — "Print labels" action via checkbox-selection in sale/order_list.php. Generates single multi-page PDF.

Direct Printing Without PDF (ZPL)

For Zebra printers, label is formatted 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);
}

Execution Timeline

Scope Timeline
HTML template + PDF generation + button 1–2 days
Barcodes + batch printing +1 day
ZPL for Zebra + network printing +1 day
Integration with carrier labels CDEK/Post separate task

Label printing automation is one of first steps toward order management when volume grows.