You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

254 lines
8.7 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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