C#调用斑马打印机打印条码标签(支持COM、LPT、USB、TCP连接方式和ZPL、EPL、CPCL指令)

在批量打印商品标签时一般都要加上条码或图片,而这类应用大多是使用斑马打印机,所以我也遇到了怎么打印的问题。

一种办法是用标签设计软件做好模板,在标签设计软件中打印,这种办法不用写代码,但对我来说觉得不能接受,所以尝试代码解决问题。

网上搜索一番,找不到什么资料,基本都是说发送ZPL、EPL指令到打印机,而且还是COM/LPT口连接打印机。后来研究.net的打印类库,发现是用绘图方式打印至打印机的,也叫GDI打印,于是思路有了点突破,那我可以用报表工具画好标签,运行报表时,把结果输出位图,再发送至打印机。

后来又找到一种更好的办法,利用标签设计软件做好模板,打印至本地文件,把其中的ZPL、EPL指令拷贝出来,替换其中动态变化的内容为变量名,做成一个模板文本,在代码中动态替换变量,再把指令输出至打印机。

折腾了几天,终于把这两种思路都实现了,顺便解决了USB接口打印机的ZPL、EPL指令发送问题。

今天有点困,改天再详细讲解一下这两种思路的具体实现。

==============================================================================================================
如何获取标签设计软件输出至打印的ZPL指令?安装好打印机驱动,修改打印机端口,新建一个打印机端口,类型为本地端口,端口名称设置为C:\printer.log,再用标签设计软件打印一次,此文件中就有ZPL指令了。

 ==============================================================================================================

2012-06-02:发布代码ZebraPrintHelper.cs。

==============================================================================================================

2013-01-17:发布代码ZebraPrintHelper.cs,修正BUG,新增TCP打印支持Zebra无线打印QL320+系列打印机。已经生产环境实际应用,支持POS小票、吊牌、洗水唛、条码、文本混合标签打印。因涉及公司源码,只能截图VS解决方案给大家看。

==============================================================================================================

 

 ZebraPrintHelper类代码:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.IO.Ports;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;

namespace Umisky.BarcodePrint.Core {
    /// 
    /// 斑马打印助手,支持LPT/COM/USB/TCP四种模式,适用于标签、票据、条码打印。
    /// 
    public static class ZebraPrintHelper {

        #region 定义私有字段
        /// 
        /// 线程锁,防止多线程调用。
        /// 
        private static object SyncRoot = new object();
        /// 
        /// ZPL压缩字典
        /// 
        private static List compressDictionary = new List();
        #endregion

        #region 定义属性
        public static float TcpLabelMaxHeightCM { get; set; }
        public static int TcpPrinterDPI { get; set; }
        public static string TcpIpAddress { get; set; }
        public static int TcpPort { get; set; }
        public static int Copies { get; set; }
        public static int Port { get; set; }
        public static string PrinterName { get; set; }
        public static bool IsWriteLog { get; set; }
        public static DeviceType PrinterType { get; set; }
        public static ProgrammingLanguage PrinterProgrammingLanguage { get; set; }
        /// 
        /// 日志保存目录,WEB应用注意不能放在BIN目录下。
        /// 
        public static string LogsDirectory { get; set; }
        public static byte[] GraphBuffer { get; set; }
        private static int GraphWidth { get; set; }
        private static int GraphHeight { get; set; }
        private static int RowSize {
            get {
                return (((GraphWidth) + 31) >> 5) << 2;
            }
        }
        private static int RowRealBytesCount {
            get {
                if ((GraphWidth % 8) > 0) {
                    return GraphWidth / 8 + 1;
                }
                else {
                    return GraphWidth / 8;
                }
            }
        }
        #endregion

        #region 静态构造方法
        static ZebraPrintHelper() {
            initCompressCode();
            Port = 1;
            GraphBuffer = new byte[0];
            IsWriteLog = false;
            LogsDirectory = "logs";
            PrinterProgrammingLanguage = ProgrammingLanguage.ZPL;
        }

        private static void initCompressCode() {
            //G H I J K L M N O P Q R S T U V W X Y        对应1,2,3,4……18,19。
            //g h i j k l m n o p q r s t u v w x y z      对应20,40,60,80……340,360,380,400。            
            for (int i = 0; i < 19; i++) {
                compressDictionary.Add(new KeyValue() { Key = Convert.ToChar(71 + i), Value = i + 1 });
            }
            for (int i = 0; i < 20; i++) {
                compressDictionary.Add(new KeyValue() { Key = Convert.ToChar(103 + i), Value = (i + 1) * 20 });
            }
        }
        #endregion

