views:

523

answers:

1

I have a mysql database containing upc numbers that I would like to print to labels with a zebra printer (LP2824). I would like to somehow be able to send those numbers directly to my label printer, which is not the default printer without the user being prompted.

As far as I can tell, IE is the only option as some type of activeX control is required to make this happen. I found a direct printing example at meadroid.com using ScriptX, but I'm not willing to pay their licensing fee. I also found an example using VBScript that will send the page to the default printer without prompting the user. My problem with that is I can't figure out how to remove the default header and footer present in IE and I can't choose which printer to use.

My question is:

Is there an activeX control out there that I can use via javascript similar to MeadCo's ScriptX but without licensing, or would the VBScript approach be better, in which case how can a person remove the header and footer, and print to the label printer which is not set at default? The ability to just send a series of commands directly to the printer would be ideal.

Here is the test code I have so far:

<head>
<script language='VBScript'>
Sub Print()
       OLECMDID_PRINT = 6
       OLECMDEXECOPT_DONTPROMPTUSER = 2
       OLECMDEXECOPT_PROMPTUSER = 1
       call WB.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER,1)
End Sub
document.write "<object ID='WB' WIDTH=0 HEIGHT=0 CLASSID='CLSID:8856F961-340A-11D0-A96B-00C04FD705A2'></object>"
</script>

</head>

<body>
Helo!!!
<a href="javascript:window.print();">Print</a>

</body>
+3  A: 

Hi,

I've had this exact problem with a web based ERP system when we needed to print article labels for incoming deliveries before putting the goods on the storing shelfs. Our initial problem was that we couldn't get IE to print to a specified label size that we configured for the label printer (Zebra TLP-2844). IE always used the default printer's A4 format. To print the "normal way" also resulted in a lot of extra clicks and settings that had to be made just for this simple task that would only take one click in a windows based application (where you have more control over the printer settings).

I made a lot of research and found some ActiveX control that were able to control the printer settings in detail but in the end the normal way of printing still would result in an unnecessary number of clicks and the customer wanted it to be super simple and super fast.

As I have former experience developing applications using label printers I knew of the printer's internal printer language that could be used. In Zebra printers it's called EPL/ZPL. It's a simple text based protocol that can be used through any of the interfaces that the printer offer e.g. Parallell Port, Serial Port, USB or 10/100 Ethernet. I have just used the serial port interface before but in this project I had to be able to print over the internet, through the firewall, to a Zebra printer connected on the local network at the customers office. After some research this proved to be quite easy actually and it ended up to be a really great solution for the customer.

The basic EPL language has its limits but often you just want a quite simple printout including some text and some bar codes or something. You are limited to a fixed width standard font in five sizes. It's possible to set the font width and height to a multiple of the original size. If you need more advanced printouts including pictures or certain layouts, fonts, sizes, etc, that could be done by creating templates with a special Label Design Application. The templates can contain variables that can be used when calling the template.

To fully understand my little example and for more details I recommend you to download the EPL Programmers manual. You also might have to configure the printer to be able to accept the commands, the procedure should be in the manual.

