How to print barcode thermal labels to Zebra ZPL or EPL printers at client side in ASP.NET Websites with C# and VB

Prerequisites
  • Neodynamic ThermalLabel SDK 4.0 or greater
  • ASP.NET 3.5 or greater
  • Any Zebra compatible ZPL/EPL thermal printer


In this guide you will learn how to print barcode thermal labels to Zebra compatible ZPL/EPL printers from an ASP.NET website using C# or VB and Neodynamic ThermalLabel SDK.

This guide outlines the scenario known as Client-side Web Printing which basically means that the printing job takes place on the user's machine as is shown in the following figure.



In the figure, each client has a local Thermal printer and an ASP.NET website hosted in the server is in charge of generating the barcode labels. Those labels are previewed on the client by using any internet browser (IE, Firefox, Chrome, Opera, etc) allowing the user to print them to its local printer.

How does stuff work?

After some testing here at Neodynamic, we found the following workflow to be the most reliable way for printing barcode labels to client-side thermal printers.



1- You create an ASP.NET website using VB or C# and create/generate barcode thermal labels using our ThermalLabel SDK (4.0 or greater).
A- You code a Generic HTTP Handler (*.ashx) in VB or C# instantiating the ThermalLabel objects like TextItem, BarcodeItem, etc. and use the ThermalLabel SDK for generating a PDF output of the label. (NOTE: ThermalLabel SDK does NOT require any third-party tool on the server for generating PDF files!)
B- You create an ASP.NET webpage (*.aspx) which will display the generated barcode label in PDF format using the HTML object tag (A complete sample code is available later in this guide)

2- The user access to the ASP.NET webpage and the barcode label is visualized on the page using the browser’s PDF plugin which features a button for printing the PDF document to a local printer.

3- The user's machine needs to have installed Adobe PDF Reader and the Zebra driver for his printer e.g. Zebra Designer Driver (ZDesigner)

4- For printing, the user must click on Print button of PDF plugin. That button will display the Print Dialog on which the user must specify the installed Zebra driver for his printer AND CHANGE the label size on such dialog to match the displayed label size if needed. For instance, if the ThermalLabel SDK is generating a 4in x 3in label, then the same size must be specified on the Print dialog! Otherwise the printing output could be cut off.

A simple ASP.NET website sample
In the following steps, we'll be creating a simple ASP.NET website which will allow a user to fill a form with product information like name and code. That info is used in the server side for generating a thermal label (4in x 3in) displaying the product name as text and the product code as a Code 128 linear barcode. ThermalLabel SDK is used for such task and it will generate a PDF output of the label for displaying and printing it on the user's machine and printer.

