主要是通过XML文件做模板来实现打印;
模板如下:
1<?xml version="1.0" encoding="utf-8" ?>
2<!--
3说明:
4justification
5center 中间对齐
6right 右对齐
7left 左对齐
8style
90 正常
101 倍宽
112 倍高
123 四倍角
13
14color
150 黑色
161 红色
17-->
18<root>
19 <template id="OCT01" name="一卡通储值卡发卡凭证">
20 <title text="一卡通发卡凭证" style="2" color="0" justification="center"/>
21 <body>
22 <item text="用户卡号:" value="CardSerialNumber" style="0" color="0"></item>
23 <item text="卡片类型:" value="productName" style="0" color="0"></item>
24 <item text="卡有效期:" value="productValidityEndDate" style="0" color="0"></item>
25 <item text="发卡押金:" value="carddepositvalue" style="0" color="0"></item>
26 <item text="交易时间:" value="transactionTime" style="0" color="0"></item>
27 <item text="网点编号:" value="NetStationID" style="0" color="1"></item>
28 <item text="操作员ID:" value="staffId" style="0" color="0"></item>
29 </body>
30 </template>
31 <template id="OCT02" name="一卡通储值卡发卡凭证">
32 <title text="充值凭证" style="2" color="0" justification="center"/>
33 <body>
34 <item text="用户卡号:" value="CardSerialNumber" style="0" color="0"></item>
35 <item text="卡片类型:" value="productName" style="0" color="0"></item>
36 <item text="卡有效期:" value="productValidityEndDate" style="0" color="0"></item>
37 <item text="充值前余额:" value="balance2" style="0" color="0"></item>
38 <item text="充值金额:" value="revalue" style="0" color="0"></item>
39 <item text="充值后金额:" value="balance" style="0" color="0"></item>
40 <item text="交易时间:" value="transactionTime" style="0" color="0"></item>
41 <item text="网点编号:" value="NetStationID" style="0" color="0"></item>
42 <item text="操作员ID:" value="staffId" style="0" color="0"></item>
43 </body>
44 </template>
45
46
47 <template id="ACC01" name="一票通储值卡发卡凭证">
48 <title text="一票通发卡凭证" style="2" color="0" justification="center"/>
49 <body>
50 <item text="用户卡号:" value="otherCardSerialNumber" style="0" color="0"></item>
51 <item text="车票种类:" value="productName" style="0" color="0"></item>
52 <item text="卡有效期:" value="ValidityEndDate" style="0" color="0"></item>
53 <item text="发卡押金:" value="carddepositvalue" style="0" color="0"></item>
54 <item text="交易时间:" value="transactionTime" style="0" color="0"></item>
55 <item text="车站名称:" value="stationName" style="0" color="0"></item>
56 <item text="设备编号:" value="deviceId" style="0" color="0"></item>
57 <item text="操作员ID:" value="staffId" style="0" color="0"></item>
58 </body>
59 </template>
60 <template id="ACC02" name="一票通储值卡发卡凭证">
61 <title text="充值凭证" style="2" color="0" justification="center"/>
62 <body>
63 <item text="用户卡号:" value="otherCardSerialNumber" style="0" color="0"></item>
64 <item text="车票种类:" value="productName" style="0" color="0"></item>
65 <item text="卡有效期:" value="ValidityEndDate" style="0" color="0"></item>
66 <item text="充值前金额:" value="" style="0" color="0"></item>
67 <item text="充值金额:" value="" style="0" color="0"></item>
68 <item text="充值后金额:" value="" style="0" color="0"></item>
69 <item text="交易时间:" value="transactionTime" style="0" color="0"></item>
70 <item text="车站名称:" value="stationName" style="0" color="0"></item>
71 <item text="设备编号:" value="deviceId" style="0" color="0"></item>
72 <item text="操作员ID:" value="staffId" style="0" color="0"></item>
73 </body>
74 </template>
75</root>
一、创建的打印类:Printer.cs
1using System;二、PrinterCommand.cs类
2using System.Collections.Generic;
3using System.Text;
4using System.IO.Ports;
5
6namespace BOM.NewUI.PrinterManager
7{
8 /// <summary>
9 /// 打印机
10 /// </summary>
11 public class Printer
12 {
13 /// <summary>
14 /// 获取打印机状态
15 /// </summary>
16 /// <param name="sp">SerialPort对象</param>
17 /// <param name="buffer">指令</param>
18 /// <returns>状态代码</returns>
19 private int GetState(SerialPort sp, byte[] buffer)
20 {
21 sp.Write(buffer, 0, buffer.Length);
22 return sp.ReadChar();
23 }
24 /// <summary>
25 /// 开钱箱
26 /// </summary>
27 /// <returns>是否打开</returns>
28 public static bool OpenMoneyBox()
29 {
30 bool result = false;
31 SerialPort sp = CreateSerialPort("票据打印机");
32 try
33 {
34 if (!sp.IsOpen)
35 sp.Open();
36 WriteData(sp, PrinterCommand.CMD_OPENMONEYBOX);
37 // sp.Write(new byte[] { 0x1B, 0x70, 0x30, 0x20, 0xF6 }, 0, 5);
38 sp.DiscardOutBuffer();
39 sp.Close();
40 result = true;
41 }
42 catch
43 {
44 throw;
45 }
46 return result;
47 }
48 /// <summary>
49 /// 创建串口对象
50 /// </summary>
51 /// <param name="portName"></param>
52 /// <returns></returns>
53 public static SerialPort CreateSerialPort(string portName)
54 {
55 ConfigManager config = new ConfigManager();
56 SerialPortInfo info = config.GetConfig(portName);
57 SerialPort sp = new SerialPort(info.portName, info.baudRate, info.parity, info.dataBits, info.stopBits);
58 sp.ReadTimeout = 1000;
59 if (!sp.IsOpen)
60 sp.Open();
61 return sp;
62 }
63
64 /// <summary>
65 /// 向串口写数据
66 /// </summary>
67 /// <param name="sp">SerialPort对象</param>
68 /// <param name="buffer">数据</param>
69 public static void WriteData(SerialPort sp, byte[] buffer)
70 {
71 sp.Write(buffer, 0, buffer.Length);
72 }
73 /// <summary>
74 /// 票据打印
75 /// </summary>
76 /// <param name="sp">SerialPort对象</param>
77 /// <param name="templateID">票据模板编号</param>
78 public static void Print(SerialPort sp,string templateID)
79 {
80 Template t = new Template();
81 t.Print(sp, templateID);
82 }
83 }
84}
85
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace BOM.NewUI.PrinterManager
6{
7 /// <summary>
8 /// 打印机指令
9 /// </summary>
10 public abstract class PrinterCommand
11 {
12 /// <summary>
13 /// 打印机初始化
14 /// </summary>
15 public static byte[] CMD_INIT = new byte[] { 0x1b, 0x40 };
16
17 /// <summary>
18 /// 居右
19 /// </summary>
20 public static byte[] CMD_RIGHT = new byte[] {0x1b,0x61,0x02 };
21
22 /// <summary>
23 /// 居左
24 /// </summary>
25 public static byte[] CMD_LEFT = new byte[] { 0x1b, 0x61, 0x00 };
26
27 /// <summary>
28 /// 居中
29 /// </summary>
30 public static byte[] CMD_CENTER = new byte[] { 0x1b, 0x61, 0x01 };
31
32 /// <summary>
33 /// 倍高and倍宽
34 /// </summary>
35 public static byte[] CMD_DOUBLEHEIGHTANDDOUBLEWIDTH = new byte[] { 0x1c, 0x21, 0x0c };
36
37 /// <summary>
38 /// 倍宽
39 /// </summary>
40 public static byte[] CMD_DOUBLEWIDTH = new byte[] { 0x1c, 0x21, 0x04 };
41
42 /// <summary>
43 /// 倍高
44 /// </summary>
45 public static byte[] CMD_DOUBLEHEIGHT = new byte[] { 0x1c, 0x21, 0x08 };
46
47 /// <summary>
48 /// 恢复正常
49 /// </summary>
50 public static byte[] CMD_NORMAL = new byte[] { 0x1c, 0x21, 0x00 };
51
52 /// <summary>
53 /// 进纸一行
54 /// </summary>
55 public static byte[] CMD_NEWLINE = new byte[] { 0x0a };
56
57 /// <summary>
58 /// 开钱箱
59 /// </summary>
60 public static byte[] CMD_OPENMONEYBOX = new byte[] { 0x1B, 0x70, 0x30, 0x20, 0xF6 };
61
62 /// <summary>
63 /// 获取打印机状态
64 /// </summary>
65 public static byte[] CMD_STATUS = new byte[] { 0x10, 0x04, 0x01 };
66
67 /// <summary>
68 /// 选择打印颜色红色
69 /// </summary>
70 public static byte[] CMD_COLOR_RED = new byte[] { 0x1B, 0x72, 0x01 };
71
72 /// <summary>
73 /// 选择打印颜色黑色
74 /// </summary>
75 public static byte[] CMD_COLOR_BLACK = new byte[] { 0x1B, 0x72, 0x00 };
76 }
77}
78
三、串口类SerialPortInfo.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.IO.Ports;
5
6namespace BOM.NewUI.PrinterManager
7{
8 public class SerialPortInfo
9 {
10 private string m_printerType;
11 private string m_portType;
12 private string m_portName;
13 private int m_baudRate;
14 private Parity m_parity;
15 private int m_dataBits;
16 private StopBits m_stopBits;
17
18 public SerialPortInfo()
19 {
20 }
21 public SerialPortInfo(string _printerType,string _portType,string _portName, int _baudRate, Parity _parity, int _dataBits, StopBits _stopBits)
22 {
23 this.m_printerType = _printerType;
24 this.m_portType = _portType;
25 this.m_portName = _portName;
26 this.m_baudRate = _baudRate;
27 this.m_parity = _parity;
28 this.m_dataBits = _dataBits;
29 this.m_stopBits = _stopBits;
30 }
31
32 public string printerType
33 {
34 set
35 {
36 this.m_printerType = value;
37 }
38 get
39 {
40 return this.m_printerType;
41 }
42 }
43 public string portType
44 {
45 set
46 {
47 this.m_portType = value;
48 }
49 get
50 {
51 return this.m_portType;
52 }
53 }
54 public string portName
55 {
56 set
57 {
58 this.m_portName = value;
59 }
60 get
61 {
62 return this.m_portName;
63 }
64 }
65
66 public int baudRate
67 {
68 set
69 {
70 this.m_baudRate = value;
71 }
72 get
73 {
74 return this.m_baudRate;
75 }
76 }
77
78 public Parity parity
79 {
80 set
81 {
82 this.m_parity = value;
83 }
84 get
85 {
86 return this.m_parity;
87 }
88 }
89 public int dataBits
90 {
91 set
92 {
93 this.m_dataBits = value;
94 }
95 get
96 {
97 return this.m_dataBits;
98 }
99 }
100 public StopBits stopBits
101 {
102 set
103 {
104 this.m_stopBits = value;
105 }
106 get
107 {
108 return this.m_stopBits;
109 }
110 }
111 }
112}
113
四、配置信息类ConfigManager.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Xml;
5using System.IO.Ports;
6
7namespace BOM.NewUI.PrinterManager
8{
9 public class ConfigManager
10 {
11 public ConfigManager()
12 {
13 }
14 /// <summary>
15 /// 配置文件路径
16 /// </summary>
17 private string fileName = "PrinterManager/printerConfig.xml";
18
19 public SerialPortInfo GetConfig(string printerName)
20 {
21 XmlDataDocument doc = new XmlDataDocument();
22 doc.Load(fileName);
23 XmlNode rootnode = doc.DocumentElement.SelectSingleNode("/SerialPortInfo/printer[@name='" + printerName + "']");
24 SerialPortInfo info = new SerialPortInfo();
25 foreach (XmlNode node in rootnode.ChildNodes)
26 {
27 switch (node.Name.ToLower())
28 {
29 case "printertype":
30 info.printerType = node.InnerText;
31 break;
32 case "porttype":
33 info.portType = node.InnerText;
34 break;
35 case "portname":
36 info.portName = node.InnerText.ToUpper();
37 break;
38 case "baudrate":
39 info.baudRate = int.Parse(node.InnerText);
40 break;
41 case "parity":
42 info.parity = GetParity(node.InnerText);
43 break;
44 case "databits":
45 info.dataBits = int.Parse(node.InnerText);
46 break;
47 case "stopbits":
48 info.stopBits = GetStopBits(node.InnerText);
49 break;
50 }
51 }
52 return info;
53 }
54
55 public void SetConfig(SerialPortInfo info,string printerName)
56 {
57 XmlDataDocument doc = new XmlDataDocument();
58 doc.Load(fileName);
59 XmlNode rootnode = doc.DocumentElement.SelectSingleNode("/SerialPortInfo/printer[@name='" + printerName + "']");
60 foreach (XmlNode node in rootnode.ChildNodes)
61 {
62 switch (node.Name.ToLower())
63 {
64 case "printertype":
65 node.InnerText = info.printerType;
66 break;
67 case "porttype":
68 node.InnerText = info.portType;
69 break;
70 case "portname":
71 node.InnerText = info.portName;
72 break;
73 case "baudrate":
74 node.InnerText = info.baudRate.ToString();
75 break;
76 case "parity":
77 node.InnerText = info.parity.ToString();
78 break;
79 case "databits":
80 node.InnerText = info.dataBits.ToString();
81 break;
82 case "stopbits":
83 node.InnerText = info.stopBits.ToString();
84 break;
85 }
86 }
87 doc.Save(this.fileName);
88 }
89
90 public Parity GetParity(string parity)
91 {
92 Parity p = Parity.None;
93 switch (parity.ToLower())
94 {
95 case "even":
96 p = Parity.Even;
97 break;
98 case "mark":
99 p = Parity.Mark;
100 break;
101 case "none":
102 p = Parity.None;
103 break;
104 case "odd":
105 p = Parity.Odd;
106 break;
107 case "space":
108 p = Parity.Space;
109 break;
110
111 }
112 return p;
113 }
114
115 public StopBits GetStopBits(string stopBits)
116 {
117 StopBits sb = StopBits.One;
118 switch (stopBits.ToLower())
119 {
120 case "none":
121 sb = StopBits.None;
122 break;
123 case "one":
124 sb = StopBits.One;
125 break;
126 case "onepointfive":
127 sb = StopBits.OnePointFive;
128 break;
129 case "two":
130 sb = StopBits.Two;
131 break;
132 }
133 return sb;
134 }
135 }
136}
137
五、利用模板获取变量值 Templete.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Xml;
5using System.IO.Ports;
6using System.Windows.Forms;
7
8namespace BOM.NewUI.PrinterManager
9{
10 /// <summary>
11 /// 票据模板类
12 /// </summary>
13 public class Template
14 {
15 /// <summary>
16 /// 模板路径
17 /// </summary>
18 private string filePath = "PrinterManager/Template.xml";
19 /// <summary>
20 /// 打印
21 /// </summary>
22 /// <param name="sp">SerialPort对象</param>
23 /// <param name="templateID">模板编号</param>
24 public void Print(SerialPort sp,string templateID)
25 {
26 XmlDataDocument doc = new XmlDataDocument();
27 doc.Load(filePath);
28 XmlNode root = doc.DocumentElement.SelectSingleNode(string.Format("/root/template[@id='{0}']", templateID));
29
30 Printer.WriteData(sp, PrinterCommand.CMD_INIT); //初始化打印机
31 foreach (XmlNode node in root.ChildNodes)
32 {
33 switch (node.Name.ToLower())
34 {
35 case "title":
36 PrintTitle(sp, node);
37 break;
38 case "body":
39 PrintBody(sp, node,templateID);
40 break;
41 }
42 }
43 }
44
45 /// <summary>
46 /// 设置对齐方式和字体样式
47 /// </summary>
48 /// <param name="sp">SerialPort</param>
49 /// <param name="justification">对齐方式</param>
50 /// <param name="style">文本样式</param>
51 /// <param name="printText">要打印的文本</param>
52 /// <param name="color">颜色</param>
53 private void SetJustificationAndStyle(SerialPort sp, string justification, string style ,string printText,string color)
54 {
55 switch( justification.ToLower())
56 {
57 case "center":
58 Printer.WriteData(sp,PrinterCommand.CMD_CENTER);
59 break;
60 case "left":
61 Printer.WriteData(sp,PrinterCommand.CMD_LEFT);
62 break;
63 case "right":
64 Printer.WriteData(sp,PrinterCommand.CMD_RIGHT);
65 break;
66 }
67 switch( style.ToLower())
68 {
69 case "0":
70 Printer.WriteData(sp, PrinterCommand.CMD_NORMAL);
71 break;
72 case "1":
73 Printer.WriteData(sp, PrinterCommand.CMD_DOUBLEHEIGHT);
74 break;
75 case "2":
76 Printer.WriteData(sp, PrinterCommand.CMD_DOUBLEWIDTH);
77 break;
78 case "3":
79 Printer.WriteData(sp, PrinterCommand.CMD_DOUBLEHEIGHTANDDOUBLEWIDTH);
80 break;
81 }
82 switch (color.ToLower())
83 {
84 case "0":
85 Printer.WriteData(sp, PrinterCommand.CMD_COLOR_BLACK);
86 break;
87 case "1":
88 Printer.WriteData(sp, PrinterCommand.CMD_COLOR_RED);
89 break;
90
91 }
92 Printer.WriteData(sp,Encoding.Default.GetBytes( printText ));
93 Printer.WriteData(sp, PrinterCommand.CMD_NEWLINE);
94 Printer.WriteData(sp,PrinterCommand.CMD_NORMAL);
95 Printer.WriteData(sp, PrinterCommand.CMD_LEFT);
96 Printer.WriteData(sp, PrinterCommand.CMD_COLOR_BLACK);
97 }
98 /// <summary>
99 /// 根据变量名称取得变量的值
100
101 /// </summary>
102 /// <param name="varName">变量名称</param>
103 /// <returns>变量值</returns>
104 private string GetValue(string varName, string templateID)
105 {
106 string result = string.Empty;
107 switch (templateID.Substring(0, 3).ToUpper())
108 {
109 case "ACC"://一票通
110
206 break;
207 case "OCT"://一卡通
208
258 break;
259 }
260 return result;
261 }
262
263 /// <summary>
264 /// 打印票据标题
265 /// </summary>
266 /// <param name="sp">SerialPort对象</param>
267 /// <param name="node">XmlNode对象</param>
268 private void PrintTitle(SerialPort sp, XmlNode root)
269 {
270 string printText = root.Attributes["text"].Value;
271 string justification = root.Attributes["justification"].Value;
272 string style = root.Attributes["style"].Value;
273 string color = root.Attributes["color"].Value;
274 SetJustificationAndStyle(sp, justification, style, printText,color);
275 }
276
277 /// <summary>
278 /// 打印票据主体
279 /// </summary>
280 /// <param name="sp">SerialPort对象</param>
281 /// <param name="root">XmlNode对象</param>
282 private void PrintBody(SerialPort sp, XmlNode root, string templateID)
283 {
284 foreach (XmlNode node in root.ChildNodes)
285 {
286 string text = node.Attributes["text"].Value;
287 string value = GetValue(node.Attributes["value"].Value,templateID);
288 string style = node.Attributes["style"].Value;
289 string color = node.Attributes["color"].Value;
290
291 StringBuilder sb = new StringBuilder();
292 sb.Append(text);
293 sb.Append("\t");
294 sb.Append(value);
295 //SetJustificationAndStyle(sp, string.Empty, style, sb.ToString(),color);
296 SetJustificationAndStyle(sp, "left", style, sb.ToString(), color);
297 }
298 }
299
300 /// <summary>
301 /// print report title and context
302 /// </summary>
303 /// <param name="sp">SerialPort对象</param>
304 /// <param name="contextstr">上下文</param>
305 public void PrintReport(SerialPort sp, string ReportTitle, string ReportContext)
306 {
307 Printer.WriteData(sp, PrinterCommand.CMD_INIT); //初始化打印机
308 string alinement = "center";
309 string alinement1 = "left";
310 string alinement2 = "right";
311 string sizeoffont = "2";//大小
312 string sizeoffont1 = "0";
313 string coloroffont = "0";//颜色
314 string coloroffont1 = "1";
315 SetJustificationAndStyle(sp, alinement, sizeoffont, ReportTitle, coloroffont1);
316 SetJustificationAndStyle(sp, alinement1, sizeoffont1, ReportContext, coloroffont);
317
318 }
319 }
320}
321
六、打印调用BOMPrinter.cs
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.IO.Ports;
5using System.IO;
6
7namespace BOM.NewUI.PrinterManager
8{
9 public class BOMPrinter
10 {
11 /// <summary>
12 /// 打印
13 /// </summary>
14 /// <param name="PrintTypeCode">ACC01 或 OCT01</param>
15 public static void Printer(string PrintTypeCode)
16 {
17 //ACC01 or OCT01 and so on
18 switch (PrintTypeCode.Substring(0, 3).ToLower())
19 {
20 case "acc":
21 SerialPort sp = BOM.NewUI.PrinterManager.Printer.CreateSerialPort("票据打印机");
22 BOM.NewUI.PrinterManager.Printer.Print(sp, PrintTypeCode);
23 sp.Close();
24 break;
25 case "oct":
26 SerialPort sp1 = BOM.NewUI.PrinterManager.Printer.CreateSerialPort("票据打印机");
27 BOM.NewUI.PrinterManager.Printer.Print(sp1, PrintTypeCode);
28 sp1.Close();
29 break;
30 default:
31 break;
32 }
33 }
34 /// <summary>
35 /// 打印DG
36 /// </summary>
37 /// <param name="ReportTitle"></param>
38 /// <param name="ReportContext"></param>
39 public static void PrintReports(string ReportTitle,string ReportContext)
40 {
41 SerialPort sp = BOM.NewUI.PrinterManager.Printer.CreateSerialPort("票据打印机");
42 Template tt = new Template();
43 tt.PrintReport(sp, ReportTitle, ReportContext);
44 sp.Close();
45 }
46 }
47}
48
七、配置文件PrinterConfig.xml
1<?xml version="1.0" encoding="utf-8" ?>
2<SerialPortInfo>
3 <printer name="发票打印机">
4 <printertype>TM-U220B</printertype>
5 <porttype>串口</porttype>
6 <portname>COM5</portname>
7 <baudrate>9600</baudrate>
8 <parity>None</parity>
9 <databits>8</databits>
10 <stopbits>One</stopbits>
11 </printer>
12 <printer name="票据打印机">
13 <printertype>TM-U220B</printertype>
14 <porttype>串口</porttype>
15 <portname>COM2</portname>
16 <baudrate>9600</baudrate>
17 <parity>None</parity>
18 <databits>8</databits>
19 <stopbits>One</stopbits>
20 </printer>
21</SerialPortInfo>
通过以后的工作后,若以后需要增加一些票据的话,只需在相应在XML文件中添加相应的模板信息再,再在Templete.cs文件中给啬的变量付值 ,就可以实现了。