        #region 日志记录方法
        private static void WriteLog(string text, LogType logType) {
            string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
            string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
            if (!Directory.Exists(LogsDirectory)) {
                Directory.CreateDirectory(LogsDirectory);
            }
            if (logType == LogType.Error) {
                File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.UTF8);
            }
            if (logType == LogType.Print) {
                File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.UTF8);
            }
        }

        private static void WriteLog(byte[] bytes, LogType logType) {
            string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
            string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
            if (!Directory.Exists(LogsDirectory)) {
                Directory.CreateDirectory(LogsDirectory);
            }
            if (logType == LogType.Error) {
                File.AppendAllText(path, string.Format("{0}{1}", Encoding.UTF8.GetString(bytes), endTag), Encoding.UTF8);
            }
            if (logType == LogType.Print) {
                File.AppendAllText(path, string.Format("{0}{1}", Encoding.UTF8.GetString(bytes), endTag), Encoding.UTF8);
            }
        }
        #endregion

        #region 封装方法,方便调用。
        public static bool PrintWithCOM(string cmd, int port, bool isWriteLog) {
            PrinterType = DeviceType.COM;
            Port = port;
            IsWriteLog = isWriteLog;
            return PrintCommand(cmd);
        }

        public static bool PrintWithCOM(byte[] bytes, int port, bool isWriteLog) {
            PrinterType = DeviceType.COM;
            Port = port;
            IsWriteLog = isWriteLog;
            return PrintGraphics(bytes);
        }

        public static bool PrintWithLPT(string cmd, int port, bool isWriteLog) {
            PrinterType = DeviceType.LPT;
            Port = port;
            IsWriteLog = isWriteLog;
            return PrintCommand(cmd);
        }

        public static bool PrintWithLPT(byte[] bytes, int port, bool isWriteLog) {
            PrinterType = DeviceType.LPT;
            Port = port;
            IsWriteLog = isWriteLog;
            return PrintGraphics(bytes);
        }

        public static bool PrintWithTCP(string cmd, bool isWriteLog) {
            PrinterType = DeviceType.TCP;
            IsWriteLog = isWriteLog;
            return PrintCommand(cmd);
        }

        public static bool PrintWithTCP(byte[] bytes, bool isWriteLog) {
            PrinterType = DeviceType.TCP;
            IsWriteLog = isWriteLog;
            return PrintGraphics(bytes);
        }

        public static bool PrintWithDRV(string cmd, string printerName, bool isWriteLog) {
            PrinterType = DeviceType.DRV;
            PrinterName = printerName;
            IsWriteLog = isWriteLog;
            return PrintCommand(cmd);
        }

        public static bool PrintWithDRV(byte[] bytes, string printerName, bool isWriteLog) {
            PrinterType = DeviceType.DRV;
            PrinterName = printerName;
            IsWriteLog = isWriteLog;
            return PrintGraphics(bytes);
        }
        #endregion

        #region 打印ZPL、EPL、CPCL、TCP指令
        public static bool PrintCommand(string cmd) {
            lock (SyncRoot) {
                bool result = false;
                try {
                    switch (PrinterType) {
                        case DeviceType.COM:
                            result = comPrint(Encoding.Default.GetBytes(cmd));
                            break;
                        case DeviceType.LPT:
                            result = lptPrint(Encoding.Default.GetBytes(cmd));
                            break;
                        case DeviceType.DRV:
                            result = drvPrint(Encoding.Default.GetBytes(cmd));
                            break;
                        case DeviceType.TCP:
                            result = tcpPrint(Encoding.Default.GetBytes(cmd));
                            break;
                    }
                    if (!string.IsNullOrEmpty(cmd) && IsWriteLog) {
                        WriteLog(cmd, LogType.Print);
                    }
                }
                catch (Exception ex) {
                    //记录日志
                    if (IsWriteLog) {
                        WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
                    }
                    throw new Exception(ex.Message, ex);
                }
                finally {
                    GraphBuffer = new byte[0];
                }
                return result;
            }
        }
        #endregion

        #region 打印图像
        public static bool PrintGraphics(byte[] graph) {
            lock (SyncRoot) {
                bool result = false;
                try {
                    GraphBuffer = graph;
                    byte[] cmdBytes = new byte[0];
                    switch (PrinterProgrammingLanguage) {
                        case ProgrammingLanguage.ZPL:
                            cmdBytes = getZPLBytes();
                            break;
                        case ProgrammingLanguage.EPL:
                            cmdBytes = getEPLBytes();
                            break;
                        case ProgrammingLanguage.CPCL:
                            cmdBytes = getCPCLBytes();
                            break;
                    }
                    switch (PrinterType) {
                        case DeviceType.COM:
                            result = comPrint(cmdBytes);
                            break;
                        case DeviceType.LPT:
                            result = lptPrint(cmdBytes);
                            break;
                        case DeviceType.DRV:
                            result = drvPrint(cmdBytes);
                            break;
                        case DeviceType.TCP:
                            result = tcpPrint(cmdBytes);
                            break;
                    }
                    if (cmdBytes.Length > 0 && IsWriteLog) {
                        WriteLog(cmdBytes, LogType.Print);
                    }
                }
                catch (Exception ex) {
                    //记录日志
                    if (IsWriteLog) {
                        WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
                    }
                    throw new Exception(ex.Message, ex);
                }
                finally {
                    GraphBuffer = new byte[0];
                }
                return result;
            }
        }
        #endregion

        #region 打印指令
        private static bool drvPrint(byte[] cmdBytes) {
            bool result = false;
            try {
                if (!string.IsNullOrEmpty(PrinterName)) {
                    result = WinDrvPort.SendBytesToPrinter(PrinterName, cmdBytes);
                }
            }
            catch (Exception ex) {
                throw new Exception(ex.Message, ex);
            }
            return result;
        }

        private static bool comPrint(byte[] cmdBytes) {
            bool result = false;
            SerialPort com = new SerialPort(string.Format("{0}{1}", PrinterType, Port), 9600, Parity.None, 8, StopBits.One);
            try {
                com.Open();
                com.Write(cmdBytes, 0, cmdBytes.Length);
                result = true;
            }
            catch (Exception ex) {
                throw new Exception(ex.Message, ex);
            }
            finally {
                if (com.IsOpen) {
                    com.Close();
                }
            }
            return result;
        }

        private static bool lptPrint(byte[] cmdBytes) {
            return LptPort.Write(string.Format("{0}{1}", PrinterType, Port), cmdBytes);
        }

        private static bool tcpPrint(byte[] cmdBytes) {
            bool result = false;
            TcpClient tcp = null;
            try {
                tcp = TimeoutSocket.Connect(string.Empty, TcpIpAddress, TcpPort, 1000);
                tcp.SendTimeout = 1000;
                tcp.ReceiveTimeout = 1000;
                if (tcp.Connected) {
                    tcp.Client.Send(cmdBytes);
                    result = true;
                }
            }
            catch (Exception ex) {
                throw new Exception("打印失败,请检查打印机或网络设置。", ex);
            }
            finally {
                if (tcp != null) {
                    if (tcp.Client != null) {
                        tcp.Client.Close();
                        tcp.Client = null;
                    }
                    tcp.Close();
                    tcp = null;
                }
            }
            return result;
        }
        #endregion

        #region 生成ZPL图像打印指令
        private static byte[] getZPLBytes() {
            byte[] bmpData = getBitmapData();
            int bmpDataLength = bmpData.Length;
            for (int i = 0; i < bmpDataLength; i++) {
                bmpData[i] ^= 0xFF;
            }
            string textBitmap = string.Empty, copiesString = string.Empty;
            string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
            textBitmap = CompressLZ77(textHex);
            for (int i = 0; i < Copies; i++) {
                copiesString += "^XA^FO0,0^XGR:IMAGE.GRF,1,1^FS^XZ";
            }
            string text = string.Format("~DGR:IMAGE.GRF,{0},{1},{2}{3}^IDR:IMAGE.GRF",
                GraphHeight * RowRealBytesCount,
                RowRealBytesCount,
                textBitmap,
                copiesString);
            return Encoding.UTF8.GetBytes(text);
        }
        #endregion

        #region 生成EPL图像打印指令
        private static byte[] getEPLBytes() {
            byte[] buffer = getBitmapData();
            string text = string.Format("N\r\nGW{0},{1},{2},{3},{4}\r\nP{5},1\r\n",
                0,
                0,
                RowRealBytesCount,
                GraphHeight,
                Encoding.GetEncoding("iso-8859-1").GetString(buffer),
                Copies);
            return Encoding.GetEncoding("iso-8859-1").GetBytes(text);
        }
        #endregion

        #region 生成CPCL图像打印指令
        public static byte[] getCPCLBytes() {
            //GRAPHICS Commands
            //Bit-mapped graphics can be printed by using graphics commands. ASCII hex (hexadecimal) is
            //used for expanded graphics data (see example). Data size can be reduced to one-half by utilizing the
            //COMPRESSED-GRAPHICS commands with the equivalent binary character(s) of the hex data. When
            //using CG, a single 8 bit character is sent for every 8 bits of graphics data. When using EG two characters
            //(16 bits) are used to transmit 8 bits of graphics data, making EG only half as efficient. Since this data is
            //character data, however, it can be easier to handle and transmit than binary data.
            //Format:
            //{command} {width} {height} {x} {y} {data}
            //where:
            //{command}: Choose from the following:
            //EXPANDED-GRAPHICS (or EG): Prints expanded graphics horizontally.
            //VEXPANDED-GRAPHICS (or VEG): Prints expanded graphics vertically.
            //COMPRESSED-GRAPHICS (or CG): Prints compressed graphics horizontally.
            //VCOMPRESSED-GRAPHICS (or VCG): Prints compressed graphics vertically.
            //{width}: Byte-width of image.
            //{height} Dot-height of image.
            //{x}: Horizontal starting position.
            //{y}: Vertical starting position.
            //{data}: Graphics data.
            //Graphics command example
            //Input:
            //! 0 200 200 210 1
            //EG 2 16 90 45 F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
            //F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F
            //FORM
            //PRINT

            byte[] bmpData = getBitmapData();
            int bmpDataLength = bmpData.Length;
            for (int i = 0; i < bmpDataLength; i++) {
                bmpData[i] ^= 0xFF;
            }
            string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
            string text = string.Format("! {0} {1} {2} {3} {4}\r\nEG {5} {6} {7} {8} {9}\r\nFORM\r\nPRINT\r\n",
                0, //水平偏移量
                TcpPrinterDPI, //横向DPI
                TcpPrinterDPI, //纵向DPI
                (int)(TcpLabelMaxHeightCM / 2.54f * TcpPrinterDPI), //标签最大像素高度=DPI*标签纸高度(英寸)
                Copies, //份数
                RowRealBytesCount, //图像的字节宽度
                GraphHeight, //图像的像素高度
                0, //横向的开始位置
                0, //纵向的开始位置
                textHex
                );
            return Encoding.UTF8.GetBytes(text);
        }
        #endregion

        #region 获取单色位图数据
        /// 
        /// 
        /// 
        /// 
        /// 
        public static Bitmap ConvertToGrayscale(Bitmap pimage) {
            Bitmap source = null;

            // If original bitmap is not already in 32 BPP, ARGB format, then convert
            if (pimage.PixelFormat != PixelFormat.Format32bppArgb) {
                source = new Bitmap(pimage.Width, pimage.Height, PixelFormat.Format32bppArgb);
                source.SetResolution(pimage.HorizontalResolution, pimage.VerticalResolution);
                using (Graphics g = Graphics.FromImage(source)) {
                    g.DrawImageUnscaled(pimage, 0, 0);
                }
            }
            else {
                source = pimage;
            }

            // Lock source bitmap in memory
            BitmapData sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            // Copy image data to binary array
            int imageSize = sourceData.Stride * sourceData.Height;
            byte[] sourceBuffer = new byte[imageSize];
            Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, imageSize);

            // Unlock source bitmap
            source.UnlockBits(sourceData);

            // Create destination bitmap
            Bitmap destination = new Bitmap(source.Width, source.Height, PixelFormat.Format1bppIndexed);

            // Lock destination bitmap in memory
            BitmapData destinationData = destination.LockBits(new Rectangle(0, 0, destination.Width, destination.Height), ImageLockMode.WriteOnly, PixelFormat.Format1bppIndexed);

            // Create destination buffer
            imageSize = destinationData.Stride * destinationData.Height;
            byte[] destinationBuffer = new byte[imageSize];

            int sourceIndex = 0;
            int destinationIndex = 0;
            int pixelTotal = 0;
            byte destinationValue = 0;
            int pixelValue = 128;
            int height = source.Height;
            int width = source.Width;
            int threshold = 500;

            // Iterate lines
            for (int y = 0; y < height; y++) {
                sourceIndex = y * sourceData.Stride;
                destinationIndex = y * destinationData.Stride;
                destinationValue = 0;
                pixelValue = 128;

                // Iterate pixels
                for (int x = 0; x < width; x++) {
                    // Compute pixel brightness (i.e. total of Red, Green, and Blue values)
                    pixelTotal = sourceBuffer[sourceIndex + 1] + sourceBuffer[sourceIndex + 2] + sourceBuffer[sourceIndex + 3];
                    if (pixelTotal > threshold) {
                        destinationValue += (byte)pixelValue;
                    }
                    if (pixelValue == 1) {
                        destinationBuffer[destinationIndex] = destinationValue;
                        destinationIndex++;
                        destinationValue = 0;
                        pixelValue = 128;
                    }
                    else {
                        pixelValue >>= 1;
                    }
                    sourceIndex += 4;
                }
                if (pixelValue != 128) {
                    destinationBuffer[destinationIndex] = destinationValue;
                }
            }

            // Copy binary image data to destination bitmap
            Marshal.Copy(destinationBuffer, 0, destinationData.Scan0, imageSize);

            // Unlock destination bitmap
            destination.UnlockBits(destinationData);

            // Dispose of source if not originally supplied bitmap
            if (source != pimage) {
                source.Dispose();
            }

            // Return
            return destination;
        }
        /// 
        /// 获取单色位图数据(1bpp),不含文件头、信息头、调色板三类数据。
        /// 
        /// 
        private static byte[] getBitmapData() {
            MemoryStream srcStream = new MemoryStream();
            MemoryStream dstStream = new MemoryStream();
            Bitmap srcBmp = null;
            Bitmap dstBmp = null;
            byte[] srcBuffer = null;
            byte[] dstBuffer = null;
            byte[] result = null;
            try {
                srcStream = new MemoryStream(GraphBuffer);
                srcBmp = Bitmap.FromStream(srcStream) as Bitmap;
                srcBuffer = srcStream.ToArray();
                GraphWidth = srcBmp.Width;
                GraphHeight = srcBmp.Height;
                //dstBmp = srcBmp.Clone(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), PixelFormat.Format1bppIndexed);
                dstBmp = ConvertToGrayscale(srcBmp);
                dstBmp.Save(dstStream, ImageFormat.Bmp);
                dstBuffer = dstStream.ToArray();

                int bfOffBits = BitConverter.ToInt32(dstBuffer, 10);
                result = new byte[GraphHeight * RowRealBytesCount];

                //读取时需要反向读取每行字节实现上下翻转的效果,打印机打印顺序需要这样读取。
                for (int i = 0; i < GraphHeight; i++) {
                    Array.Copy(dstBuffer, bfOffBits + (GraphHeight - 1 - i) * RowSize, result, i * RowRealBytesCount, RowRealBytesCount);
                }
            }
            catch (Exception ex) {
                throw new Exception(ex.Message, ex);
            }
            finally {
                if (srcStream != null) {
                    srcStream.Dispose();
                    srcStream = null;
                }
                if (dstStream != null) {
                    dstStream.Dispose();
                    dstStream = null;
                }
                if (srcBmp != null) {
                    srcBmp.Dispose();
                    srcBmp = null;
                }
                if (dstBmp != null) {
                    dstBmp.Dispose();
                    dstBmp = null;
                }
            }
            return result;
        }
        #endregion

        #region LZ77图像字节流压缩方法
        public static string CompressLZ77(string text) {
            //将转成16进制的文本进行压缩
            string result = string.Empty;
            char[] arrChar = text.ToCharArray();
            int count = 1;
            for (int i = 1; i < text.Length; i++) {
                if (arrChar[i - 1] == arrChar[i]) {
                    count++;
                }
                else {
                    result += convertNumber(count) + arrChar[i - 1];
                    count = 1;
                }
                if (i == text.Length - 1) {
                    result += convertNumber(count) + arrChar[i];
                }
            }
            return result;
        }

        public static string DecompressLZ77(string text) {
            string result = string.Empty;
            char[] arrChar = text.ToCharArray();
            int count = 0;
            for (int i = 0; i < arrChar.Length; i++) {
                if (isHexChar(arrChar[i])) {
                    //十六进制值
                    result += new string(arrChar[i], count == 0 ? 1 : count);
                    count = 0;
                }
                else {
                    //压缩码
                    int value = GetCompressValue(arrChar[i]);
                    count += value;
                }
            }
            return result;
        }

        private static int GetCompressValue(char c) {
            int result = 0;
            for (int i = 0; i < compressDictionary.Count; i++) {
                if (c == compressDictionary[i].Key) {
                    result = compressDictionary[i].Value;
                }
            }
            return result;
        }

        private static bool isHexChar(char c) {
            return c > 47 && c < 58 || c > 64 && c < 71 || c > 96 && c < 103;
        }

        private static string convertNumber(int count) {
            //将连续的数字转换成LZ77压缩代码,如000可用I0表示。
            string result = string.Empty;
            if (count > 1) {
                while (count > 0) {
                    for (int i = compressDictionary.Count - 1; i >= 0; i--) {
                        if (count >= compressDictionary[i].Value) {
                            result += compressDictionary[i].Key;
                            count -= compressDictionary[i].Value;
                            break;
                        }
                    }
                }
            }
            return result;
        }
        #endregion
    }
}


 