To reproduce the sample code, please follow up these steps:
  • Open Visual Studio (2008 or 2010) or Visual Web Developer (2008 or 2010) and create a new ASP.NET website targeting ASP.NET v3.5 or greater. Name your project ThermalLabelAspNetClientSidePrintingCS (if you are using C#) or ThermalLabelAspNetClientSidePrintingVB (if you are using VB)
  • Add a reference to ThermalLabel SDK 4.0 assembly (Neodynamic.SDK.ThermalLabel.dll)
  • Add a new Generic Handler item naming it LabelGen.ashx
    This handler will take info about the product from the query string parameters. With that info, a ThermalLabel object is created with a TextItem and a BarcodeItem. Then the ThermalLabel is generated in PDF format and sent back to the user’s browser. Copy/paste the following code in your LabelGen.ashx file:

    Visual Basic .NET
    Imports System.Web

    Imports Neodynamic.SDK.Printing
    Imports System.Threading

    Public Class LabelGen
    Implements System.Web.IHttpHandler


    Dim m_buffer() As Byte
    Dim m_productId As String = ""
    Dim m_productName As String = ""
    Dim m_dpi As Double = 203

    Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

    'get data for label from the querystring params...
    m_productId = context.Request("prodId")
    m_productName = context.Request("prodName")
    m_dpi = 203
    Try
    m_dpi = Double.Parse(context.Request("dpi"))
    Catch

    End Try

    Me.GenerateThermalLabel()

    context.Response.ContentType = "application/pdf"
    context.Response.BufferOutput = True
    context.Response.BinaryWrite(m_buffer)
    context.Response.Flush()

    End Sub

    ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
    Get
    Return False
    End Get
    End Property

    Private Sub GenerateThermalLabel()
    Dim worker As New Thread(New ThreadStart(AddressOf Me.GenerateThermalLabelWorker))
    worker.SetApartmentState(ApartmentState.STA)
    worker.Name = "GenerateThermalLabelWorker"
    worker.Start()
    worker.Join()
    End Sub


    Private Sub GenerateThermalLabelWorker()
    'Create the thermal label object
    Dim tLabel As New ThermalLabel(UnitType.Inch, 4, 3)

    'Define a TextItem object
    Dim txtItem As New TextItem(0.2, 0.2, 3, 0.5, m_productName)
    'font settings
    txtItem.Font.Name = "Arial"
    txtItem.Font.Unit = FontUnit.Point
    txtItem.Font.Size = 20

    'Define a BarcodeItem object
    Dim bcItem As New BarcodeItem(0.2, 1, 3.6, 1.25, BarcodeSymbology.Code128, m_productId)
    'Set bars height to .75inch
    bcItem.BarHeight = 0.75
    'Set bars width to 0.02inch
    bcItem.BarWidth = 0.02
    'font settings
    bcItem.Font.Name = "Arial"
    bcItem.Font.Unit = FontUnit.Point
    bcItem.Font.Size = 12
    'border settings
    bcItem.BorderThickness = New FrameThickness(0.02)
    bcItem.CornerRadius = New RectangleCornerRadius(0.075)
    'center barcode inside its container
    bcItem.BarcodeAlignment = BarcodeAlignment.MiddleCenter

    'Add items to ThermalLabel object...
    tLabel.Items.Add(txtItem)
    tLabel.Items.Add(bcItem)

    'generate a pdf doc of the label
    Using ms As New System.IO.MemoryStream()
    Using pj As New PrintJob()
    pj.ExportToPdf(tLabel, ms, m_dpi)
    End Using

    m_buffer = ms.ToArray()
    End Using

    End Sub

    End Class


    Visual C#
    using System;
    using System.Web;

    using Neodynamic.SDK.Printing;
    using System.Threading;

    namespace ThermalLabelAspNetClientSidePrintingCS
    {
    ///
    /// Summary description for LabelGen
    ///

    public class LabelGen : IHttpHandler
    {
    byte[] _buffer = null;
    string _productId = "";
    string _productName = "";
    double _dpi = 203;

    public void ProcessRequest(HttpContext context)
    {
    //get data for label from the querystring params...
    _productId = context.Request["prodId"];
    _productName = context.Request["prodName"];
    _dpi = 203;
    try
    {
    _dpi = double.Parse(context.Request["dpi"]);
    }
    catch { }

    this.GenerateThermalLabel();

    context.Response.ContentType = "application/pdf";
    context.Response.BufferOutput = true;
    context.Response.BinaryWrite(_buffer);
    context.Response.Flush();
    }

    public bool IsReusable
    {
    get
    {
    return false;
    }
    }


    private void GenerateThermalLabel()
    {
    Thread worker = new Thread(new ThreadStart(this.GenerateThermalLabelWorker));
    worker.SetApartmentState(ApartmentState.STA);
    worker.Name = "GenerateThermalLabelWorker";
    worker.Start();
    worker.Join();
    }

    private void GenerateThermalLabelWorker()
    {
    //Create the thermal label object
    ThermalLabel tLabel = new ThermalLabel(UnitType.Inch, 4, 3);

    //Define a TextItem object
    TextItem txtItem = new TextItem(0.2, 0.2, 3, 0.5, _productName);
    //font settings
    txtItem.Font.Name = "Arial";
    txtItem.Font.Unit = FontUnit.Point;
    txtItem.Font.Size = 20;

    //Define a BarcodeItem object
    BarcodeItem bcItem = new BarcodeItem(0.2, 1, 3.6, 1.25, BarcodeSymbology.Code128, _productId);
    //Set bars height to .75inch
    bcItem.BarHeight = 0.75;
    //Set bars width to 0.02inch
    bcItem.BarWidth = 0.02;
    //font settings
    bcItem.Font.Name = "Arial";
    bcItem.Font.Unit = FontUnit.Point;
    bcItem.Font.Size = 12;
    //border settings
    bcItem.BorderThickness = new FrameThickness(0.02);
    bcItem.CornerRadius = new RectangleCornerRadius(0.075);
    //center barcode inside its container
    bcItem.BarcodeAlignment = BarcodeAlignment.MiddleCenter;

    //Add items to ThermalLabel object...
    tLabel.Items.Add(txtItem);
    tLabel.Items.Add(bcItem);

    //generate a pdf doc of the label
    using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
    {
    using (PrintJob pj = new PrintJob())
    {
    pj.ExportToPdf(tLabel, ms, _dpi);
    }

    _buffer = ms.ToArray();
    }
    }
    }
    }
  • Now open Default.aspx file and create a simple form. In it the user can enter a Product Name and Code as well as set up the DPI value for generating the thermal label. The PDF thermal label document generated by the LabelGen.ashx file is displayed to the user by a dynamic generated HTML object tag (of type application/pdf). The browser PDF plugin (the Adobe PDF plugin in most cases) allows the user to zoom, save and print the document. Here the print functionality is essential for client-side thermal label printing.

    Open the Default.aspx and copy/paste the following HTML/ASP.NET markup:



    Printing Barcode Labels to Thermal Printers from ASP.NET






    ThermalLabel SDK - Print from client side to thermal printer










    Fill the form:


    Product Name: 


    Product Code: 


    Printer DPI: ropDownList ID="DropDownList1" runat="server">



    ropDownList>

















    After that, open the code-behind class file of the page i.e. Default.aspx.vb or Default.aspx.cs and copy/paste the following code:

    Visual Basic .NET
    Public Class _Default
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    pdfViewer.Text = CreatePdfObjectTag("LabelGen.ashx?dpi=" + DropDownList1.SelectedItem.ToString() + "&prodId=" + TextBox2.Text + "&prodName=" + TextBox1.Text + "&out=PDF")
    End Sub

    Private Function CreatePdfObjectTag(ByVal pdfUrl As String) As String
    Dim sb As New StringBuilder()
    sb.Append(" sb.Append("data=""")
    sb.Append(pdfUrl)
    sb.Append("#toolbar=1&navpanes=0&scrollbar=1&page=1&zoom=100"" width=""600px"" height=""400px"" VIEWASTEXT>

    It appears you don't have a PDF plugin for your browser. sb.Append(pdfUrl)
    sb.Append(""">Click here to download the PDF file.

    ")
    Return sb.ToString()
    End Function

    End Class


    Visual C#
    public partial class _Default : System.Web.UI.Page
    {

    protected void Page_Load(object sender, EventArgs e)
    {
    pdfViewer.Text = CreatePdfObjectTag("LabelGen.ashx?dpi=" + DropDownList1.SelectedItem.ToString() + "&prodId=" + TextBox2.Text + "&prodName=" + TextBox1.Text + "&out=PDF");
    }

    private string CreatePdfObjectTag(string pdfUrl)
    {
    StringBuilder sb = new StringBuilder();
    sb.Append(" sb.Append("data=\"");
    sb.Append(pdfUrl);
    sb.Append("#toolbar=1&navpanes=0&scrollbar=1&page=1&zoom=100\" width=\"600px\" height=\"400px\" VIEWASTEXT>

    It appears you don't have a PDF plugin for your browser. sb.Append(pdfUrl);
    sb.Append("\">Click here to download the PDF file.

    ");
    return sb.ToString();
    }
    }
  • That's it! For testing, just open Default.aspx file in your preferred browser. The page will display the thermal label in PDF format generated by the LabelGen.ashx handler with the default values.


  • Enter some product info like "Super Neo Cycle" for the name and "NEO23900038765" for the product code. Click on "Refresh Preview" button and the thermal label will be re-generated by LabelGen.ashx handler.


  • Finally, for printing, click on the "printer icon button" of the PDF plugin toolbar. The print dialog will appear. IMPORTANT: In the print dialog you must select the installed Zebra printer driver. In the sample, it is a "ZDesigner GK420t". When you select the driver, you get a print preview based on the PAPER size which is set up on the driver. In the figure it is "Paper: 3.0 x 2.0in" while the document i.e. the thermal label generated by the website (LabelGen.ashx) is 4.0 x 3.0in!



    You (or the user) must change the PAPER size of the printer driver to match the thermal label size; otherwise the label output printing is likely to be cut off. To change the PAPER size on the printer driver you must click on "Properties" button on the print dialog. That will display the printer driver properties allowing you to change the paper size.



    When done, click ok on both dialogs and the label will be printed to the user's local thermal printer.


Links:
This Demos
Demos
Download ThermalLabel SDK for .NET
More Information about Neodynamic ThermalLabel SDK for .NET


Neodynamic
.NET Components & Controls
Neodynamic
ThermalLabel SDK for .NET - Print thermal labels on Zebra ZPL and EPL printers from C# and VB