玩儿条形码之条码打印
条码打印机终于到货了,拿到打印机后才发现原来条码打印机是不需要自己写条码生成程序的,只要把相应的打印机语言指令(例如斑马打印机的EPL2)发送到打印机就行了,白白浪费了那么多时间去研究条码打印的代码,真是郁闷呀。象平时写打印的程序一样,打开一打印对话框,让用户选择打印机,开始打印。咦,结果怎么跟想像中不一样,虽然我发送了EPL2的指令,但是并没有生成条形码出来,打印出来的结果还是EPL2指令呀。看来对于条码打印机,这种方式好象是行不通的,结合打印机文档的实例,只能象在DOS下面那样直接把指令发送到打印机端口才行了(详见上一篇blog)。关于怎么在windows下直接发送打印机指令到打印机,可以参考MSDN文档How to send raw data to a printer by using Visual Basic .NET。
因此,定义一个接口ICommand来取得打印指令:
定义类Label,对条形码标签进封装:
最后,定义标签,把你打印的标签指令送到打印机,标签成功打印(我采用方式是生成临时文件,再把文件发到打印机)
因此,定义一个接口ICommand来取得打印指令:
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace PrinterUtils.Commands
6{
7 public interface ICommand
8 {
9 string GetCommandString();
10 }
11}
定义接口IComplexCommand来进行各种指令的操作:2using System.Collections.Generic;
3using System.Text;
4
5namespace PrinterUtils.Commands
6{
7 public interface ICommand
8 {
9 string GetCommandString();
10 }
11}
1using System;
2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Text;
5
6namespace PrinterUtils.Commands
7{
8 public interface IComplexCommand:ICommand
9 {
10 ReadOnlyCollection<ICommand> Commands{ get; }
11 void AddCommand(ICommand cmd);
12 void RemoveCommand(ICommand cmd);
13 void RemoveCommandAt(int pos);
14 }
15}
定义类PrintTextCommand、BarCodeCommand和Print1bppImageCommand分别对应文本打印、条码打印及图形打印的指令:2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Text;
5
6namespace PrinterUtils.Commands
7{
8 public interface IComplexCommand:ICommand
9 {
10 ReadOnlyCollection<ICommand> Commands{ get; }
11 void AddCommand(ICommand cmd);
12 void RemoveCommand(ICommand cmd);
13 void RemoveCommandAt(int pos);
14 }
15}
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace PrinterUtils.Commands
6{
7 public class BarCodeCommand:BasePositioning, ICommand
8 {
9 private PrintingRotation _rotation;
10 private int _wideBarWidth;
11 private int _codeBarHeight;
12 private string _code;
13 private HumanReadableCode _printHumanCode;
14 private BarCode _barCodeType;
15 private int _narrowBarWidthInDots;
16
17 public BarCodeCommand( int x, int y, PrintingRotation rotation,
18 int narrowBarWidthInDots, int wideBarWidth,
19 int codeBarHeight, HumanReadableCode printHumanCode, BarCode barCodeType, string code)
20 :base(x,y)
21 {
22 _rotation = rotation;
23 _wideBarWidth = wideBarWidth;
24 _codeBarHeight = codeBarHeight;
25 _code = code;
26 _printHumanCode = printHumanCode;
27 _barCodeType = barCodeType;
28 _narrowBarWidthInDots = narrowBarWidthInDots;
29 }
30 //preciso adaptar ao codigo usado por predefinicao
31 public BarCodeCommand( int x, int y, string code )
32 :this(x, y, PrintingRotation.NoRotation, 3, 3, 10, HumanReadableCode.Yes,
33 BarCode.Codabar, code)
34 {}
35
36 public static BarCodeCommand CreateEAN13BarCodeCommand(int x, int y, string code)
37 {
38 return new BarCodeCommand(x, y, PrintingRotation.NoRotation, 2, //narrowBand
39 2, //widebarwidth
40 50,
41 HumanReadableCode.Yes,
42 BarCode.EAN13,
43 code);
44
45 }
46
47 public static BarCodeCommand CreateEAN128BarCodeCommand(int x, int y, string code)
48 {
49 //same as UCC
50 return new BarCodeCommand(x, y, PrintingRotation.NoRotation,
51 2, //narrowBand
52 2, //widebarwidth
53 50,
54 HumanReadableCode.Yes,
55 BarCode.UCCEAN128, code);
56
57 }
58
59 public static BarCodeCommand CreateCode39BarCodeCommand(int x, int y, string code)
60 {
61 return new BarCodeCommand(x, y, PrintingRotation.NoRotation,
62 1,
63 3,
64 50,
65 HumanReadableCode.Yes,
66 BarCode.Code39Std, code);
67 }
68
69 ICommand Members
86 }
87}
88
2using System.Collections.Generic;
3using System.Text;
4
5namespace PrinterUtils.Commands
6{
7 public class BarCodeCommand:BasePositioning, ICommand
8 {
9 private PrintingRotation _rotation;
10 private int _wideBarWidth;
11 private int _codeBarHeight;
12 private string _code;
13 private HumanReadableCode _printHumanCode;
14 private BarCode _barCodeType;
15 private int _narrowBarWidthInDots;
16
17 public BarCodeCommand( int x, int y, PrintingRotation rotation,
18 int narrowBarWidthInDots, int wideBarWidth,
19 int codeBarHeight, HumanReadableCode printHumanCode, BarCode barCodeType, string code)
20 :base(x,y)
21 {
22 _rotation = rotation;
23 _wideBarWidth = wideBarWidth;
24 _codeBarHeight = codeBarHeight;
25 _code = code;
26 _printHumanCode = printHumanCode;
27 _barCodeType = barCodeType;
28 _narrowBarWidthInDots = narrowBarWidthInDots;
29 }
30 //preciso adaptar ao codigo usado por predefinicao
31 public BarCodeCommand( int x, int y, string code )
32 :this(x, y, PrintingRotation.NoRotation, 3, 3, 10, HumanReadableCode.Yes,
33 BarCode.Codabar, code)
34 {}
35
36 public static BarCodeCommand CreateEAN13BarCodeCommand(int x, int y, string code)
37 {
38 return new BarCodeCommand(x, y, PrintingRotation.NoRotation, 2, //narrowBand
39 2, //widebarwidth
40 50,
41 HumanReadableCode.Yes,
42 BarCode.EAN13,
43 code);
44
45 }
46
47 public static BarCodeCommand CreateEAN128BarCodeCommand(int x, int y, string code)
48 {
49 //same as UCC
50 return new BarCodeCommand(x, y, PrintingRotation.NoRotation,
51 2, //narrowBand
52 2, //widebarwidth
53 50,
54 HumanReadableCode.Yes,
55 BarCode.UCCEAN128, code);
56
57 }
58
59 public static BarCodeCommand CreateCode39BarCodeCommand(int x, int y, string code)
60 {
61 return new BarCodeCommand(x, y, PrintingRotation.NoRotation,
62 1,
63 3,
64 50,
65 HumanReadableCode.Yes,
66 BarCode.Code39Std, code);
67 }
68
69 ICommand Members
86 }
87}
88
1using System;
2using System.Collections.Generic;
3using System.Text;
4
5namespace PrinterUtils.Commands
6{
7 public class PrintTextCommand:BasePositioning, ICommand
8 {
9
10 private string _txt;
11 private int _fontSelection;
12 private PrintingRotation _rotation;
13 private PrintingMultiplier _horizontalMultiplier;
14 private PrintingMultiplier _verticalMultiplier;
15 private PrintingReverse _printingReverse;
16
17 public PrintTextCommand( int x, int y, string txt, PrintingRotation rotation, int fontSelection,
18 PrintingMultiplier horizontalMultiplier, PrintingMultiplier verticalMultiplier,
19 PrintingReverse printingReverse)
20 :base(x, y)
21 {
22 _txt = txt;
23 _fontSelection = fontSelection;
24 _rotation = rotation;
25 _horizontalMultiplier = horizontalMultiplier;
26 _verticalMultiplier = verticalMultiplier;
27 _printingReverse = printingReverse;
28 }
29
30 public PrintTextCommand( int x, int y, string txt, int size)
31 :this(x, y, txt, PrintingRotation.NoRotation, size, PrintingMultiplier.One,
32 PrintingMultiplier.One, PrintingReverse.N)
33 {}
34
35 public PrintTextCommand( int x, int y, string txt)
36 :this(x, y, txt, 2)
37 {
38
39 }
40
41 ICommand Members
57 }
58}
59
2using System.Collections.Generic;
3using System.Text;
4
5namespace PrinterUtils.Commands
6{
7 public class PrintTextCommand:BasePositioning, ICommand
8 {
9
10 private string _txt;
11 private int _fontSelection;
12 private PrintingRotation _rotation;
13 private PrintingMultiplier _horizontalMultiplier;
14 private PrintingMultiplier _verticalMultiplier;
15 private PrintingReverse _printingReverse;
16
17 public PrintTextCommand( int x, int y, string txt, PrintingRotation rotation, int fontSelection,
18 PrintingMultiplier horizontalMultiplier, PrintingMultiplier verticalMultiplier,
19 PrintingReverse printingReverse)
20 :base(x, y)
21 {
22 _txt = txt;
23 _fontSelection = fontSelection;
24 _rotation = rotation;
25 _horizontalMultiplier = horizontalMultiplier;
26 _verticalMultiplier = verticalMultiplier;
27 _printingReverse = printingReverse;
28 }
29
30 public PrintTextCommand( int x, int y, string txt, int size)
31 :this(x, y, txt, PrintingRotation.NoRotation, size, PrintingMultiplier.One,
32 PrintingMultiplier.One, PrintingReverse.N)
33 {}
34
35 public PrintTextCommand( int x, int y, string txt)
36 :this(x, y, txt, 2)
37 {
38
39 }
40
41 ICommand Members
57 }
58}
59
定义类Label,对条形码标签进封装:
1using System;
2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Drawing;
5using System.Text;
6
7namespace PrinterUtils.Commands
8{
9 public class Label: IComplexCommand
10 {
11 private Size _size;
12 private int _gapLength;
13 private Point _referencePoint;
14 private int _numberCopies;
15
16 private IList<ICommand> _cmds;
17
18 public Label(int width, int height)
19 :this( new Size(width, height))
20 {
21 }
22
23 public Label( Size size)
24 :this( size, 19, Point.Empty, 1)
25 {
26 }
27
28 public Label( Size size, int gapLength, Point referencePoint, int numberCopies)
29 {
30 _size = size;
31 _gapLength = gapLength;
32 _referencePoint = referencePoint;
33 _cmds = new List<ICommand>();
34 _numberCopies = numberCopies;
35 }
36
37
38 public Size Size
39 {
40 get { return _size; }
41 set { _size = value; }
42 }
43
44 public int GapLength
45 {
46 get { return _gapLength; }
47 set { _gapLength = value; }
48 }
49
50 ICommand Members
73
74 IComplexCommand Members
97 }
98}
99
2using System.Collections.Generic;
3using System.Collections.ObjectModel;
4using System.Drawing;
5using System.Text;
6
7namespace PrinterUtils.Commands
8{
9 public class Label: IComplexCommand
10 {
11 private Size _size;
12 private int _gapLength;
13 private Point _referencePoint;
14 private int _numberCopies;
15
16 private IList<ICommand> _cmds;
17
18 public Label(int width, int height)
19 :this( new Size(width, height))
20 {
21 }
22
23 public Label( Size size)
24 :this( size, 19, Point.Empty, 1)
25 {
26 }
27
28 public Label( Size size, int gapLength, Point referencePoint, int numberCopies)
29 {
30 _size = size;
31 _gapLength = gapLength;
32 _referencePoint = referencePoint;
33 _cmds = new List<ICommand>();
34 _numberCopies = numberCopies;
35 }
36
37
38 public Size Size
39 {
40 get { return _size; }
41 set { _size = value; }
42 }
43
44 public int GapLength
45 {
46 get { return _gapLength; }
47 set { _gapLength = value; }
48 }
49
50 ICommand Members
73
74 IComplexCommand Members
97 }
98}
99
最后,定义标签,把你打印的标签指令送到打印机,标签成功打印(我采用方式是生成临时文件,再把文件发到打印机)
1 private void buttonPrint_Click(object sender, EventArgs e)
2 {
3 if (dataGridView1.Rows.Count < 1)
4 MessageBox.Show("没有条码可以打印!请选择条码后再按此按钮。", "条码打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
5 //if (printDialog1.ShowDialog() == DialogResult.OK)
6 //{
7 using (IZebraPrinter printer = new LPT1Printer(ConfigurationManager.AppSettings["PrinterName"]))
8 {
9 List<ShimaoLabel> labels = GetPrintLabels();
10 printer.PreparePrinter();
11 foreach (ShimaoLabel sLabel in labels)
12 {
13 string printString = ((ICommand)sLabel).GetCommandString();
14 File.WriteAllText(System.Guid.NewGuid().ToString() + ".prn", printString, Encoding.GetEncoding(0));
15 printer.WriteCommandToPrinter(sLabel);
16 }
17 }
18 //}
19 }
2 {
3 if (dataGridView1.Rows.Count < 1)
4 MessageBox.Show("没有条码可以打印!请选择条码后再按此按钮。", "条码打印", MessageBoxButtons.OK, MessageBoxIcon.Warning);
5 //if (printDialog1.ShowDialog() == DialogResult.OK)
6 //{
7 using (IZebraPrinter printer = new LPT1Printer(ConfigurationManager.AppSettings["PrinterName"]))
8 {
9 List<ShimaoLabel> labels = GetPrintLabels();
10 printer.PreparePrinter();
11 foreach (ShimaoLabel sLabel in labels)
12 {
13 string printString = ((ICommand)sLabel).GetCommandString();
14 File.WriteAllText(System.Guid.NewGuid().ToString() + ".prn", printString, Encoding.GetEncoding(0));
15 printer.WriteCommandToPrinter(sLabel);
16 }
17 }
18 //}
19 }