调用例子代码:

[csharp] view plain copy print ?
  1. private void BackgroundWorkerPrint_DoWork(object sender, DoWorkEventArgs e) {  
  2.     BackgroundWorker worker = sender as BackgroundWorker;  
  3.   
  4.     int i = 0, nextRemainder = 0, count = this._listBarcodeData.Count;  
  5.     bool flag = true;  
  6.     float pageWidth, pageHeight;  
  7.     int dpiX, dpiY, perPaperFactor;  
  8.     string reportPath = string.Format(@"{0}/Reports/{1}", Application.StartupPath, this._modelType);  
  9.     PrintLog printLog = new PrintLog() { Operater = LoginName };  
  10.     PrinterSettings printerSettings = new PrinterSettings() { PrinterName = PrintParam, Copies = 1 };  
  11.   
  12.     using (StreamReader tr = new StreamReader(this.ModelFilePath)) {  
  13.         XElement xe = XDocument.Load(tr).Root.Elements()  
  14.             .Elements(XName.Get("ModelType")).First(x => x.Value == this._modelType).Parent;  
  15.         pageWidth = float.Parse(xe.Elements(XName.Get("PageWidth")).First().Value);  
  16.         pageHeight = float.Parse(xe.Elements(XName.Get("PageHeight")).First().Value);  
  17.         dpiX = int.Parse(xe.Elements(XName.Get("DotPerInchX")).First().Value);  
  18.         dpiY = int.Parse(xe.Elements(XName.Get("DotPerInchY")).First().Value);  
  19.         perPaperFactor = int.Parse(xe.Elements(XName.Get("PerPaperFactor")).First().Value);  
  20.         this._no = int.Parse(xe.Elements(XName.Get("NO")).First().Value);  
  21.     }  
  22.   
  23.     using (LocalReportHelper printHelper = new LocalReportHelper(reportPath)) {  
  24.         printHelper.PrintTypeNO = this._no;  
  25.         printHelper.PrintLogInformation = printLog;  
  26.         printHelper.ExportImageDeviceInfo.DpiX = dpiX;  
  27.         printHelper.ExportImageDeviceInfo.DpiY = dpiY;  
  28.         printHelper.ExportImageDeviceInfo.PageWidth = pageWidth;  
  29.         printHelper.ExportImageDeviceInfo.PageHeight = pageHeight;  
  30.         foreach (BarcodeData bdCurrent in this._listBarcodeData) {  
  31.             if (worker.CancellationPending == true) {  
  32.                 e.Cancel = true;  
  33.                 break;  
  34.             }  
  35.             else {  
  36.                 try {  
  37.                     DataSet dsCurrent = this.GetDataForPrinterByBarcode(bdCurrent.Barcode, bdCurrent.IncreaseType);  
  38.                     DataSet dsNext = null, dsPrevious = dsCurrent.Copy();  
  39.   
  40.                     int amount = this._printType == 0 ? 1 : bdCurrent.Amount - nextRemainder;  
  41.                     int copies = amount / perPaperFactor;  
  42.                     int remainder = nextRemainder = amount % perPaperFactor;  
  43.   
  44.                     Actionintstringint> actPrint = (ds, duplicates, barcodes, amountForLog) => {  
  45.                         printHelper.PrintLogInformation.Barcode = barcodes;  
  46.                         printHelper.PrintLogInformation.Amount = amountForLog;  
  47.                         if (this.PrintType == 0 && DeviceType == DeviceType.DRV) {  
  48.                             printerSettings.Copies = (short)duplicates;  
  49.                             printHelper.WindowsDriverPrint(printerSettings, dpiX, ds);  
  50.                         }  
  51.                         else {  
  52.                             printHelper.OriginalPrint(DeviceType, ds, duplicates, PrintParam);  
  53.                         }  
  54.                     };  
  55.   
  56.                     if (copies > 0) {  
  57.                         int amountForCopy = copies;  
  58.                         if (perPaperFactor > 1) {  
  59.                             DataSet dsCurrentCopy = dsCurrent.CopyForBarcode();  
  60.                             dsCurrent.Merge(dsCurrentCopy);  
  61.                             amountForCopy = copies * perPaperFactor;  
  62.                         }  
  63.   
  64.                         actPrint.Invoke(dsCurrent, copies, bdCurrent.Barcode, amountForCopy);  
  65.                     }  
  66.                     if (remainder > 0) {  
  67.                         int nextIndex = i + 1;  
  68.                         string barcodes = bdCurrent.Barcode;  
  69.                         if (nextIndex < count) {  
  70.                             BarcodeData bdNext = this._listBarcodeData[nextIndex];  
  71.                             dsNext = this.GetDataForPrinterByBarcode(bdNext.Barcode, bdNext.IncreaseType);  
  72.                             dsPrevious.Merge(dsNext);  
  73.                             barcodes += "," + bdNext.Barcode;  
  74.                         }  
  75.                         actPrint.Invoke(dsPrevious, 1, barcodes, 1);  
  76.                     }  
  77.                     worker.ReportProgress(i++, string.Format("正在生成 {0} 并输送往打印机...", bdCurrent.Barcode));  
  78.   
  79.                     if (this._printType == 0) {  
  80.                         count = 1;  
  81.                         flag = true;  
  82.                         break;  
  83.                     }  
  84.                 }  
  85.                 catch (Exception ex) {  
  86.                     flag = false;  
  87.                     e.Result = ex.Message;  
  88.                     break;  
  89.                 }  
  90.             }  
  91.         }  
  92.         if (!e.Cancel && flag) {  
  93.             e.Result = string.Format("打印操作成功完成,共处理条码 {0} 条", count);  
  94.         }  
  95.     }  
  96. }  
        private void BackgroundWorkerPrint_DoWork(object sender, DoWorkEventArgs e) {
            BackgroundWorker worker = sender as BackgroundWorker;

            int i = 0, nextRemainder = 0, count = this._listBarcodeData.Count;
            bool flag = true;
            float pageWidth, pageHeight;
            int dpiX, dpiY, perPaperFactor;
            string reportPath = string.Format(@"{0}/Reports/{1}", Application.StartupPath, this._modelType);
            PrintLog printLog = new PrintLog() { Operater = LoginName };
            PrinterSettings printerSettings = new PrinterSettings() { PrinterName = PrintParam, Copies = 1 };

            using (StreamReader tr = new StreamReader(this.ModelFilePath)) {
                XElement xe = XDocument.Load(tr).Root.Elements()
                    .Elements(XName.Get("ModelType")).First(x => x.Value == this._modelType).Parent;
                pageWidth = float.Parse(xe.Elements(XName.Get("PageWidth")).First().Value);
                pageHeight = float.Parse(xe.Elements(XName.Get("PageHeight")).First().Value);
                dpiX = int.Parse(xe.Elements(XName.Get("DotPerInchX")).First().Value);
                dpiY = int.Parse(xe.Elements(XName.Get("DotPerInchY")).First().Value);
                perPaperFactor = int.Parse(xe.Elements(XName.Get("PerPaperFactor")).First().Value);
                this._no = int.Parse(xe.Elements(XName.Get("NO")).First().Value);
            }

            using (LocalReportHelper printHelper = new LocalReportHelper(reportPath)) {
                printHelper.PrintTypeNO = this._no;
                printHelper.PrintLogInformation = printLog;
                printHelper.ExportImageDeviceInfo.DpiX = dpiX;
                printHelper.ExportImageDeviceInfo.DpiY = dpiY;
                printHelper.ExportImageDeviceInfo.PageWidth = pageWidth;
                printHelper.ExportImageDeviceInfo.PageHeight = pageHeight;
                foreach (BarcodeData bdCurrent in this._listBarcodeData) {
                    if (worker.CancellationPending == true) {
                        e.Cancel = true;
                        break;
                    }
                    else {
                        try {
                            DataSet dsCurrent = this.GetDataForPrinterByBarcode(bdCurrent.Barcode, bdCurrent.IncreaseType);
                            DataSet dsNext = null, dsPrevious = dsCurrent.Copy();

                            int amount = this._printType == 0 ? 1 : bdCurrent.Amount - nextRemainder;
                            int copies = amount / perPaperFactor;
                            int remainder = nextRemainder = amount % perPaperFactor;

                            Action actPrint = (ds, duplicates, barcodes, amountForLog) => {
                                printHelper.PrintLogInformation.Barcode = barcodes;
                                printHelper.PrintLogInformation.Amount = amountForLog;
                                if (this.PrintType == 0 && DeviceType == DeviceType.DRV) {
                                    printerSettings.Copies = (short)duplicates;
                                    printHelper.WindowsDriverPrint(printerSettings, dpiX, ds);
                                }
                                else {
                                    printHelper.OriginalPrint(DeviceType, ds, duplicates, PrintParam);
                                }
                            };

                            if (copies > 0) {
                                int amountForCopy = copies;
                                if (perPaperFactor > 1) {
                                    DataSet dsCurrentCopy = dsCurrent.CopyForBarcode();
                                    dsCurrent.Merge(dsCurrentCopy);
                                    amountForCopy = copies * perPaperFactor;
                                }

                                actPrint.Invoke(dsCurrent, copies, bdCurrent.Barcode, amountForCopy);
                            }
                            if (remainder > 0) {
                                int nextIndex = i + 1;
                                string barcodes = bdCurrent.Barcode;
                                if (nextIndex < count) {
                                    BarcodeData bdNext = this._listBarcodeData[nextIndex];
                                    dsNext = this.GetDataForPrinterByBarcode(bdNext.Barcode, bdNext.IncreaseType);
                                    dsPrevious.Merge(dsNext);
                                    barcodes += "," + bdNext.Barcode;
                                }
                                actPrint.Invoke(dsPrevious, 1, barcodes, 1);
                            }
                            worker.ReportProgress(i++, string.Format("正在生成 {0} 并输送往打印机...", bdCurrent.Barcode));

                            if (this._printType == 0) {
                                count = 1;
                                flag = true;
                                break;
                            }
                        }
                        catch (Exception ex) {
                            flag = false;
                            e.Result = ex.Message;
                            break;
                        }
                    }
                }
                if (!e.Cancel && flag) {
                    e.Result = string.Format("打印操作成功完成,共处理条码 {0} 条", count);
                }
            }
        }

 

