|
|
using Estsh.Client.Base;
|
|
|
using System.Data;
|
|
|
using System.Net.Sockets;
|
|
|
using System.Runtime.InteropServices;
|
|
|
using System.Text;
|
|
|
|
|
|
namespace Estsh.Client.ZPLPrinter
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 中文字符串类
|
|
|
/// </summary>
|
|
|
public class CNStr
|
|
|
{
|
|
|
public string Id;
|
|
|
public string Text;
|
|
|
public int XPos;
|
|
|
public int YPos;
|
|
|
public int Height;
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 使用 ZPL 指令直接打印条码
|
|
|
/// </summary>
|
|
|
public class PrintSNByZPL : StepBase
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// 打印条码
|
|
|
/// </summary>
|
|
|
/// <param name="snData">数据源</param>
|
|
|
/// <param name="templateFile">ZPL模板名称</param>
|
|
|
/// <param name="printerIP">打印机IP地址</param>
|
|
|
/// <param name="printerPort">打印机端口号</param>
|
|
|
/// <param name="copies">打印份数</param>
|
|
|
/// <returns>是否打印成功</returns>
|
|
|
public bool PrintSerialNumber(List<dynamic> snData, string templateFile, string printerIP, int printerPort, int copies)
|
|
|
{
|
|
|
if (snData == null || snData.Count == 0)
|
|
|
{
|
|
|
ShowMessage(this, "未包含打印数据!");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (!File.Exists(templateFile))
|
|
|
{
|
|
|
ShowMessage(this, "文件不存在!" + templateFile);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 此处最好加上 Ping 打印机的指令
|
|
|
|
|
|
// 存放处理好的打印指令,统一输出到打印机
|
|
|
List<string> PrintPool = new List<string>();
|
|
|
|
|
|
// 单个条码的打印指令
|
|
|
StringBuilder ZPLString = new StringBuilder(10 * 1024);
|
|
|
|
|
|
// 单个条码中的所有中文字符串
|
|
|
List<CNStr> CNStrs = new List<CNStr>();
|
|
|
|
|
|
// 处理 ZPL 模板文件
|
|
|
using (StreamReader sr = new StreamReader(templateFile))
|
|
|
{
|
|
|
while (!sr.EndOfStream)
|
|
|
{
|
|
|
string NewLine = sr.ReadLine();
|
|
|
|
|
|
// 有中文字符优先处理
|
|
|
if (NewLine.Contains("<CNStr:"))
|
|
|
{
|
|
|
CNStr cnStr = new CNStr();
|
|
|
|
|
|
string[] ArrayStr = NewLine.Replace(">", "").Split(':');
|
|
|
|
|
|
ArrayStr = ArrayStr[1].Split(',');
|
|
|
|
|
|
cnStr.Id = ArrayStr[0];
|
|
|
cnStr.XPos = Convert.ToInt32(ArrayStr[1]);
|
|
|
cnStr.YPos = Convert.ToInt32(ArrayStr[2]);
|
|
|
cnStr.Height = Convert.ToInt32(ArrayStr[3]);
|
|
|
|
|
|
CNStrs.Add(cnStr);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ZPLString.Append(NewLine);
|
|
|
ZPLString.Append(Environment.NewLine);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 遍历数据行
|
|
|
foreach (var dr in snData)
|
|
|
{
|
|
|
// 每个标签的打印指令
|
|
|
StringBuilder NewPrintZPLString = new StringBuilder(ZPLString.ToString());
|
|
|
|
|
|
// 遍历每一列
|
|
|
foreach (var dc in dr.GetType().GetProperties())
|
|
|
{
|
|
|
// 替换非中文字符变量,<VarName> 格式表示
|
|
|
NewPrintZPLString.Replace(string.Format("<{0}>", dc.Name.Trim()), dr[dc.Name].ToString());
|
|
|
}
|
|
|
// 处理所有的中文字符串
|
|
|
foreach (CNStr cnStr in CNStrs)
|
|
|
{
|
|
|
if (dr.GetType().GetProperties().Contains(cnStr.Id))
|
|
|
{
|
|
|
// 如果数据源中存在这个字段,则替换具体的变量值
|
|
|
cnStr.Text = dr[cnStr.Id].ToString();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 数据源中不存在这个字段就清空,防止残留变量值
|
|
|
cnStr.Text = string.Empty;
|
|
|
}
|
|
|
}
|
|
|
NewPrintZPLString.Append(GetZPLStringByCNStrs(CNStrs));
|
|
|
|
|
|
// 按照打印份数加入打印队列
|
|
|
for(int i=0; i < copies; i++)
|
|
|
{
|
|
|
PrintPool.Add(NewPrintZPLString.ToString());
|
|
|
}
|
|
|
}
|
|
|
// 输出到打印机
|
|
|
return PrintZPL(printerIP, printerPort, PrintPool);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 把处理好的 ZPL 指令队列输出到打印机
|
|
|
/// </summary>
|
|
|
/// <param name="printerIP">打印机 IP 地址</param>
|
|
|
/// <param name="printerPort">打印机端口号</param>
|
|
|
/// <param name="zpls">ZPL指令队列</param>
|
|
|
public bool PrintZPL(string printerIP, int printerPort, List<string> zpls)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
using (StreamWriter sw = new StreamWriter("log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", true))
|
|
|
{
|
|
|
sw.WriteLine(string.Format("{0}", 1));
|
|
|
sw.Flush();
|
|
|
sw.Close();
|
|
|
}
|
|
|
using (TcpClient client = new TcpClient())
|
|
|
{
|
|
|
client.Connect(printerIP, printerPort);
|
|
|
|
|
|
using (StreamWriter writer = new StreamWriter(client.GetStream()))
|
|
|
{
|
|
|
foreach (string zpl in zpls)
|
|
|
{
|
|
|
writer.Write(zpl);
|
|
|
using (StreamWriter sw = new StreamWriter("log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", true))
|
|
|
{
|
|
|
sw.WriteLine(string.Format("{0}", zpl));
|
|
|
sw.Flush();
|
|
|
sw.Close();
|
|
|
}
|
|
|
writer.Flush();
|
|
|
|
|
|
// 等待传输完成
|
|
|
Thread.Sleep(10);
|
|
|
}
|
|
|
|
|
|
writer.Close();
|
|
|
}
|
|
|
|
|
|
client.Close();
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
catch
|
|
|
{
|
|
|
using (StreamWriter sw = new StreamWriter("log_" + DateTime.Now.ToString("yyyyMMdd") + ".txt", true))
|
|
|
{
|
|
|
sw.WriteLine(string.Format("{0}", 2));
|
|
|
sw.Flush();
|
|
|
sw.Close();
|
|
|
}
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 获取字符串的点阵信息,用于 ZPL 中文打印
|
|
|
[DllImport(@"FNTHEX32.DLL", CharSet = CharSet.Ansi)]
|
|
|
public static extern int GETFONTHEX(
|
|
|
string chnstr,
|
|
|
string fontname,
|
|
|
string chnname,
|
|
|
int orient,
|
|
|
int height,
|
|
|
int width,
|
|
|
int bold,
|
|
|
int italic,
|
|
|
StringBuilder param1);
|
|
|
|
|
|
/// <summary>
|
|
|
/// 中文文本转化成点阵字符串
|
|
|
/// </summary>
|
|
|
/// <param name="text">中文文本</param>
|
|
|
/// <param name="textId">文本的ID,不能重复</param>
|
|
|
/// <param name="height">文本的高度</param>
|
|
|
/// <returns>点阵字符串</returns>
|
|
|
public string TextToHex(string text, string textId, int height)
|
|
|
{
|
|
|
StringBuilder hexBuilder = new StringBuilder(8 * 2048);
|
|
|
|
|
|
int subStrCount = 0;
|
|
|
|
|
|
subStrCount = GETFONTHEX(text, "Arial", textId, 0, height, 0, 1, 0, hexBuilder);
|
|
|
|
|
|
return hexBuilder.ToString().Substring(0, subStrCount);
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
/// 根据一组中文字符串信息获取对应的 ZPL 打印指令
|
|
|
/// </summary>
|
|
|
/// <param name="cnStrs">中文变量集合</param>
|
|
|
private string GetZPLStringByCNStrs(List<CNStr> cnStrs)
|
|
|
{
|
|
|
string labelIdCmd = string.Empty;
|
|
|
string labelContentCmd = string.Empty;
|
|
|
|
|
|
int count = 0;
|
|
|
|
|
|
foreach (CNStr str in cnStrs)
|
|
|
{
|
|
|
if (!string.IsNullOrEmpty(str.Text))
|
|
|
{
|
|
|
labelIdCmd += "^FT" + str.XPos.ToString() + "," + str.YPos.ToString() + "^XG" + str.Id + ",1,1^FS";
|
|
|
labelContentCmd += TextToHex(str.Text, str.Id, str.Height);
|
|
|
|
|
|
count++;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
string content = string.Empty;
|
|
|
|
|
|
if (count > 0)
|
|
|
{
|
|
|
content = labelContentCmd
|
|
|
+ "^LH0,0^PR2,2^FO0,0"
|
|
|
+ labelIdCmd;
|
|
|
}
|
|
|
|
|
|
content += "^PQ1,0,1,Y^XZ";
|
|
|
|
|
|
return content;
|
|
|
}
|
|
|
}
|
|
|
}
|