Below you find a simple example for ASP.NET 2.0 (C#). As I initially made a console application for testing there is some error handling that I just commented out. The example is based on a fully functional customer solution but I have excluded and rewritten some parts to make the example more understandable. I have tested the basic functionality and the returned strings seems to be ok, but I haven't tested to print to a Zebra printer as I don't have access to any at the moment, so be aware of unexpected bugs. :) But it should be ok.

Good luck!

Resources:

Zebra - Resource Library

Note: You need to register to be able to download the EPL Programmers Manual

Example code:

<%@ Import Namespace = "System.Data" %>
<%@ Import Namespace = "System.Text" %>
<%@ Import Namespace = "System.Net.Sockets" %>
<%@ Import Namespace = "System.IO" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;

<script language="C#" runat="server">
    public String strPrintOutput;

    void Page_Load(Object sender,EventArgs e)
    {
        // Build output string - Example - Printer Settings
        //strPrintOutput = BuildString1();

        // Build output string - Example - Print Label with Barcode and some text (Prints two labels)
        strPrintOutput = BuildString2("123456", "2010-01-02", "1234567890", "123", "Harddrive", "D31", "123456", "2");

        // Print output to HTML-page
        txtPrintout.Text = strPrintOutput;

        // Send output to Zebra Printer
        // xxx.xxx.xxx.xxx = The IP of the Zebra printer
        // 9100 = The default printer port, but that could be changed on the printer
        // For external access (e.g. through the internet) you need to use the IP/domain name of the router/firewall and also open a port in the firewall and forward the traffic to the internal IP and port set on the printer
        // Note that for external access appropriate security measures should be added in some way.
        Connect("xxx.xxx.xxx.xxx", 9100, strPrintOutput);
    }

  public void Connect(String ip, Int32 port, String strMessage)
  {
    try
    {
      // Convert String to Byte Array with encoding Windows-1252
      //Byte[] data = System.Text.Encoding.ASCII.GetBytes(strMessage);
      Byte[] data = System.Text.Encoding.GetEncoding(1252).GetBytes(strMessage);

      // Create connection to printer
      TcpClient printer = new TcpClient(ip, port);

      // Get stream object of printer
      NetworkStream strm = printer.GetStream();

      // Write message to stream
      strm.Write(data, 0, data.Length);

      // Status Message
      //Console.WriteLine("Sent: {0}", strMessage);

      // Close stream
      strm.Close();

      //Close connection to printer
      printer.Close();

    } // end try

    catch (ArgumentNullException e)
    {
        //Console.WriteLine("ArgumentNullException: {0}", e);
    }

    catch (SocketException e)
    {
        //Console.WriteLine("SocketException: {0}", e);
    }

    //Console.WriteLine("\n Press Enter to continue...");
    //Console.Read();
  }

  /*
   * \n = LF (Line Feed)
   * \r = CR (Carriage Return)
   * \r\n = CrLf
   * Printer ignores CR when sent
   * CR cannot be used in place of LF
  */
  public String BuildString1()
  {
    StringBuilder sb = new StringBuilder();

    //Clears out printer buffer
    sb.Append("\n");

        //Print the current printer configuration
    sb.Append("U\n");

    return sb.ToString();
  }

  public String BuildString2(String strBarCode, String strDate, String strArticleNumber, String strPurchaseOrderNumber, String strArticleName, String strLocation, String strOrderNumber, String strNoOfLabels)
  {
    StringBuilder sb = new StringBuilder();

    //Clears out printer buffer
    sb.Append("\n");

    //Clears out the image buffer
    sb.Append("N\n");

    //Set 8-bit, CodePage Windows 1252 (Latin 1), KDU Sweden (Printer with display)
    sb.Append("I8,A,046\n");

        // Create Print Objects
    sb.Append("B35,5,0,3C,3,6,60,N,\"" + strBarCode + "\"\n");
    sb.Append("A35,75,0,3,1,1,N,\"Article No:\"\n");
    sb.Append("A35,100,0,3,1,1,N,\"Article Name:\"\n");
    sb.Append("A35,125,0,3,1,1,N,\"Location:\"\n");
    sb.Append("A35,150,0,3,1,1,N,\"Order:\"\n");

    sb.Append("A205,75,0,3,1,1,N,\"" + strArticleNumber + "\"\n");
    sb.Append("A205,100,0,3,1,1,N,\"" + strArticleName + "\"\n");
    sb.Append("A205,125,0,3,1,1,N,\"" + strLocation + "\"\n");
    sb.Append("A205,150,0,3,1,1,N,\"" + strOrderNumber + "\"\n");

    sb.Append("A432,49,0,3,1,1,N,\"" + strDate + "\"\n");
    sb.Append("A530,75,0,3,1,1,N,\"" + strPurchaseOrderNumber + "\"\n");
    sb.Append("P" + strNoOfLabels + "\nN\n\n");

    return sb.ToString();
  }

</script>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Print to Zebra Label Printer</title>
</head>
<body>
    <form id="form1" runat="server">
      <asp:Panel runat="server">
        <asp:TextBox id="txtPrintout" TextMode="MultiLine" runat="server" BackColor="LightBlue" Width="100%" Height="800px"></asp:TextBox>
      </asp:Panel>
    </form>
</body>
</html>
Octadrone