LocalReportHelper类代码:

[csharp] view plain copy print ?
  1. using System;  
  2. using System.Configuration;  
  3. using System.Data;  
  4. using System.Drawing;  
  5. using System.Drawing.Imaging;  
  6. using System.Drawing.Printing;  
  7. using System.IO;  
  8. using System.Text;  
  9. using System.Windows.Forms;  
  10. using Microsoft.Reporting.WinForms;  
  11. using Umisky.BarcodePrint.Core;  
  12.   
  13. namespace Umisky.BarcodePrint.Codes {  
  14.     public class LocalReportHelper : IDisposable { 
  15.  
  16.         #region Properties   
  17.   
  18.         public String LocalReportPath { getset; }  
  19.         public LocalReport LocalReportInstance { getprivate set; }  
  20.         public GraphDeviceInfo ExportImageDeviceInfo { getset; }  
  21.         public PrintLog PrintLogInformation { getset; }  
  22.         public int PrintTypeNO { getset; } 
  23.  
  24.         #endregion   
  25.   
  26.         private Stream _stream;  
  27.         private int _bmpDPI;  
  28.         private DataSet _ds;  
  29.   
  30.         public LocalReportHelper(String reportPath)  
  31.             : this(reportPath, new GraphDeviceInfo() {  
  32.                 ColorDepth = 1,  
  33.                 DpiX = 203,  
  34.                 DpiY = 203,  
  35.                 PageWidth = 8f,  
  36.                 PageHeight = 12.2f,  
  37.                 MarginTop = 0.2f  
  38.             }) { }  
  39.   
  40.         public LocalReportHelper(String reportPath, GraphDeviceInfo deviceInfo) {  
  41.             this._bmpDPI = 96;  
  42.   
  43.             this.LocalReportPath = reportPath;  
  44.             this.ExportImageDeviceInfo = deviceInfo;  
  45.             this.LocalReportInstance = new LocalReport() { ReportPath = reportPath };  
  46.             this.LocalReportInstance.SubreportProcessing += new SubreportProcessingEventHandler(LocalReportInstance_SubreportProcessing);  
  47.         }  
  48.   
  49.         private void LocalReportInstance_SubreportProcessing(object sender, SubreportProcessingEventArgs e) {  
  50.             foreach (DataTable dt in this._ds.Tables) {  
  51.                 e.DataSources.Add(new ReportDataSource(dt.TableName, dt));  
  52.             }  
  53.         }  
  54.   
  55.         public void Dispose() {  
  56.             this.ExportImageDeviceInfo = null;  
  57.             this.LocalReportInstance = null;  
  58.             this.LocalReportPath = null;  
  59.   
  60.             this._ds = null;  
  61.         }  
  62.   
  63.         public void AddReportParameter(string paramName, string value) {  
  64.             this.LocalReportInstance.SetParameters(new ReportParameter(paramName, value));  
  65.         }  
  66.  
  67.         #region Export hang title image by reporting services  
  68.   
  69.         private void AddWashIcones() {  
  70.             this.LocalReportInstance.EnableExternalImages = true;  
  71.             this.LocalReportInstance.SetParameters(new ReportParameter("AppPath", Application.StartupPath));  
  72.         }  
  73.   
  74.         private void AddBarcodesAssembly() {  
  75.             this.LocalReportInstance.AddTrustedCodeModuleInCurrentAppDomain(ConfigurationManager.AppSettings["BarcodesAssembly"]);  
  76.         }  
  77.   
  78.         private Stream CreateStreamCallBack(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) {  
  79.             string tempFolderPath = string.Concat(Environment.GetEnvironmentVariable("TEMP"), "/");  
  80.             this._stream = new FileStream(string.Concat(tempFolderPath, name, ".", fileNameExtension), FileMode.Create);  
  81.             return this._stream;  
  82.         }  
  83.         private void Export() {  
  84.             if (string.IsNullOrEmpty(this.LocalReportPath) ||  
  85.                 this.LocalReportInstance == null ||  
  86.                 this.ExportImageDeviceInfo == null) {  
  87.                 throw new InvalidExpressionException("Invalid parameters");  
  88.             }  
  89.             if (this.PrintTypeNO >= -1 || this.PrintTypeNO == -3) {  
  90.                 this.AddBarcodesAssembly();  
  91.                 if (this.PrintTypeNO >= 0) {  
  92.                     this.AddWashIcones();  
  93.                 }  
  94.             }  
  95.             if (this.PrintTypeNO >= 0) {  
  96.                 this.LocalReportInstance.DataSources.Clear();  
  97.                 foreach (DataTable dt in this._ds.Tables) {  
  98.                     this.LocalReportInstance.DataSources.Add(new ReportDataSource(dt.TableName, dt));  
  99.                 }  
  100.             }  
  101.             this.LocalReportInstance.Refresh();  
  102.   
  103.             if (this._stream != null) {  
  104.                 this._stream.Close();  
  105.                 this._stream = null;  
  106.             }  
  107.             Warning[] warnings;  
  108.             this.LocalReportInstance.Render(  
  109.                 "Image",  
  110.                 this.ExportImageDeviceInfo.ToString(),  
  111.                 PageCountMode.Actual,  
  112.                 CreateStreamCallBack,  
  113.                 out warnings);  
  114.             this._stream.Position = 0;  
  115.         }  
  116.         private void SaveLog() {  
  117.             using (Bitmap image = (Bitmap)Image.FromStream(this._stream)) {  
  118.                 image.SetResolution(96, 96);  
  119.                 using (MemoryStream ms = new MemoryStream()) {  
  120.                     image.Save(ms, ImageFormat.Jpeg);  
  121.                     this.PrintLogInformation.BarcodeImage = ms.ToArray();  
  122.                 }  
  123.             }  
  124.             LogHelper.AddLog(this.PrintLogInformation);  
  125.             if (this._stream != null) {  
  126.                 this._stream.Close();  
  127.                 this._stream = null;  
  128.             }  
  129.         }  
  130.  
  131.         #endregion  
  132.  
  133.         #region Windows driver print  
  134.   
  135.         private void PrintPage(object sender, PrintPageEventArgs ev) {  
  136.             Bitmap bmp = (Bitmap)Image.FromStream(this._stream);  
  137.             bmp.SetResolution(this._bmpDPI, this._bmpDPI);  
  138.             ev.Graphics.DrawImage(bmp, 0, 0);  
  139.             ev.HasMorePages = false;  
  140.         }  
  141.         ///    
  142.         /// Print by windows driver   
  143.         ///    
  144.         /// .net framework PrinterSettings class, including some printer information  
  145.         /// the bitmap image resoluation, dots per inch  
  146.         public void WindowsDriverPrint(PrinterSettings printerSettings, int bmpDPI, DataSet ds) {  
  147.             this._ds = ds;  
  148.             this.Export();  
  149.             if (this._stream == null) {  
  150.                 return;  
  151.             }  
  152.             this._bmpDPI = bmpDPI;  
  153.   
  154.             PrintDocument printDoc = new PrintDocument();  
  155.             printDoc.DocumentName = "条码打印";  
  156.             printDoc.PrinterSettings = printerSettings;  
  157.             printDoc.PrintController = new StandardPrintController();  
  158.             if (!printDoc.PrinterSettings.IsValid) {  
  159.                 if (this._stream != null) {  
  160.                     this._stream.Close();  
  161.                     this._stream = null;  
  162.                 }  
  163.                 MessageBox.Show("Printer found errors, Please contact your administrators!""Print Error");  
  164.                 return;  
  165.             }  
  166.             printDoc.PrintPage += new PrintPageEventHandler(PrintPage);  
  167.             printDoc.Print();  
  168.             this.SaveLog();  
  169.         }  
  170.  
  171.         #endregion  
  172.  
  173.         #region Original print   
  174.   
  175.         ///    
  176.         /// Send the file to the printer or use the printer command  
  177.         ///    
  178.         /// The port(LPT,COM,DRV) which the device connecting  
  179.         /// Total number for print  
  180.         /// The report datasource  
  181.         /// Print parameters  
  182.         /// The built-in printer programming language, you can choose EPL or ZPL  
  183.         public void OriginalPrint(DeviceType deviceType,  
  184.             DataSet ds,  
  185.             int copies = 1,  
  186.             string printParam = null,  
  187.             ProgrammingLanguage printLanguage = ProgrammingLanguage.ZPL) {  
  188.             this._ds = ds;  
  189.             this.Export();  
  190.             if (this._stream == null) {  
  191.                 return;  
  192.             }  
  193.             int port = 1;  
  194.             int.TryParse(printParam, out port);  
  195.             int length = (int)this._stream.Length;  
  196.             byte[] bytes = new byte[length];  
  197.             this._stream.Read(bytes, 0, length);  
  198.             ZebraPrintHelper.Copies = copies;  
  199.             ZebraPrintHelper.PrinterType = deviceType;  
  200.             ZebraPrintHelper.PrinterName = printParam;  
  201.             ZebraPrintHelper.Port = port;  
  202.             ZebraPrintHelper.PrinterProgrammingLanguage = printLanguage;  
  203.             ZebraPrintHelper.PrintGraphics(bytes);  
  204.             this.SaveLog();  
  205.         }  
  206.  
  207.         #endregion   
  208.   
  209.     }  
  210. }  
