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

ZebraPrintHelper.cs。

[csharp] view plaincopy
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.Drawing.Imaging;
  5. using System.Drawing.Printing;
  6. using System.IO;
  7. using System.IO.Ports;
  8. using System.Linq;
  9. using System.Runtime.InteropServices;
  10. using System.Text;
  11. using Microsoft.Win32.SafeHandles;
  12. namespace Umisky.HTServer.Util
  13. {
  14. #region 定义设备类型枚举
  15. public enum DeviceType
  16. {
  17. COM = 0,
  18. LPT = 1,
  19. DRV = 2
  20. }
  21. #endregion
  22. #region 定义打印机指令类型枚举
  23. public enum ProgrammingLanguage
  24. {
  25. ZPL = 0,
  26. EPL = 1
  27. }
  28. #endregion
  29. #region 定义日志类型枚举
  30. public enum LogType
  31. {
  32. Print = 0,
  33. Error = 1
  34. }
  35. #endregion
  36. #region 定义打印文档信息类
  37. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
  38. public class DocInfo
  39. {
  40. [MarshalAs(UnmanagedType.LPStr)]
  41. public string DocName;
  42. [MarshalAs(UnmanagedType.LPStr)]
  43. public string OutputFile;
  44. [MarshalAs(UnmanagedType.LPStr)]
  45. public string DataType;
  46. }
  47. #endregion
  48. #region 定义图像设备信息类
  49. public class DeviceInfo
  50. {
  51. #region 属性说明
  52. /*
  53. ColorDepth
  54. 图像输出支持的颜色范围的像素深度。有效值为 1、4、8、24 和 32。默认值为 24。仅对 TIFF 呈现支持 ColorDepth,对于其他图像输出格式报表服务器将忽略此设置。
  55. 注意:
  56. 对于此版本的 SQL Server,此设置的值将被忽略,且通常将 TIFF 图像呈现为 24 位。
  57. Columns
  58. 要为报表设置的列数。此值将覆盖报表的原始设置。
  59. ColumnSpacing
  60. 要为报表设置的列间距。此值将覆盖报表的原始设置。
  61. DpiX
  62. 输出设备在 X 方向的分辨率。默认值为 96。
  63. DpiY
  64. 输出设备在 Y 方向的分辨率。默认值为 96。
  65. EndPage
  66. 要呈现的报表的最后一页。默认值为 StartPage 的值。
  67. MarginBottom
  68. 要为报表设置的下边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。
  69. MarginLeft
  70. 要为报表设置的左边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。
  71. MarginRight
  72. 要为报表设置的右边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。
  73. MarginTop
  74. 要为报表设置的上边距值,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,1in)。此值将覆盖报表的原始设置。
  75. OutputFormat
  76. 图形设备接口 (GDI) 支持的输出格式之一:BMP、EMF、GIF、JPEG、PNG 或 TIFF。
  77. PageHeight
  78. 要为报表设置的页高,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,11in)。此值将覆盖报表的原始设置。
  79. PageWidth
  80. 要为报表设置的页宽,以英寸为单位。您必须包含一个整数或小数值,后跟“in”(例如,8.5in)。此值将覆盖报表的原始设置。
  81. StartPage
  82. 要呈现的报告的第一页。值为 0 指示将呈现所有页。默认值为 1。
  83. */
  84. #endregion
  85. public enum GDIOutputFormat { BMP, EMF, GIF, JPEG, PNG, TIFF }
  86. public int ColorDepth { get; set; }
  87. public int Columns { get; set; }
  88. public int ColumnSpacing { get; set; }
  89. public int DpiX { get; set; }
  90. public int DpiY { get; set; }
  91. public int EndPage { get; set; }
  92. public int MarginBottom { get; set; }
  93. public int MarginLeft { get; set; }
  94. public int MarginRight { get; set; }
  95. public int MarginTop { get; set; }
  96. public GDIOutputFormat OutputFormat { get; set; }
  97. public int PageHeight { get; set; }
  98. public int PageWidth { get; set; }
  99. public int StartPage { get; set; }
  100. private const string xmlFormater = @"<DeviceInfo>
  101. <ColorDepth>{0}</ColorDepth>
  102. <Columns>{1}</Columns>
  103. <ColumnSpacing>{2}</ColumnSpacing>
  104. <DpiX>{3}</DpiX>
  105. <DpiY>{4}</DpiY>
  106. <EndPage>{5}</EndPage>
  107. <MarginBottom>{6}</MarginBottom>
  108. <MarginLeft>{7}</MarginLeft>
  109. <MarginRight>{8}</MarginRight>
  110. <MarginTop>{9}</MarginTop>
  111. <OutputFormat>{10}</OutputFormat>
  112. <PageHeight>{11}</PageHeight>
  113. <PageWidth>{12}</PageWidth>
  114. <StartPage>{13}</StartPage>
  115. </DeviceInfo>";
  116. public DeviceInfo()
  117. {
  118. this.ColorDepth = 24;
  119. this.Columns = 0;
  120. this.StartPage = 1;
  121. this.EndPage = 1;
  122. }
  123. public string GetDeviceInfo()
  124. {
  125. string result = string.Format(xmlFormater,
  126. this.ColorDepth,
  127. this.Columns,
  128. this.ColumnSpacing,
  129. this.DpiX,
  130. this.DpiY,
  131. this.EndPage,
  132. this.MarginBottom,
  133. this.MarginLeft,
  134. this.MarginRight,
  135. this.MarginTop,
  136. this.OutputFormat,
  137. this.PageHeight,
  138. this.PageWidth,
  139. this.StartPage);
  140. return result;
  141. }
  142. public string GetDeviceInfoForImage()
  143. {
  144. string result = string.Format("<DeviceInfo><StartPage>{0}</StartPage><EndPage>{1}</EndPage><OutputFormat>{2}</OutputFormat><DpiX>{3}</DpiX><DpiY>{4}</DpiY></DeviceInfo>",
  145. this.StartPage,
  146. this.EndPage,
  147. this.OutputFormat,
  148. this.DpiX,
  149. this.DpiY);
  150. return result;
  151. }
  152. }
  153. #endregion
  154. #region 定义斑马打印助手类
  155. /// <summary>
  156. /// 斑马打印助手,支持LPT/COM/DRV三种模式,适用于标签、票据、条码打印。
  157. /// </summary>
  158. public static class ZebraPrintHelper
  159. {
  160. #region 定义API方法
  161. #region 写打印口(LPT)方法
  162. private const short FILE_ATTRIBUTE_NORMAL = 0x80;
  163. private const short INVALID_HANDLE_VALUE = -1;
  164. private const uint GENERIC_READ = 0x80000000;
  165. private const uint GENERIC_WRITE = 0x40000000;
  166. private const uint CREATE_NEW = 1;
  167. private const uint CREATE_ALWAYS = 2;
  168. private const uint OPEN_EXISTING = 3;
  169. [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
  170. private static extern SafeFileHandle CreateFile(string strFileName,
  171. uint dwDesiredAccess,
  172. uint dwShareMode,
  173. IntPtr intptrSecurityAttributes,
  174. uint dwCreationDisposition,
  175. uint dwFlagsAndAttributes,
  176. IntPtr intptrTemplateFile);
  177. #endregion
  178. [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  179. public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string printerName, out IntPtr intptrPrinter, IntPtr intptrPrintDocument);
  180. [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  181. public static extern bool ClosePrinter(IntPtr intptrPrinter);
  182. [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Auto, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  183. public static extern bool StartDocPrinter(IntPtr intptrPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DocInfo docInfo);
  184. [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  185. public static extern bool EndDocPrinter(IntPtr intptrPrinter);
  186. [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  187. public static extern bool StartPagePrinter(IntPtr intptrPrinter);
  188. [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  189. public static extern bool EndPagePrinter(IntPtr intptrPrinter);
  190. [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
  191. public static extern bool WritePrinter(IntPtr intptrPrinter, IntPtr intptrBytes, Int32 count, out Int32 written);
  192. #endregion
  193. #region 定义私有字段
  194. /// <summary>
  195. /// 线程锁,防止多线程调用。
  196. /// </summary>
  197. private static object SyncRoot = new object();
  198. /// <summary>
  199. /// 字节流传递时采用的字符编码
  200. /// </summary>
  201. private static readonly Encoding TransferFormat = Encoding.GetEncoding("iso-8859-1");
  202. #endregion
  203. #region 定义属性
  204. public static int Port { get; set; }
  205. public static string PrinterName { get; set; }
  206. public static bool IsWriteLog { get; set; }
  207. public static DeviceType PrinterType { get; set; }
  208. public static ProgrammingLanguage PrinterProgrammingLanguage { get; set; }
  209. /// <summary>
  210. /// 日志保存目录,WEB应用注意不能放在BIN目录下。
  211. /// </summary>
  212. public static string LogsDirectory { get; set; }
  213. private static byte[] GraphBuffer { get; set; }
  214. private static int GraphWidth { get; set; }
  215. private static int GraphHeight { get; set; }
  216. private static int RowSize
  217. {
  218. get
  219. {
  220. return (((GraphWidth) + 31) >> 5) << 2;
  221. }
  222. }
  223. private static int RowRealBytesCount
  224. {
  225. get
  226. {
  227. if ((GraphWidth % 8) > 0)
  228. {
  229. return GraphWidth / 8 + 1;
  230. }
  231. else
  232. {
  233. return GraphWidth / 8;
  234. }
  235. }
  236. }
  237. #endregion
  238. #region 静态构造方法
  239. static ZebraPrintHelper()
  240. {
  241. GraphBuffer = new byte[0];
  242. IsWriteLog = false;
  243. LogsDirectory = "logs";
  244. }
  245. #endregion
  246. #region 定义发送原始数据到打印机的方法
  247. private static bool SendBytesToPrinter(string printerName, IntPtr intptrBytes, Int32 count)
  248. {
  249. Int32 error = 0, written = 0;
  250. IntPtr intptrPrinter = new IntPtr(0);
  251. DocInfo docInfo = new DocInfo();
  252. bool bSuccess = false;
  253. docInfo.DocName = ".NET RAW Document";
  254. docInfo.DataType = "RAW";
  255. // Open the printer.
  256. if (OpenPrinter(printerName.Normalize(), out intptrPrinter, IntPtr.Zero))
  257. {
  258. // Start a document.
  259. if (StartDocPrinter(intptrPrinter, 1, docInfo))
  260. {
  261. // Start a page.
  262. if (StartPagePrinter(intptrPrinter))
  263. {
  264. // Write your bytes.
  265. bSuccess = WritePrinter(intptrPrinter, intptrBytes, count, out written);
  266. EndPagePrinter(intptrPrinter);
  267. }
  268. EndDocPrinter(intptrPrinter);
  269. }
  270. ClosePrinter(intptrPrinter);
  271. }
  272. // If you did not succeed, GetLastError may give more information
  273. // about why not.
  274. if (bSuccess == false)
  275. {
  276. error = Marshal.GetLastWin32Error();
  277. }
  278. return bSuccess;
  279. }
  280. public static bool SendFileToPrinter(string printerName, string fileName)
  281. {
  282. // Open the file.
  283. FileStream fs = new FileStream(fileName, FileMode.Open);
  284. // Create a BinaryReader on the file.
  285. BinaryReader br = new BinaryReader(fs);
  286. // Dim an array of bytes big enough to hold the file's contents.
  287. Byte[] bytes = new Byte[fs.Length];
  288. bool bSuccess = false;
  289. // Your unmanaged pointer.
  290. IntPtr pUnmanagedBytes = new IntPtr(0);
  291. int nLength;
  292. nLength = Convert.ToInt32(fs.Length);
  293. // Read the contents of the file into the array.
  294. bytes = br.ReadBytes(nLength);
  295. // Allocate some unmanaged memory for those bytes.
  296. pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
  297. // Copy the managed byte array into the unmanaged array.
  298. Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
  299. // Send the unmanaged bytes to the printer.
  300. bSuccess = SendBytesToPrinter(printerName, pUnmanagedBytes, nLength);
  301. // Free the unmanaged memory that you allocated earlier.
  302. Marshal.FreeCoTaskMem(pUnmanagedBytes);
  303. return bSuccess;
  304. }
  305. public static bool SendBytesToPrinter(string printerName, byte[] bytes)
  306. {
  307. bool bSuccess = false;
  308. IntPtr pUnmanagedBytes = new IntPtr(0);
  309. int nLength = bytes.Length;
  310. // Allocate some unmanaged memory for those bytes.
  311. pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
  312. // Copy the managed byte array into the unmanaged array.
  313. Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength);
  314. // Send the unmanaged bytes to the printer.
  315. bSuccess = SendBytesToPrinter(printerName, pUnmanagedBytes, nLength);
  316. // Free the unmanaged memory that you allocated earlier.
  317. Marshal.FreeCoTaskMem(pUnmanagedBytes);
  318. return bSuccess;
  319. }
  320. public static bool SendStringToPrinter(string printerName, string text)
  321. {
  322. IntPtr pBytes;
  323. Int32 dwCount;
  324. // How many characters are in the string?
  325. dwCount = (text.Length + 1) * Marshal.SystemMaxDBCSCharSize;
  326. // Assume that the printer is expecting ANSI text, and then convert
  327. // the string to ANSI text.
  328. pBytes = Marshal.StringToCoTaskMemAnsi(text);
  329. // Send the converted ANSI string to the printer.
  330. SendBytesToPrinter(printerName, pBytes, dwCount);
  331. Marshal.FreeCoTaskMem(pBytes);
  332. return true;
  333. }
  334. #endregion
  335. #region 日志记录方法
  336. private static void WriteLog(string text, LogType logType)
  337. {
  338. string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
  339. string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
  340. if (!Directory.Exists(LogsDirectory))
  341. {
  342. Directory.CreateDirectory(LogsDirectory);
  343. }
  344. if (logType == LogType.Error)
  345. {
  346. File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.Default);
  347. }
  348. if (logType == LogType.Print)
  349. {
  350. if (text.StartsWith("N\r\nGW"))
  351. {
  352. using (FileStream fs = new FileStream(path, FileMode.Append))
  353. {
  354. byte[] bytes = TransferFormat.GetBytes(text);
  355. byte[] tag = TransferFormat.GetBytes(endTag);
  356. fs.Write(bytes, 0, bytes.Length);
  357. fs.Write(tag, 0, tag.Length);
  358. fs.Close();
  359. }
  360. }
  361. else
  362. {
  363. File.AppendAllText(path, string.Format("{0}{1}", text, endTag), Encoding.Default);
  364. }
  365. }
  366. }
  367. private static void WriteLog(byte[] bytes, LogType logType)
  368. {
  369. string endTag = string.Format("\r\n{0}\r\n", new string('=', 80));
  370. string path = string.Format("{0}\\{1}-{2}.log", LogsDirectory, DateTime.Now.ToString("yyyy-MM-dd"), logType);
  371. if (!Directory.Exists(LogsDirectory))
  372. {
  373. Directory.CreateDirectory(LogsDirectory);
  374. }
  375. if (logType == LogType.Error)
  376. {
  377. File.AppendAllText(path, string.Format("{0}{1}", Encoding.Default.GetString(bytes), endTag), Encoding.Default);
  378. }
  379. if (logType == LogType.Print)
  380. {
  381. string transferFormat = TransferFormat.GetString(bytes);
  382. if (transferFormat.StartsWith("N\r\nGW"))
  383. {
  384. using (FileStream fs = new FileStream(path, FileMode.Append))
  385. {
  386. byte[] tag = TransferFormat.GetBytes(endTag);
  387. fs.Write(bytes, 0, bytes.Length);
  388. fs.Write(tag, 0, tag.Length);
  389. fs.Close();
  390. }
  391. }
  392. else
  393. {
  394. File.AppendAllText(path, string.Format("{0}{1}", Encoding.Default.GetString(bytes), endTag), Encoding.Default);
  395. }
  396. }
  397. }
  398. #endregion
  399. #region 封装方法,方便调用。
  400. public static bool PrintWithCOM(string cmd, int port, bool isWriteLog)
  401. {
  402. PrinterType = DeviceType.COM;
  403. Port = port;
  404. IsWriteLog = isWriteLog;
  405. return PrintCommand(cmd);
  406. }
  407. public static bool PrintWithCOM(byte[] bytes, int port, bool isWriteLog, ProgrammingLanguage progLanguage)
  408. {
  409. PrinterType = DeviceType.COM;
  410. Port = port;
  411. IsWriteLog = isWriteLog;
  412. PrinterProgrammingLanguage = progLanguage;
  413. return PrintGraphics(bytes);
  414. }
  415. public static bool PrintWithLPT(string cmd, int port, bool isWriteLog)
  416. {
  417. PrinterType = DeviceType.LPT;
  418. Port = port;
  419. IsWriteLog = isWriteLog;
  420. return PrintCommand(cmd);
  421. }
  422. public static bool PrintWithLPT(byte[] bytes, int port, bool isWriteLog, ProgrammingLanguage progLanguage)
  423. {
  424. PrinterType = DeviceType.LPT;
  425. Port = port;
  426. IsWriteLog = isWriteLog;
  427. PrinterProgrammingLanguage = progLanguage;
  428. return PrintGraphics(bytes);
  429. }
  430. public static bool PrintWithDRV(string cmd, string printerName, bool isWriteLog)
  431. {
  432. PrinterType = DeviceType.DRV;
  433. PrinterName = printerName;
  434. IsWriteLog = isWriteLog;
  435. return PrintCommand(cmd);
  436. }
  437. public static bool PrintWithDRV(byte[] bytes, string printerName, bool isWriteLog, ProgrammingLanguage progLanguage)
  438. {
  439. PrinterType = DeviceType.DRV;
  440. PrinterName = printerName;
  441. IsWriteLog = isWriteLog;
  442. PrinterProgrammingLanguage = progLanguage;
  443. return PrintGraphics(bytes);
  444. }
  445. #endregion
  446. #region 打印ZPL、EPL指令
  447. public static bool PrintCommand(string cmd)
  448. {
  449. lock (SyncRoot)
  450. {
  451. bool result = false;
  452. try
  453. {
  454. switch (PrinterType)
  455. {
  456. case DeviceType.COM:
  457. result = comPrint(Encoding.Default.GetBytes(cmd));
  458. break;
  459. case DeviceType.LPT:
  460. result = lptPrint(Encoding.Default.GetBytes(cmd));
  461. break;
  462. case DeviceType.DRV:
  463. result = drvPrint(Encoding.Default.GetBytes(cmd));
  464. break;
  465. }
  466. if (!string.IsNullOrEmpty(cmd) && IsWriteLog)
  467. {
  468. WriteLog(cmd, LogType.Print);
  469. }
  470. }
  471. catch (Exception ex)
  472. {
  473. //记录日志
  474. if (IsWriteLog)
  475. {
  476. WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
  477. }
  478. }
  479. finally
  480. {
  481. GraphBuffer = new byte[0];
  482. }
  483. return result;
  484. }
  485. }
  486. #endregion
  487. #region 打印图像字节流
  488. public static bool PrintGraphics(byte[] graph)
  489. {
  490. lock (SyncRoot)
  491. {
  492. bool result = false;
  493. try
  494. {
  495. GraphBuffer = graph;
  496. byte[] cmdBytes = new byte[0];
  497. if (PrinterProgrammingLanguage == ProgrammingLanguage.ZPL)
  498. {
  499. cmdBytes = getZPLBytes();
  500. }
  501. if (PrinterProgrammingLanguage == ProgrammingLanguage.EPL)
  502. {
  503. cmdBytes = getEPLBytes();
  504. }
  505. switch (PrinterType)
  506. {
  507. case DeviceType.COM:
  508. result = comPrint(cmdBytes);
  509. break;
  510. case DeviceType.LPT:
  511. result = lptPrint(cmdBytes);
  512. break;
  513. case DeviceType.DRV:
  514. result = drvPrint(cmdBytes);
  515. break;
  516. }
  517. if (cmdBytes.Length > 0 && IsWriteLog)
  518. {
  519. WriteLog(cmdBytes, LogType.Print);
  520. }
  521. }
  522. catch (Exception ex)
  523. {
  524. //记录日志
  525. if (IsWriteLog)
  526. {
  527. WriteLog(string.Format("{0} => {1}\r\n{2}", DateTime.Now, ex.Message, ex), LogType.Error);
  528. }
  529. }
  530. finally
  531. {
  532. GraphBuffer = new byte[0];
  533. }
  534. return result;
  535. }
  536. }
  537. #endregion
  538. #region COM/LPT/DRV三种模式打印方法
  539. private static bool drvPrint(byte[] cmdBytes)
  540. {
  541. bool result = false;
  542. try
  543. {
  544. if (!string.IsNullOrEmpty(PrinterName))
  545. {
  546. result = SendBytesToPrinter(PrinterName, cmdBytes);
  547. }
  548. }
  549. catch (Exception ex)
  550. {
  551. throw ex;
  552. }
  553. return result;
  554. }
  555. private static bool comPrint(byte[] cmdBytes)
  556. {
  557. bool result = false;
  558. SerialPort com = new SerialPort(string.Format("{0}{1}", PrinterType, Port), 9600, Parity.None, 8, StopBits.One);
  559. try
  560. {
  561. com.Open();
  562. com.Write(cmdBytes, 0, cmdBytes.Length);
  563. result = true;
  564. }
  565. catch (Exception ex)
  566. {
  567. throw ex;
  568. }
  569. finally
  570. {
  571. if (com.IsOpen)
  572. {
  573. com.Close();
  574. }
  575. }
  576. return result;
  577. }
  578. private static bool lptPrint(byte[] cmdBytes)
  579. {
  580. bool result = false;
  581. FileStream fileStream = null;
  582. StreamWriter streamWriter = null;
  583. SafeFileHandle handle = null;
  584. try
  585. {
  586. handle = CreateFile(string.Format("{0}{1}", PrinterType, Port), GENERIC_WRITE, 0, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
  587. if (!handle.IsInvalid)
  588. {
  589. fileStream = new FileStream(handle, FileAccess.ReadWrite);
  590. streamWriter = new StreamWriter(fileStream, Encoding.Default);
  591. streamWriter.Write(cmdBytes);
  592. result = true;
  593. }
  594. }
  595. catch (Exception ex)
  596. {
  597. throw ex;
  598. }
  599. finally
  600. {
  601. if (fileStream != null)
  602. {
  603. fileStream.Close();
  604. fileStream = null;
  605. }
  606. if (streamWriter != null)
  607. {
  608. streamWriter.Close();
  609. streamWriter = null;
  610. }
  611. if (handle != null)
  612. {
  613. handle.Close();
  614. handle = null;
  615. }
  616. }
  617. return result;
  618. }
  619. #endregion
  620. #region 生成ZPL图像打印指令
  621. private static byte[] getZPLBytes()
  622. {
  623. byte[] result = new byte[0];
  624. byte[] bmpData = getBitmapData();
  625. string textBitmap = string.Empty;
  626. string textHex = BitConverter.ToString(bmpData).Replace("-", string.Empty);
  627. for (int i = 0; i < GraphHeight;i++ )
  628. {
  629. textBitmap += textHex.Substring(i * RowRealBytesCount * 2, RowRealBytesCount * 2) + "\r\n";
  630. }
  631. 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",
  632. GraphHeight * RowRealBytesCount,
  633. RowRealBytesCount,
  634. textBitmap);
  635. result = Encoding.Default.GetBytes(text);
  636. return result;
  637. }
  638. #endregion
  639. #region 生成EPL图像打印指令
  640. private static byte[] getEPLBytes()
  641. {
  642. byte[] result = new byte[0];
  643. byte[] buffer = getBitmapData();
  644. string text = string.Format("N\r\nGW{0},{1},{2},{3},{4}\r\nP\r\n",
  645. 0,
  646. 0,
  647. RowRealBytesCount,
  648. GraphHeight,
  649. TransferFormat.GetString(buffer));
  650. result = TransferFormat.GetBytes(text);
  651. return result;
  652. }
  653. #endregion
  654. #region 获取单色位图数据
  655. /// <summary>
  656. /// 获取单色位图数据(1bpp),不含文件头、信息头、调色板三类数据。
  657. /// </summary>
  658. /// <returns></returns>
  659. private static byte[] getBitmapData()
  660. {
  661. MemoryStream srcStream = new MemoryStream();
  662. MemoryStream dstStream = new MemoryStream();
  663. Bitmap srcBmp = null;
  664. Bitmap dstBmp = null;
  665. byte[] srcBuffer = null;
  666. byte[] dstBuffer = null;
  667. byte[] result = null;
  668. try
  669. {
  670. srcStream = new MemoryStream(GraphBuffer);
  671. srcBmp = Bitmap.FromStream(srcStream) as Bitmap;
  672. srcBuffer = srcStream.ToArray();
  673. GraphWidth = srcBmp.Width;
  674. GraphHeight = srcBmp.Height;
  675. dstBmp = srcBmp.Clone(new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), PixelFormat.Format1bppIndexed);
  676. dstBmp.Save(dstStream, ImageFormat.Bmp);
  677. dstBuffer = dstStream.ToArray();
  678. int bfSize = BitConverter.ToInt32(dstBuffer, 2);
  679. int bfOffBits = BitConverter.ToInt32(dstBuffer, 10);
  680. int bitmapDataLength = bfSize - bfOffBits;
  681. result = new byte[GraphHeight * RowRealBytesCount];
  682. //读取时需要反向读取每行字节实现上下翻转的效果,打印机打印顺序需要这样读取。
  683. for (int i = 0; i < GraphHeight; i++)
  684. {
  685. Array.Copy(dstBuffer, bfOffBits + (GraphHeight - 1 - i) * RowSize, result, i * RowRealBytesCount, RowRealBytesCount);
  686. }
  687. }
  688. catch (Exception ex)
  689. {
  690. throw ex;
  691. }
  692. finally
  693. {
  694. if (srcStream != null)
  695. {
  696. srcStream.Dispose();
  697. srcStream = null;
  698. }
  699. if (dstStream != null)
  700. {
  701. dstStream.Dispose();
  702. dstStream = null;
  703. }
  704. if (srcBmp != null)
  705. {
  706. srcBmp.Dispose();
  707. srcBmp = null;
  708. }
  709. if (dstBmp != null)
  710. {
  711. dstBmp.Dispose();
  712. dstBmp = null;
  713. }
  714. }
  715. return result;
  716. }
  717. #endregion
  718. }
  719. #endregion
  720. }

如何获取标签设计软件输出至打印的ZPL指令?

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

C#调用斑马打印机打印条码标签(支持COM/LPT/USB/ZPL/EPL/Bitmap)相关推荐

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

    在批量打印商品标签时一般都要加上条码或图片,而这类应用大多是使用斑马打印机,所以我也遇到了怎么打印的问题. 一种办法是用标签设计软件做好模板,在标签设计软件中打印,这种办法不用写代码,但对我来说觉得不 ...

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

    在批量打印商品标签时一般都要加上条码或图片,而这类应用大多是使用斑马打印机,所以我也遇到了怎么打印的问题. 一种办法是用标签设计软件做好模板,在标签设计软件中打印,这种办法不用写代码,但对我来说觉得不 ...

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

    原文地址:http://blog.csdn.net/ldljlq/article/details/7338772 在批量打印商品标签时一般都要加上条码或图片,而这类应用大多是使用斑马打印机,所以我也遇 ...

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

    在批量打印商品标签时一般都要加上条码或图片,而这类应用大多是使用斑马打印机,所以我也遇到了怎么打印的问题. 一种办法是用标签设计软件做好模板,在标签设计软件中打印,这种办法不用写代码,但对我来说觉得不 ...

  5. 调用斑马打印机实现标签打印

    Java 调用斑马打印机实现标签打印 代码实现 最近的一个项目中,需要实现java调用斑马的打印机实现标签打印功能,百度了一些资源,找了不少人搞了一台快报废的斑马105SL 300DPI打印机,分分钟 ...

  6. 【求助】关于.NET(C#)调用斑马打印机(ZDesigner GK888t (EPL))换页时退纸的问题

    有解决过类似问题的大神请留步,救救我吧. -------分割------- 最近在做一个快递标签打印系统,使用.NET(C#)调用斑马打印机[ZDesigner GK888t (EPL)]进行打印,程 ...

  7. 斑马打印机打印不出来字怎么解决

    在条码打印软件中制作标签的时候,有的时候标签内容比较多,可能不注意就在标签上或者数据源中添加了一个空对象,也没预览,就直接连接斑马打印机进行打印了.最后发现,点击打印之后,斑马打印机没反应,咨询是怎么 ...

  8. 斑马打印机打印中文乱码的问题

    斑马打印机打印中文乱码的问题 前些天公司有需求需要使用web打印,咱也没弄过也没接触过呀,这种情况只能上官网看看了,因为我是用的是java环境,所以以下只介绍在java环境下解决的办法.这需要下载开发 ...

  9. PHP\Java\C#\Js\Go\Python调用小票打印机打印订单实现

    优声云打印机U7是成都优声科技有限公司推出的一款WIFI.4G联网的打印机.注意这是一款热敏58mm小票打印机,就是大家购物,外卖那样的收银小票. 在原来的小票打印机世界里,通常都是U口和蓝牙,更高级 ...

最新文章

  1. 阿里云API网关(14)流控策略
  2. stm32f103rb升级到stm32f103rc时代码移植注意事项
  3. CG CTF WEB MYSQL
  4. 微博polg什么意思_成都网站代运营是什么意思?-建站
  5. 动态规划训练20 [Treats for the Cows POJ - 3186 ]
  6. python元组取值_Python基础之元组
  7. 【转】DBMS_STATS.GATHER_TABLE_STATS详解
  8. 智能会议系统(15)--- linphone-android 业务流程
  9. thinkphp5 异步调用方法_详解thinkphp5+swoole实现异步邮件群发(SMTP方式)
  10. Atitit glb 1tie 2tie city lst 一二线城市列表数据约50个一线城市Alpha ++ 阿尔法++,,London 伦敦,,New York 纽约,,Alpha +
  11. 智慧城管核心应用系统建设
  12. J2Cache+Spring注入配置参数,无需读取固定路径下的j2cache.properties配置文件
  13. 复杂性应对之道 - 领域建模
  14. 计算机网络密码用户名是什么,宽带连接的用户名和密码是什么
  15. 结果导向的前提是过程控制
  16. 【论文泛读18】利用BERT进行端到端面向方面的情感分析
  17. matlab求解微分方程解析解
  18. 在 Flutter 中自定义画笔 Painter
  19. rman备份指定备份集对应文件
  20. 基于C++的医院管理系统设计与实现

热门文章

  1. 虚拟服务器端口211,双路由器要这样映射-路由器设置端口映射
  2. 向 Oracle 数据库添加 ST_Geometry 类型
  3. html输入页码跳转,WordPress分页导航添加输入页码跳转功能
  4. 2021年R1快开门式压力容器操作最新解析及R1快开门式压力容器操作证考试
  5. 用JavaScript canvas做的走迷宫游戏,肝了一下午,请帮忙点个赞!
  6. 交换机日志删除_锐捷交换机如何删除日志
  7. [Swift A] - 实战-豆瓣电台总结
  8. LeetCode225. Implement Stack using Queues
  9. P问题、NP问题、NPC问题的概念及实例证明
  10. 用大顶堆取出一个数组中最小的k个数