当我们需要在将货物放在存储货架上之前打印收货的商品标签时,我在基于 Web 的 ERP 系统中遇到了这个确切的问题。我们最初的问题是我们无法让 IE 打印到我们为标签打印机 (Zebra TLP-2844) 配置的指定标签尺寸。IE 总是使用默认打印机的 A4 格式。以“正常方式”打印还导致了许多额外的点击和设置,这些点击和设置只是为了这个简单的任务,只需在基于 Windows 的应用程序中点击一次(您可以更好地控制打印机设置)。
我做了很多研究,发现了一些能够详细控制打印机设置的ActiveX控件,但最终正常的打印方式仍然会导致不必要的点击次数,客户希望它超级简单和超级快速地。
由于我以前有使用标签打印机开发应用程序的经验,因此我知道可以使用打印机的内部打印机语言。在 Zebra 打印机中,它称为 EPL/ZPL。这是一个简单的基于文本的协议,可以通过打印机提供的任何接口使用,例如并行端口、串行端口、USB 或 10/100 以太网。我之前刚刚使用过串行端口接口,但在这个项目中,我必须能够通过互联网,通过防火墙,打印到连接在客户办公室本地网络上的 Zebra 打印机。经过一些研究,事实证明这很容易,最终成为客户的一个非常好的解决方案。
基本的 EPL 语言有其局限性,但通常您只需要一个非常简单的打印输出,包括一些文本和一些条形码或其他东西。您只能使用五种尺寸的固定宽度标准字体。可以将字体宽度和高度设置为原始大小的倍数。如果您需要更高级的打印输出,包括图片或某些布局、字体、大小等,可以通过使用特殊的标签设计应用程序创建模板来完成。模板可以包含调用模板时可以使用的变量。
为了完全理解我的小例子和更多细节,我推荐你下载 EPL Programmers 手册。您可能还必须将打印机配置为能够接受命令,该过程应该在手册中。
下面是一个简单的 ASP.NET 2.0 (C#) 示例。由于我最初制作了一个用于测试的控制台应用程序,因此我刚刚注释掉了一些错误处理。该示例基于功能齐全的客户解决方案,但我已排除并重写了一些部分以使示例更易于理解。我已经测试了基本功能,返回的字符串似乎没问题,但我没有测试打印到 Zebra 打印机,因为我目前无权访问任何内容,因此请注意意外错误。:) 但应该没问题。
祝你好运!
资源:
斑马 - 资源库
注意:您需要注册才能下载 EPL 程序员手册
示例代码:
<%@ 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">
<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>