using System;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Microsoft.Reporting.WinForms;
using Umisky.BarcodePrint.Core;

namespace Umisky.BarcodePrint.Codes {
    public class LocalReportHelper : IDisposable {

        #region Properties

        public String LocalReportPath { get; set; }
        public LocalReport LocalReportInstance { get; private set; }
        public GraphDeviceInfo ExportImageDeviceInfo { get; set; }
        public PrintLog PrintLogInformation { get; set; }
        public int PrintTypeNO { get; set; }

        #endregion

        private Stream _stream;
        private int _bmpDPI;
        private DataSet _ds;

        public LocalReportHelper(String reportPath)
            : this(reportPath, new GraphDeviceInfo() {
                ColorDepth = 1,
                DpiX = 203,
                DpiY = 203,
                PageWidth = 8f,
                PageHeight = 12.2f,
                MarginTop = 0.2f
            }) { }

        public LocalReportHelper(String reportPath, GraphDeviceInfo deviceInfo) {
            this._bmpDPI = 96;

            this.LocalReportPath = reportPath;
            this.ExportImageDeviceInfo = deviceInfo;
            this.LocalReportInstance = new LocalReport() { ReportPath = reportPath };
            this.LocalReportInstance.SubreportProcessing += new SubreportProcessingEventHandler(LocalReportInstance_SubreportProcessing);
        }

