C# EPL USB 指令打印

 1 private void btnPrinter_Click(object sender, EventArgs e)
 2         {
 3 
 4            #region ESC 热敏图像点阵像素点读取打印
 5 
 6             //Bitmap bitmap = new Bitmap(@"D:\450X100.bmp");
 7             //NetPOSPrinter netPOSPrinter = new NetPOSPrinter();
 8             //netPOSPrinter.PrintPic(bitmap);
 9 
10             #endregion
11 
12             #region EPL USB 打印
13             //Bitmap img = new Bitmap(@"D:\450X100.bmp");
14             //ZebraPrintHelper.PrinterType = DeviceType.DRV;
15             //ZebraPrintHelper.PrinterProgrammingLanguage = ProgrammingLanguage.EPL;
16             //ZebraPrintHelper.PrinterName = "ZDesigner GK888t (EPL)";
17             //byte[] imgByte = ImageToByte.ImgToByt(img);
18             //ZebraPrintHelper.PrintGraphics(imgByte);
19 
20             #endregion
21 
22             #region ZPL II 打印指令
23             //^XA^CFD
24             //^POI
25             //^LH330,10
26             //^FO50,50
27             //^FDSMARTDIGITAL^FS
28             //^FO50,75
29             //^FD021-51871630^FS
30             //^XZ
31 
32             //StringBuilder sb = new StringBuilder();
33             //sb.Append("^XA^CFD");
34             //sb.Append("^POI");
35             //sb.Append("^LH330,10");
36             //sb.Append("^FO50,50");
37             //sb.Append("^FDSMARTDIGITAL^FS");
38             //sb.Append("^FO50,75");
39             //sb.Append("^FD021-51871630^FS");
40             //sb.Append("^XZ");
41 
42             //byte[] cmd = Encoding.Default.GetBytes(sb.ToString());
43 
44             #endregion
45 
46             #region EPL USB 指令打印
47             ZebraPrintHelper.PrinterProgrammingLanguage = ProgrammingLanguage.EPL;
48             ZebraPrintHelper.PrinterName = "ZDesigner GK888t (EPL)";
49             ZebraPrintHelper.PrinterType = DeviceType.DRV;
50             
51             string cmd = "N" + "\r\n" +
52                 "Q400,025" + "\n\r" +
53                 "A140,45,0,8,1,1,N,\"古典黄芥沫调味酱\"" + "\r\n" +
54                 "A140,90,0,8,1,1,N,\"规格:\"" + "\r\n" +
55                 "A240,95,0,4,1,1,N,\"" + "100ML/瓶" + "\"" + "\r\n" +
56                 "A140,135,0,8,1,1,N,\"生产日期:\"" + "\r\n" +
57                 "A300,140,0,4,1,1,N,\"" + "2015-10-02" + "\"" + "\r\n" +
58                 "B140,180,0,1,3,2,100,B,\"" + "8957891234567895789588535" + "\"" + "\r\n" +
59                 "P1" + "\r\n";
60 
61             ZebraPrintHelper.PrintCommand(cmd.ToString());
62             #endregion
63         }
   1 using Microsoft.Win32.SafeHandles;
   2 using System;
   3 using System.Collections.Generic;
   4 using System.Drawing;
   5 using System.Drawing.Imaging;
   6 using System.IO;
   7 using System.IO.Ports;
   8 using System.Net;
   9 using System.Net.Sockets;
  10 using System.Runtime.InteropServices;
  11 using System.Text;
  12 
  13 namespace ZebraLibrary
  14 {
  15     /// <summary>
  16     /// 斑马打印助手,支持LPT/COM/USB/TCP四种模式,适用于标签、票据、条码打印。
  17     /// </summary>
  18     public static class ZebraPrintHelper
  19     {
  20         #region 定义API方法
  21 
  22         #region 写打印口(LPT)方法
  23         private const short FILE_ATTRIBUTE_NORMAL = 0x80;
  24         private const short INVALID_HANDLE_VALUE = -1;
  25         private const uint GENERIC_READ = 0x80000000;
  26         private const uint GENERIC_WRITE = 0x40000000;
  27         private const uint CREATE_NEW = 1;
  28         private const uint CREATE_ALWAYS = 2;
  29         private const uint OPEN_EXISTING = 3;
  30         [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  31         private static extern SafeFileHandle CreateFile(string strFileName,
  32             uint dwDesiredAccess,
  33             uint dwShareMode,
  34             IntPtr intptrSecurityAttributes,
  35             uint dwCreationDisposition,
  36             uint dwFlagsAndAttributes,
  37             IntPtr intptrTemplateFile);
  38         #endregion
  39 
  40         [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  41         public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string printerName, out IntPtr intptrPrinter, IntPtr intptrPrintDocument);
  42 
  43         [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  44         public static extern bool ClosePrinter(IntPtr intptrPrinter);
  45 
  46         [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  47         public static extern bool StartDocPrinter(IntPtr intptrPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DocInfo docInfo);
  48 
  49         [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  50         public static extern bool EndDocPrinter(IntPtr intptrPrinter);
  51 
  52         [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  53         public static extern bool StartPagePrinter(IntPtr intptrPrinter);
  54 
  55         [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  56         public static extern bool EndPagePrinter(IntPtr intptrPrinter);
  57 
  58         [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  59         public static extern bool WritePrinter(IntPtr intptrPrinter, IntPtr intptrBytes, Int32 count, out Int32 written);
  60         #endregion  
  61  
  62         #region 定义私有字段
  63 
  64         /// <summary>  
  65         /// 线程锁,防止多线程调用。  
  66         /// </summary>  
  67         private static object SyncRoot = new object();
  68 
  69         /// <summary>  
  70         /// 字节流传递时采用的字符编码  
  71         /// </summary>  
  72         private static readonly Encoding TransferFormat = Encoding.GetEncoding("iso-8859-1");
  73 
  74         #endregion
  75 
  76         #region 定义属性
  77         public static int Port { get; set; }
  78         public static string PrinterName { get; set; }
  79         public static bool IsWriteLog { get; set; }
  80         public static DeviceType PrinterType { get; set; }
  81         public static ProgrammingLanguage PrinterProgrammingLanguage { get; set; }
  82 
  83         public static float TcpLabelMaxHeightCM { get; set; }
  84         public static int TcpPrinterDPI { get; set; }
  85         public static string TcpIpAddress { get; set; }
  86         public static int TcpPort { get; set; }
  87         public static int Copies { get; set; }  
  88 
  89         /// <summary>  
  90         /// 日志保存目录,WEB应用注意不能放在BIN目录下。  
  91         /// </summary>  
  92         public static string LogsDirectory { get; set; }
  93 
  94         private static byte[] GraphBuffer { get; set; }
  95         private static int GraphWidth { get; set; }
  96         private static int GraphHeight { get; set; }
  97 
  98         private static int RowSize
  99         {
 100             get
 101             {
 102                 return (((GraphWidth) + 31) >> 5) << 2;
 103             }
 104         }
 105 
 106         private static int RowRealBytesCount
 107         {
 108             get
 109             {
 110                 if ((GraphWidth % 8) > 0)
 111                 {
 112                     return GraphWidth / 8 + 1;
 113                 }
 114                 else
 115                 {
 116                     return GraphWidth / 8;
 117                 }
 118             }
 119         }
 120         #endregion  
 121 
 122         #region 静态构造方法
 123         static ZebraPrintHelper()
 124         {
 125             GraphBuffer = new byte[0];
 126             IsWriteLog = false;
 127             LogsDirectory = "logs";
 128         }
 129         #endregion
 130 
 131         #region 定义发送原始数据到打印机的方法
 132         private static bool SendBytesToPrinter(string printerName, IntPtr intptrBytes, Int32 count)
 133         {
 134             Int32 error = 0, written = 0;
 135             IntPtr intptrPrinter = new IntPtr(0);
 136             DocInfo docInfo = new DocInfo();
 137             bool bSuccess = false;
 138 
 139             docInfo.DocName = ".NET RAW Document";
 140             docInfo.DataType = "RAW";
 141 
 142             // Open the printer.  
 143             if (OpenPrinter(printerName.Normalize(), out intptrPrinter, IntPtr.Zero))
 144             {
 145                 // Start a document.  
 146                 if (StartDocPrinter(intptrPrinter, 1, docInfo))
 147                 {
 148                     // Start a page.  
 149                     if (StartPagePrinter(intptrPrinter))
 150                     {
 151                         // Write your bytes.  
 152                         bSuccess = WritePrinter(intptrPrinter, intptrBytes, count, out written);
 153                         EndPagePrinter(intptrPrinter);
 154                     }
 155                     EndDocPrinter(intptrPrinter);
 156                 }
 157                 ClosePrinter(intptrPrinter);
 158             }
 159             // If you did not succeed, GetLastError may give more information  
 160             // about why not.  
 161             if (bSuccess == false)
 162             {
 163                 error = Marshal.GetLastWin32Error();
 164             }
 165             return bSuccess;
 166         }
 167 
 168         public static bool SendFileToPrinter(string printerName, string fileName)
 169         {
 170             // Open the file.  
 171             FileStream fs = new FileStream(fileName, FileMode.Open);
 172             // Create a BinaryReader on the file.  
 173             BinaryReader br = new BinaryReader(fs);
 174             // Dim an array of bytes big enough to hold the file's contents.  
 175             Byte[] bytes = new Byte[fs.Length];
 176             bool bSuccess = false;
 177             // Your unmanaged pointer.  
 178             IntPtr pUnmanagedBytes = new IntPtr(0);
 179             int nLength;
 180 
 181             nLength = Convert.ToInt32(fs.Length);
 182             // Read the contents of the file into the array.  
 183             bytes = br.ReadBytes(nLength);
 184             // Allocate some unmanaged memory for those bytes.  
 185             pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
 186             // Copy the managed byte array into the unmanaged array.  
 187             Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
 188             // Send the unmanaged bytes to the printer.  
 189             bSuccess = SendBytesToPrinter(printerName, pUnmanagedBytes, nLength);
 190             // Free the unmanaged memory that you allocated earlier.  
 191             Marshal.FreeCoTaskMem(pUnmanagedBytes);
 192             return bSuccess;
 193         }
 194 
 195         public static bool SendBytesToPrinter(string printerName, byte[] bytes)
 196         {
 197             bool bSuccess = false;
 198             IntPtr pUnmanagedBytes = new IntPtr(0);
 199             int nLength = bytes.Length;
 200             // Allocate some unmanaged memory for those bytes.  
 201             pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
 202             // Copy the managed byte array into the unmanaged array.  
 203             Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
 204             // Send the unmanaged bytes to the printer.  
 205             bSuccess = SendBytesToPrinter(printerName, pUnmanagedBytes, nLength);
 206             // Free the unmanaged memory that you allocated earlier.  
 207             Marshal.FreeCoTaskMem(pUnmanagedBytes);
 208             return bSuccess;
 209         }
 210 
 211         public static bool SendStringToPrinter(string printerName, string text)
 212         {
 213             IntPtr pBytes;
 214             Int32 dwCount;
 215             // How many characters are in the string?  
 216             dwCount = (text.Length + 1) * Marshal.SystemMaxDBCSCharSize;
 217             // Assume that the printer is expecting ANSI text, and then convert  
 218             // the string to ANSI text.  
 219             pBytes = Marshal.StringToCoTaskMemAnsi(text);
 220             // Send the converted ANSI string to the printer.  
 221             SendBytesToPrinter(printerName, pBytes, dwCount);
 222             Marshal.FreeCoTaskMem(pBytes);
 223             return true;
 224         }
 225         #endregion  
 226 
 227         #region 日志记录方法
 228         private static void WriteLog(string text, LogType logType)
 229         {
 230             string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
 231             string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
 232             if (!Directory.Exists(LogsDirectory))
 233             {
 234                 Directory.CreateDirectory(LogsDirectory);
 235             }
 236             if (logType == LogType.Error)
 237             {
 238                 File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.Default);
 239             }
 240             if (logType == LogType.Print)
 241             {
 242                 if (text.StartsWith("N\r\nGW"))
 243                 {
 244                     using (FileStream fs = new FileStream(path, FileMode.Append))
 245                     {
 246                         byte[] bytes = TransferFormat.GetBytes(text);
 247                         byte[] tag = TransferFormat.GetBytes(endTag);
 248                         fs.Write(bytes, 0, bytes.Length);
 249                         fs.Write(tag, 0, tag.Length);
 250                         fs.Close();
 251                     }
 252                 }
 253                 else
 254                 {
 255                     File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.Default);
 256                 }
 257             }
 258         }
 259 
 260         private static void WriteLog(byte[] bytes, LogType logType)
 261         {
 262             string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
 263             string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
 264             if (!Directory.Exists(LogsDirectory))
 265             {
 266                 Directory.CreateDirectory(LogsDirectory);
 267             }
 268             if (logType == LogType.Error)
 269             {
 270                 File.AppendAllText(path, string.Format("{0}{1}", Encoding.Default.GetString(bytes), endTag), Encoding.Default);
 271             }
 272             if (logType == LogType.Print)
 273             {
 274                 string transferFormat = TransferFormat.GetString(bytes);
 275                 if (transferFormat.StartsWith("N\r\nGW"))
 276                 {
 277                     using (FileStream fs = new FileStream(path, FileMode.Append))
 278                     {
 279                         byte[] tag = TransferFormat.GetBytes(endTag);
 280                         fs.Write(bytes, 0, bytes.Length);
 281                         fs.Write(tag, 0, tag.Length);
 282                         fs.Close();
 283                     }
 284                 }
 285                 else
 286                 {
 287                     File.AppendAllText(path, string.Format("{0}{1}", Encoding.Default.GetString(bytes), endTag), Encoding.Default);
 288                 }
 289             }
 290         }
 291         #endregion  
 292 
 293         #region 封装方法,方便调用。
 294         public static bool PrintWithCOM(string cmd, int port, bool isWriteLog)
 295         {
 296             PrinterType = DeviceType.COM;
 297             Port = port;
 298             IsWriteLog = isWriteLog;
 299             return PrintCommand(cmd);
 300         }
 301 
 302         public static bool PrintWithCOM(byte[] bytes, int port, bool isWriteLog, ProgrammingLanguage progLanguage)
 303         {
 304             PrinterType = DeviceType.COM;
 305             Port = port;
 306             IsWriteLog = isWriteLog;
 307             PrinterProgrammingLanguage = progLanguage;
 308             return PrintGraphics(bytes);
 309         }
 310 
 311         public static bool PrintWithLPT(string cmd, int port, bool isWriteLog)
 312         {
 313             PrinterType = DeviceType.LPT;
 314             Port = port;
 315             IsWriteLog = isWriteLog;
 316             return PrintCommand(cmd);
 317         }
 318 
 319         public static bool PrintWithLPT(byte[] bytes, int port, bool isWriteLog, ProgrammingLanguage progLanguage)
 320         {
 321             PrinterType = DeviceType.LPT;
 322             Port = port;
 323             IsWriteLog = isWriteLog;
 324             PrinterProgrammingLanguage = progLanguage;
 325             return PrintGraphics(bytes);
 326         }
 327 
 328         public static bool PrintWithDRV(string cmd, string printerName, bool isWriteLog)
 329         {
 330             PrinterType = DeviceType.DRV;
 331             PrinterName = printerName;
 332             IsWriteLog = isWriteLog;
 333             return PrintCommand(cmd);
 334         }
 335 
 336         public static bool PrintWithDRV(byte[] bytes, string printerName, bool isWriteLog, ProgrammingLanguage progLanguage)
 337         {
 338             PrinterType = DeviceType.DRV;
 339             PrinterName = printerName;
 340             IsWriteLog = isWriteLog;
 341             PrinterProgrammingLanguage = progLanguage;
 342             return PrintGraphics(bytes);
 343         }
 344         #endregion  
 345 
 346         #region 打印ZPL、EPL指令
 347         public static bool PrintCommand(string cmd)
 348         {
 349             lock (SyncRoot)
 350             {
 351                 bool result = false;
 352                 try
 353                 {
 354                     switch (PrinterType)
 355                     {
 356                         case DeviceType.COM:
 357                             result = comPrint(Encoding.Default.GetBytes(cmd));
 358                             break;
 359                         case DeviceType.LPT:
 360                             result = lptPrint(Encoding.Default.GetBytes(cmd));
 361                             break;
 362                         case DeviceType.DRV:
 363                             result = drvPrint(Encoding.Default.GetBytes(cmd));
 364                             break;
 365                         case DeviceType.TCP:
 366                             result = tcpPrint(Encoding.Default.GetBytes(cmd));
 367                             break;  
 368                     }
 369                     if (!string.IsNullOrEmpty(cmd) && IsWriteLog)
 370                     {
 371                         WriteLog(cmd, LogType.Print);
 372                     }
 373                 }
 374                 catch (Exception ex)
 375                 {
 376                     //记录日志  
 377                     if (IsWriteLog)
 378                     {
 379                         WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
 380                     }
 381                 }
 382                 finally
 383                 {
 384                     GraphBuffer = new byte[0];
 385                 }
 386                 return result;
 387             }
 388         }
 389         #endregion  
 390 
 391         #region 打印图像字节流
 392         public static bool PrintGraphics(byte[] graph)
 393         {
 394             lock (SyncRoot)
 395             {
 396                 bool result = false;
 397                 try
 398                 {
 399                     GraphBuffer = graph;
 400                     byte[] cmdBytes = new byte[0];
 401                     if (PrinterProgrammingLanguage == ProgrammingLanguage.ZPL)
 402                     {
 403                         cmdBytes = getZPLBytes();
 404                     }
 405                     if (PrinterProgrammingLanguage == ProgrammingLanguage.EPL)
 406                     {
 407                         cmdBytes = getEPLBytes();
 408                     }
 409                     if (PrinterProgrammingLanguage == ProgrammingLanguage.CPCL)
 410                     {
 411                         cmdBytes = getCPCLBytes();
 412                     }
 413                     switch (PrinterType)
 414                     {
 415                         case DeviceType.COM:
 416                             result = comPrint(cmdBytes);
 417                             break;
 418                         case DeviceType.LPT:
 419                             result = lptPrint(cmdBytes);
 420                             break;
 421                         case DeviceType.DRV:
 422                             result = drvPrint(cmdBytes);
 423                             break;
 424                         case DeviceType.TCP:
 425                             result = tcpPrint(cmdBytes);
 426                             break;  
 427                     }
 428                     if (cmdBytes.Length > 0 && IsWriteLog)
 429                     {
 430                         WriteLog(cmdBytes, LogType.Print);
 431                     }
 432                 }
 433                 catch (Exception ex)
 434                 {
 435                     //记录日志  
 436                     if (IsWriteLog)
 437                     {
 438                         WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
 439                     }
 440                 }
 441                 finally
 442                 {
 443                     GraphBuffer = new byte[0];
 444                 }
 445                 return result;
 446             }
 447         }
 448         #endregion  
 449 
 450         #region COM/LPT/DRV三种模式打印方法
 451         private static bool drvPrint(byte[] cmdBytes)
 452         {
 453             bool result = false;
 454             try
 455             {
 456                 if (!string.IsNullOrEmpty(PrinterName))
 457                 {
 458                     result = SendBytesToPrinter(PrinterName, cmdBytes);
 459                 }
 460             }
 461             catch (Exception ex)
 462             {
 463                 throw ex;
 464             }
 465             return result;
 466         }
 467 
 468         private static bool comPrint(byte[] cmdBytes)
 469         {
 470             bool result = false;
 471             SerialPort com = new SerialPort(string.Format("{0}{1}", PrinterType, Port), 9600, Parity.None, 8, StopBits.One);
 472             try
 473             {
 474                 com.Open();
 475                 com.Write(cmdBytes, 0, cmdBytes.Length);
 476                 result = true;
 477             }
 478             catch (Exception ex)
 479             {
 480                 throw ex;
 481             }
 482             finally
 483             {
 484                 if (com.IsOpen)
 485                 {
 486                     com.Close();
 487                 }
 488             }
 489             return result;
 490         }
 491 
 492         private static bool lptPrint(byte[] cmdBytes)
 493         {
 494             bool result = false;
 495             FileStream fileStream = null;
 496             StreamWriter streamWriter = null;
 497             SafeFileHandle handle = null;
 498             try
 499             {
 500                 handle = CreateFile(string.Format("{0}{1}", PrinterType, Port), GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
 501                 if (!handle.IsInvalid)
 502                 {
 503                     fileStream = new FileStream(handle, FileAccess.ReadWrite);
 504                     streamWriter = new StreamWriter(fileStream, Encoding.Default);
 505                     streamWriter.Write(cmdBytes);
 506                     result = true;
 507                 }
 508             }
 509             catch (Exception ex)
 510             {
 511                 throw ex;
 512             }
 513             finally
 514             {
 515                 if (fileStream != null)
 516                 {
 517                     fileStream.Close();
 518                     fileStream = null;
 519                 }
 520                 if (streamWriter != null)
 521                 {
 522                     streamWriter.Close();
 523                     streamWriter = null;
 524                 }
 525                 if (handle != null)
 526                 {
 527                     handle.Close();
 528                     handle = null;
 529                 }
 530             }
 531             return result;
 532         }
 533 
 534         private static bool tcpPrint(byte[] cmdBytes) 
 535         {
 536             bool result = false;
 537             TcpClient tcp = null;
 538             try
 539             {
 540                 IPAddress ip = IPAddress.Parse(TcpIpAddress);
 541                 IPEndPoint iport = new IPEndPoint(ip, TcpPort);//9100为小票打印机指定端口
 542                 tcp = new TcpClient(iport);
 543                 tcp.SendTimeout = 1000;
 544                 tcp.ReceiveTimeout = 1000;
 545                 if (tcp.Connected)
 546                 {
 547                     tcp.Client.Send(cmdBytes);
 548                     result = true;
 549                 }
 550             }
 551             catch (Exception ex)
 552             {
 553                 throw new Exception("打印失败,请检查打印机或网络设置。", ex);
 554             }
 555             finally
 556             {
 557                 if (tcp != null)
 558                 {
 559                     if (tcp.Client != null)
 560                     {
 561                         tcp.Client.Close();
 562                         tcp.Client = null;
 563                     }
 564                     tcp.Close();
 565                     tcp = null;
 566                 }
 567             }
 568             return result;  
 569         }
 570         #endregion  
 571 
 572         #region 生成ZPL图像打印指令
 573         private static byte[] getZPLBytes()
 574         {
 575             byte[] result = new byte[0];
 576             byte[] bmpData = getBitmapData();
 577             string textBitmap = string.Empty;
 578             string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
 579             for (int i = 0; i < GraphHeight; i++)
 580             {
 581                 textBitmap += textHex.Substring(i * RowRealBytesCount * 2, RowRealBytesCount * 2) + "\r\n";
 582             }
 583             string text = string.Format("~DGR:IMAGE.GRF,{0},{1},\r\n{2}^XGR:IMAGE.GRF,1,1^FS\r\n^IDR:IMAGE.GRF\r\n",
 584                 GraphHeight * RowRealBytesCount,
 585                 RowRealBytesCount,
 586                 textBitmap);
 587             result = Encoding.Default.GetBytes(text);
 588             return result;
 589         }
 590         #endregion
 591 
 592         #region 生成EPL图像打印指令
 593         private static byte[] getEPLBytes()
 594         {
 595             byte[] result = new byte[0];
 596             byte[] buffer = getBitmapData();
 597             string text = string.Format("N\r\nGW{0},{1},{2},{3},{4}\r\nP\r\n",
 598                 0,
 599                 0,
 600                 RowRealBytesCount,
 601                 GraphHeight,
 602                 TransferFormat.GetString(buffer));
 603             result = TransferFormat.GetBytes(text);
 604             return result;
 605         }
 606         #endregion  
 607 
 608         #region 生成CPCL图像打印指令
 609         public static byte[] getCPCLBytes()
 610         {
 611             //GRAPHICS Commands  
 612             //Bit-mapped graphics can be printed by using graphics commands. ASCII hex (hexadecimal) is  
 613             //used for expanded graphics data (see example). Data size can be reduced to one-half by utilizing the  
 614             //COMPRESSED-GRAPHICS commands with the equivalent binary character(s) of the hex data. When  
 615             //using CG, a single 8 bit character is sent for every 8 bits of graphics data. When using EG two characters  
 616             //(16 bits) are used to transmit 8 bits of graphics data, making EG only half as efficient. Since this data is  
 617             //character data, however, it can be easier to handle and transmit than binary data.  
 618             //Format:  
 619             //{command} {width} {height} {x} {y} {data}  
 620             //where:  
 621             //{command}: Choose from the following:  
 622             //EXPANDED-GRAPHICS (or EG): Prints expanded graphics horizontally.  
 623             //VEXPANDED-GRAPHICS (or VEG): Prints expanded graphics vertically.  
 624             //COMPRESSED-GRAPHICS (or CG): Prints compressed graphics horizontally.  
 625             //VCOMPRESSED-GRAPHICS (or VCG): Prints compressed graphics vertically.  
 626             //{width}: Byte-width of image.  
 627             //{height} Dot-height of image.  
 628             //{x}: Horizontal starting position.  
 629             //{y}: Vertical starting position.  
 630             //{data}: Graphics data.  
 631             //Graphics command example  
 632             //Input:  
 633             //! 0 200 200 210 1  
 634             //EG 2 16 90 45 F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F  
 635             //F0F0F0F0F0F0F0F00F0F0F0F0F0F0F0F  
 636             //FORM  
 637             //PRINT  
 638 
 639             byte[] bmpData = getBitmapData();
 640             int bmpDataLength = bmpData.Length;
 641             for (int i = 0; i < bmpDataLength; i++)
 642             {
 643                 bmpData[i] ^= 0xFF;
 644             }
 645             string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
 646             string text = string.Format("! {0} {1} {2} {3} {4}\r\nEG {5} {6} {7} {8} {9}\r\nFORM\r\nPRINT\r\n",
 647                 0, //水平偏移量  
 648                 TcpPrinterDPI, //横向DPI  
 649                 TcpPrinterDPI, //纵向DPI  
 650                 (int)(TcpLabelMaxHeightCM / 2.54f * TcpPrinterDPI), //标签最大像素高度=DPI*标签纸高度(英寸)  
 651                 Copies, //份数  
 652                 RowRealBytesCount, //图像的字节宽度  
 653                 GraphHeight, //图像的像素高度  
 654                 0, //横向的开始位置  
 655                 0, //纵向的开始位置  
 656                 textHex
 657                 );
 658             return Encoding.UTF8.GetBytes(text);
 659         }
 660         #endregion
 661 
 662         #region 获取单色位图数据
 663         /// <summary>  
 664         /// 获取单色位图数据(1bpp),不含文件头、信息头、调色板三类数据。  
 665         /// </summary>  
 666         /// <returns></returns>  
 667         private static byte[] getBitmapData()
 668         {
 669             MemoryStream srcStream = new MemoryStream();
 670             MemoryStream dstStream = new MemoryStream();
 671             Bitmap srcBmp = null;
 672             Bitmap dstBmp = null;
 673             byte[] srcBuffer = null;
 674             byte[] dstBuffer = null;
 675             byte[] result = null;
 676             try
 677             {
 678                 srcStream = new MemoryStream(GraphBuffer);
 679                 srcBmp = Bitmap.FromStream(srcStream) as Bitmap;
 680                 srcBuffer = srcStream.ToArray();
 681                 GraphWidth = srcBmp.Width;
 682                 GraphHeight = srcBmp.Height;
 683                 dstBmp = srcBmp.Clone(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), PixelFormat.Format1bppIndexed);
 684                 dstBmp.Save(dstStream, ImageFormat.Bmp);
 685                 dstBuffer = dstStream.ToArray();
 686 
 687                 int bfSize = BitConverter.ToInt32(dstBuffer, 2);
 688                 int bfOffBits = BitConverter.ToInt32(dstBuffer, 10);
 689                 int bitmapDataLength = bfSize - bfOffBits;
 690                 result = new byte[GraphHeight * RowRealBytesCount];
 691 
 692                 //读取时需要反向读取每行字节实现上下翻转的效果,打印机打印顺序需要这样读取。  
 693                 for (int i = 0; i < GraphHeight; i++)
 694                 {
 695                     Array.Copy(dstBuffer, bfOffBits + (GraphHeight - 1 - i) * RowSize, result, i * RowRealBytesCount, RowRealBytesCount);
 696                 }
 697             }
 698             catch (Exception ex)
 699             {
 700                 throw ex;
 701             }
 702             finally
 703             {
 704                 if (srcStream != null)
 705                 {
 706                     srcStream.Dispose();
 707                     srcStream = null;
 708                 }
 709                 if (dstStream != null)
 710                 {
 711                     dstStream.Dispose();
 712                     dstStream = null;
 713                 }
 714                 if (srcBmp != null)
 715                 {
 716                     srcBmp.Dispose();
 717                     srcBmp = null;
 718                 }
 719                 if (dstBmp != null)
 720                 {
 721                     dstBmp.Dispose();
 722                     dstBmp = null;
 723                 }
 724             }
 725             return result;
 726         }
 727         #endregion  
 728 
 729         #region 扩展
 730 
 731         #region CPCL命令打印24位bmp
 732         private static string get24BitBmpData(string filePath)
 733         {
 734             Bitmap bmp = new Bitmap(filePath);
 735             byte[] bitArray = { 128, 64, 32, 16, 8, 4, 2, 1 };
 736             string imgTxt = "";
 737             Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
 738             BitmapData data = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
 739             IntPtr firstPix = data.Scan0;
 740 
 741             int rowByteCount = bmp.Width * 3;
 742             int filledCount = data.Stride - rowByteCount;
 743             int bytes = data.Stride * data.Height;//Math.Ceiling((double)bmp.Width / 8)
 744             byte[] rgbValues = new byte[bytes];
 745             System.Runtime.InteropServices.Marshal.Copy(firstPix, rgbValues, 0, bytes);
 746 
 747             int printRowByteCount = Convert.ToInt32(Math.Ceiling((double)(bmp.Width) / 8));
 748             int printRowByteFillCount = 4 - (printRowByteCount % 4);
 749             //int bitFillCount = 8 - (bmp.Width % 8);
 750             byte[] printData = new byte[(printRowByteCount + printRowByteFillCount) * bmp.Height];
 751 
 752             int byteCount = 0;
 753             int bitCount = 0;
 754             int rowPoint = 0;
 755             for (int i = 0; i < rgbValues.Length; i += 3)
 756             {
 757                 int rgbValue = rgbValues[i] + rgbValues[i + 1] + rgbValues[i + 2];
 758                 if (rgbValue != (255 * 3))
 759                 {
 760                     printData[byteCount] = Convert.ToByte(printData[byteCount] | bitArray[bitCount]);
 761                 }
 762                 if (bitCount == 7)
 763                 {
 764                     bitCount = 0;
 765                     byteCount++;
 766                 }
 767                 else
 768                 {
 769                     bitCount++;
 770                 }
 771                 if ((rowPoint + 3) == rowByteCount)
 772                 {
 773                     rowPoint = 0;
 774                     if (bitCount > 0)
 775                     {
 776                         byteCount++;
 777                     }
 778                     bitCount = 0;
 779                     byteCount += printRowByteFillCount;
 780                     i = i + filledCount;
 781                 }
 782                 else
 783                 {
 784                     rowPoint += 3;
 785                 }
 786             }
 787 
 788             foreach (byte byteData in printData)
 789             {
 790                 string hexStr = Convert.ToString(byteData, 16);
 791                 if (hexStr.Length == 1)
 792                 {
 793                     hexStr = '0' + hexStr;
 794                 }
 795                 imgTxt += hexStr;
 796             }
 797             bmp.UnlockBits(data);
 798             return imgTxt.ToUpper();
 799         }
 800 
 801         public static void Printer(string bitbmpPath) 
 802         {
 803             string CRNL = "\r\n";
 804             string imgTxt = get24BitBmpData(bitbmpPath);
 805             string cmddata = "! 0 200 200 300 1" + CRNL +
 806                             "EG " + 24 + " " + 50 + " 10 10 " + imgTxt + CRNL +
 807                             "FORM" + CRNL +
 808                             "PRINT" + CRNL;
 809             try
 810             {
 811                 string ipAddress = "192.168.1.212";
 812                 int port = 9100;
 813 
 814                 // Open connection
 815                 System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient();
 816                 client.Connect(ipAddress, port);
 817 
 818                 // Write CPCL String to connection
 819                 System.IO.StreamWriter writer =new System.IO.StreamWriter(client.GetStream());
 820                 writer.Write(cmddata);
 821                 writer.Flush();
 822 
 823                 // Close Connection
 824                 writer.Close();
 825                 client.Close();
 826             }
 827             catch (Exception)
 828             {
 829                 // Catch Exception
 830             }
 831         }
 832         #endregion
 833 
 834         #endregion
 835     }
 836 
 837     #region 定义设备类型枚举
 838     public enum DeviceType
 839     {
 840         COM = 0,
 841         LPT = 1,
 842         DRV = 2,
 843         TCP = 3
 844     }
 845     #endregion
 846 
 847     #region 定义打印机指令类型枚举
 848     public enum ProgrammingLanguage
 849     {
 850         ZPL = 0,
 851         EPL = 1,
 852         CPCL = 2
 853     }
 854     #endregion
 855 
 856     #region 定义日志类型枚举
 857     public enum LogType
 858     {
 859         Print = 0,
 860         Error = 1
 861     }
 862     #endregion
 863 
 864     #region 定义打印文档信息类
 865     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
 866     public class DocInfo
 867     {
 868         [MarshalAs(UnmanagedType.LPStr)]
 869         public string DocName;
 870         [MarshalAs(UnmanagedType.LPStr)]
 871         public string OutputFile;
 872         [MarshalAs(UnmanagedType.LPStr)]
 873         public string DataType;
 874     }
 875     #endregion
 876 
 877     #region 定义图像设备信息类
 878     public class DeviceInfo
 879     {
 880         #region 属性说明
 881         /* 
 882         ColorDepth  
 883             图像输出支持的颜色范围的像素深度。有效值为 1、4、8、24 和 32。默认值为 24。仅对 TIFF 呈现支持 ColorDepth,对于其他图像输出格式报表服务器将忽略此设置。 
 884  
 885         注意:  
 886         对于此版本的 SQL Server,此设置的值将被忽略,且通常将 TIFF 图像呈现为 24 位。 
 887   
 888         Columns  
 889             要为报表设置的列数。此值将覆盖报表的原始设置。 
 890   
 891         ColumnSpacing  
 892             要为报表设置的列间距。此值将覆盖报表的原始设置。 
 893   
 894         DpiX  
 895             输出设备在 X 方向的分辨率。默认值为 96。 
 896   
 897         DpiY  
 898             输出设备在 Y 方向的分辨率。默认值为 96。 
 899   
 900         EndPage  
 901             要呈现的报表的最后一页。默认值为 StartPage 的值。 
 902   
 903         MarginBottom  
 904             要为报表设置的下边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。 
 905   
 906         MarginLeft  
 907             要为报表设置的左边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。 
 908   
 909         MarginRight  
 910             要为报表设置的右边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。 
 911   
 912         MarginTop  
 913             要为报表设置的上边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。 
 914   
 915         OutputFormat  
 916             图形设备接口 (GDI) 支持的输出格式之一:BMP、EMF、GIF、JPEG、PNG 或 TIFF。 
 917   
 918         PageHeight  
 919             要为报表设置的页高,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,11in)。此值将覆盖报表的原始设置。 
 920   
 921         PageWidth  
 922             要为报表设置的页宽,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,8.5in)。此值将覆盖报表的原始设置。 
 923   
 924         StartPage  
 925             要呈现的报告的第一页。值为 0 指示将呈现所有页。默认值为 1。  
 926          */
 927         #endregion
 928 
 929         public enum GDIOutputFormat { BMP, EMF, GIF, JPEG, PNG, TIFF }
 930 
 931         public int ColorDepth { get; set; }
 932         public int Columns { get; set; }
 933         public int ColumnSpacing { get; set; }
 934         public int DpiX { get; set; }
 935         public int DpiY { get; set; }
 936         public int EndPage { get; set; }
 937         public int MarginBottom { get; set; }
 938         public int MarginLeft { get; set; }
 939         public int MarginRight { get; set; }
 940         public int MarginTop { get; set; }
 941         public GDIOutputFormat OutputFormat { get; set; }
 942         public int PageHeight { get; set; }
 943         public int PageWidth { get; set; }
 944         public int StartPage { get; set; }
 945 
 946         private const string xmlFormater = @"<DeviceInfo>  
 947                 <ColorDepth>{0}</ColorDepth>  
 948                 <Columns>{1}</Columns>  
 949                 <ColumnSpacing>{2}</ColumnSpacing>  
 950                 <DpiX>{3}</DpiX>  
 951                 <DpiY>{4}</DpiY>  
 952                 <EndPage>{5}</EndPage>  
 953                 <MarginBottom>{6}</MarginBottom>  
 954                 <MarginLeft>{7}</MarginLeft>  
 955                 <MarginRight>{8}</MarginRight>  
 956                 <MarginTop>{9}</MarginTop>  
 957                 <OutputFormat>{10}</OutputFormat>  
 958                 <PageHeight>{11}</PageHeight>  
 959                 <PageWidth>{12}</PageWidth>  
 960                 <StartPage>{13}</StartPage>  
 961                 </DeviceInfo>";
 962 
 963         public DeviceInfo()
 964         {
 965             this.ColorDepth = 24;
 966             this.Columns = 0;
 967             this.StartPage = 1;
 968             this.EndPage = 1;
 969         }
 970 
 971         public string GetDeviceInfo()
 972         {
 973             string result = string.Format(xmlFormater,
 974                 this.ColorDepth,
 975                 this.Columns,
 976                 this.ColumnSpacing,
 977                 this.DpiX,
 978                 this.DpiY,
 979                 this.EndPage,
 980                 this.MarginBottom,
 981                 this.MarginLeft,
 982                 this.MarginRight,
 983                 this.MarginTop,
 984                 this.OutputFormat,
 985                 this.PageHeight,
 986                 this.PageWidth,
 987                 this.StartPage);
 988             return result;
 989         }
 990 
 991         public string GetDeviceInfoForImage()
 992         {
 993             string result = string.Format("<DeviceInfo><StartPage>{0}</StartPage><EndPage>{1}</EndPage><OutputFormat>{2}</OutputFormat><DpiX>{3}</DpiX><DpiY>{4}</DpiY></DeviceInfo>",
 994                 this.StartPage,
 995                 this.EndPage,
 996                 this.OutputFormat,
 997                 this.DpiX,
 998                 this.DpiY);
 999             return result;
1000         }
1001     }
1002     #endregion  
1003 }

http://www.cnblogs.com/rinack/p/4843627.html

posted @ 2017-01-04 11:56  FelixWang  阅读(2072)  评论(1编辑  收藏  举报