        private void LocalReportInstance_SubreportProcessing(object sender, SubreportProcessingEventArgs e) {
            foreach (DataTable dt in this._ds.Tables) {
                e.DataSources.Add(new ReportDataSource(dt.TableName, dt));
            }
        }

        public void Dispose() {
            this.ExportImageDeviceInfo = null;
            this.LocalReportInstance = null;
            this.LocalReportPath = null;

            this._ds = null;
        }

        public void AddReportParameter(string paramName, string value) {
            this.LocalReportInstance.SetParameters(new ReportParameter(paramName, value));
        }

        #region Export hang title image by reporting services

        private void AddWashIcones() {
            this.LocalReportInstance.EnableExternalImages = true;
            this.LocalReportInstance.SetParameters(new ReportParameter("AppPath", Application.StartupPath));
        }

        private void AddBarcodesAssembly() {
            this.LocalReportInstance.AddTrustedCodeModuleInCurrentAppDomain(ConfigurationManager.AppSettings["BarcodesAssembly"]);
        }

        private Stream CreateStreamCallBack(string name, string fileNameExtension, Encoding encoding, string mimeType, bool willSeek) {
            string tempFolderPath = string.Concat(Environment.GetEnvironmentVariable("TEMP"), "/");
            this._stream = new FileStream(string.Concat(tempFolderPath, name, ".", fileNameExtension), FileMode.Create);
            return this._stream;
        }
        private void Export() {
            if (string.IsNullOrEmpty(this.LocalReportPath) ||
                this.LocalReportInstance == null ||
                this.ExportImageDeviceInfo == null) {
                throw new InvalidExpressionException("Invalid parameters");
            }
            if (this.PrintTypeNO >= -1 || this.PrintTypeNO == -3) {
                this.AddBarcodesAssembly();
                if (this.PrintTypeNO >= 0) {
                    this.AddWashIcones();
                }
            }
            if (this.PrintTypeNO >= 0) {
                this.LocalReportInstance.DataSources.Clear();
                foreach (DataTable dt in this._ds.Tables) {
                    this.LocalReportInstance.DataSources.Add(new ReportDataSource(dt.TableName, dt));
                }
            }
            this.LocalReportInstance.Refresh();

            if (this._stream != null) {
                this._stream.Close();
                this._stream = null;
            }
            Warning[] warnings;
            this.LocalReportInstance.Render(
                "Image",
                this.ExportImageDeviceInfo.ToString(),
                PageCountMode.Actual,
                CreateStreamCallBack,
                out warnings);
            this._stream.Position = 0;
        }
        private void SaveLog() {
            using (Bitmap image = (Bitmap)Image.FromStream(this._stream)) {
                image.SetResolution(96, 96);
                using (MemoryStream ms = new MemoryStream()) {
                    image.Save(ms, ImageFormat.Jpeg);
                    this.PrintLogInformation.BarcodeImage = ms.ToArray();
                }
            }
            LogHelper.AddLog(this.PrintLogInformation);
            if (this._stream != null) {
                this._stream.Close();
                this._stream = null;
            }
        }

        #endregion

        #region Windows driver print

        private void PrintPage(object sender, PrintPageEventArgs ev) {
            Bitmap bmp = (Bitmap)Image.FromStream(this._stream);
            bmp.SetResolution(this._bmpDPI, this._bmpDPI);
            ev.Graphics.DrawImage(bmp, 0, 0);
            ev.HasMorePages = false;
        }
        /// 
        /// Print by windows driver
        /// 
        /// .net framework PrinterSettings class, including some printer information
        /// the bitmap image resoluation, dots per inch
        public void WindowsDriverPrint(PrinterSettings printerSettings, int bmpDPI, DataSet ds) {
            this._ds = ds;
            this.Export();
            if (this._stream == null) {
                return;
            }
            this._bmpDPI = bmpDPI;

            PrintDocument printDoc = new PrintDocument();
            printDoc.DocumentName = "条码打印";
            printDoc.PrinterSettings = printerSettings;
            printDoc.PrintController = new StandardPrintController();
            if (!printDoc.PrinterSettings.IsValid) {
                if (this._stream != null) {
                    this._stream.Close();
                    this._stream = null;
                }
                MessageBox.Show("Printer found errors, Please contact your administrators!", "Print Error");
                return;
            }
            printDoc.PrintPage += new PrintPageEventHandler(PrintPage);
            printDoc.Print();
            this.SaveLog();
        }

        #endregion

        #region Original print

        /// 
        /// Send the file to the printer or use the printer command
        /// 
        /// The port(LPT,COM,DRV) which the device connecting
        /// Total number for print
        /// The report datasource
        /// Print parameters
        /// The built-in printer programming language, you can choose EPL or ZPL
        public void OriginalPrint(DeviceType deviceType,
            DataSet ds,
            int copies = 1,
            string printParam = null,
            ProgrammingLanguage printLanguage = ProgrammingLanguage.ZPL) {
            this._ds = ds;
            this.Export();
            if (this._stream == null) {
                return;
            }
            int port = 1;
            int.TryParse(printParam, out port);
            int length = (int)this._stream.Length;
            byte[] bytes = new byte[length];
            this._stream.Read(bytes, 0, length);
            ZebraPrintHelper.Copies = copies;
            ZebraPrintHelper.PrinterType = deviceType;
            ZebraPrintHelper.PrinterName = printParam;
            ZebraPrintHelper.Port = port;
            ZebraPrintHelper.PrinterProgrammingLanguage = printLanguage;
            ZebraPrintHelper.PrintGraphics(bytes);
            this.SaveLog();
        }

        #endregion

    }
}



 


 

 

转自:http://blog.csdn.net/ldljlq/article/details/7338772#

你可能感兴趣的:(2008,VS,水晶报表,C#,.net,C#,标签,打印,条码)