using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace BarCodeLibrary { public class ZebraGesigner { [StructLayout(LayoutKind.Sequential)] private struct OVERLAPPED { int Internal; int InternalHigh; int Offset; int OffSetHigh; int hEvent; } [DllImport("kernel32.dll")] private static extern int CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile); [DllImport("kernel32.dll")] private static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWriter, out int lpNumberOfBytesWriten, out OVERLAPPED lpOverLapped); [DllImport("kernel32.dll")] private static extern bool CloseHandle(int hObject); [DllImport("fnthex32.dll")] public static extern int GETFONTHEX(string barcodeText,string fontName,int orient,int height,int width,int isBold,int isItalic,StringBuilder returnBarcodeCMD); private int iHandle; //打開LPT 端口 public bool Open() { iHandle = CreateFile("lpt1", 0x40000000, 0, 0, 3, 0, 0); if (iHandle != -1) { return true; } else { return false; } } //打印函數,參數為打印機的命令或者其他文本! public bool Write(string MyString) { if (iHandle != -1) { int i; OVERLAPPED x; byte[] mybyte = System.Text.Encoding.Default.GetBytes(MyString); return WriteFile(iHandle, mybyte, mybyte.Length, out i, out x); } else { throw new Exception("端口未打開~!"); } } //關閉打印端口 public bool Close() { return CloseHandle(iHandle); } } }
vate void button1_Click(object sender, EventArgs e) { ZebraGesigner zb = new ZebraGesigner(); string mycommanglines = System.IO.File.ReadAllText("print.txt");//print.txt里寫了條碼機的命令 zb.Open(); zb.Write(mycommanglines); zb.Close(); }
/* ^XA ^XA指令塊的開始 ^MD30 ^MD是設置色帶顏色的深度,取值范圍從-30到30,上面的示意指令將顏色調到了最深. ^LH60,10 ^LH是設置條碼紙的邊距的,這個東西在實際操作上來回試幾次即可. ^FO20,10 ^FO是設置條碼左上角的位置的,這個對程序員應該很容易理解. 0,0代表完全不留邊距. ^ACN,18,10 ^ACN是設置字體的.因為在條碼下方會顯示該條碼的內容,所以要設一下字體.這個跟條碼無關. ^BY1.4,3,50 ^BY是設置條碼樣式的,1.4是條碼的縮放級別,3是條碼中粗細柱的比例,50是條碼高度. ^BCN,,Y,N ^BC是打印code128的指令,具體參數詳見ZPL的說明書(百度雲盤) ^FD01008D004Q-0^FS ^FD設置要打印的內容, ^FS表示換行. ^XZ ^XZ指令塊的開始 */ StringBuilder builder = new StringBuilder(); builder.AppendLine("^XA"); builder.AppendLine("^MD30"); builder.AppendLine("^LH60,10"); builder.AppendLine("^FO20,10"); builder.AppendLine("^ACN,18,10"); builder.AppendLine("^BY1.4,3,50"); builder.AppendLine("^BCN,,Y,N"); builder.AppendLine("^FD01008D004Q-0^FS"); builder.AppendLine("^XZ");
在實踐中, 常常會需要一次橫打兩張, 其實可以把一排的兩張想像成一張, 連續執行兩個打印命令, 把第二個FO的橫坐標設置得大一些就行了.
例如:
^XA
^FO20,10
^FD001^FS
^FO60,10
^FD002^FS
^XZ
第一對FO/FD命令打印左側, 第二對FO/FD命令打印右側.
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using System.Drawing.Printing; using System.Windows.Forms; using System.Runtime.InteropServices; namespace ZPLPrinter { class RawPrinterHelper { // Structure and API declarions: [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] public class DOCINFOA { [MarshalAs(UnmanagedType.LPStr)] public string pDocName; [MarshalAs(UnmanagedType.LPStr)] public string pOutputFile; [MarshalAs(UnmanagedType.LPStr)] public string pDataType; } [DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); // SendBytesToPrinter() // When the function is given a printer name and an unmanaged array // of bytes, the function sends those bytes to the print queue. // Returns true on success, false on failure. public static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount) { Int32 dwError = 0, dwWritten = 0; IntPtr hPrinter = new IntPtr(0); DOCINFOA di = new DOCINFOA(); bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = "My C#.NET RAW Document"; di.pDataType = "RAW"; // Open the printer. if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero)) { // Start a document. if (StartDocPrinter(hPrinter, 1, di)) { // Start a page. if (StartPagePrinter(hPrinter)) { // Write your bytes. bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten); EndPagePrinter(hPrinter); } EndDocPrinter(hPrinter); } ClosePrinter(hPrinter); } // If you did not succeed, GetLastError may give more information // about why not. if (bSuccess == false) { dwError = Marshal.GetLastWin32Error(); } return bSuccess; } public static bool SendFileToPrinter(string szPrinterName, string szFileName) { // Open the file. FileStream fs = new FileStream(szFileName, FileMode.Open); // Create a BinaryReader on the file. BinaryReader br = new BinaryReader(fs); // Dim an array of bytes big enough to hold the file's contents. Byte[] bytes = new Byte[fs.Length]; bool bSuccess = false; // Your unmanaged pointer. IntPtr pUnmanagedBytes = new IntPtr(0); int nLength; nLength = Convert.ToInt32(fs.Length); // Read the contents of the file into the array. bytes = br.ReadBytes(nLength); // Allocate some unmanaged memory for those bytes. pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength); // Copy the managed byte array into the unmanaged array. Marshal.Copy(bytes, 0, pUnmanagedBytes, nLength); // Send the unmanaged bytes to the printer. bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength); // Free the unmanaged memory that you allocated earlier. Marshal.FreeCoTaskMem(pUnmanagedBytes); return bSuccess; } public static bool SendStringToPrinter(string szPrinterName, string szString) { IntPtr pBytes; Int32 dwCount; // How many characters are in the string? dwCount = szString.Length; // Assume that the printer is expecting ANSI text, and then convert // the string to ANSI text. pBytes = Marshal.StringToCoTaskMemAnsi(szString); // Send the converted ANSI string to the printer. SendBytesToPrinter(szPrinterName, pBytes, dwCount); Marshal.FreeCoTaskMem(pBytes); return true; } } }
public string Print(string stuNo, string liuBookNo, string suoBookNum, string stuName) { if (string.IsNullOrEmpty(liuBookNo) || string.IsNullOrEmpty(suoBookNum)) { return "參數錯誤,打印失敗!"; } StringBuilder tiaomaStr = new StringBuilder(); tiaomaStr.AppendLine(); tiaomaStr.AppendLine("N"); tiaomaStr.AppendLine("B0,10,0,1,2,3,100,B,$" + suoBookNum + "$"); tiaomaStr.AppendLine("A2050,10,5,9,1,1,N,$" + liuBookNo + "$"); tiaomaStr.AppendLine("A0,160,0,8,1,1,N,$未知$"); tiaomaStr.AppendLine("A0,210,0,8,1,1,N,$捐書人:" + stuName + "$"); tiaomaStr.AppendLine("D15"); tiaomaStr.AppendLine("P1"); FileStream fs = null; try { string path = Server.MapPath("~/BooksManagement\\File\\tiaoma.txt"); fs = new FileStream(path, FileMode.Create, FileAccess.Write); StreamWriter sw = new StreamWriter(fs, Encoding.Default);//ANSI編碼格式 if (File.Exists(path)) { sw.Write(tiaomaStr.ToString().Replace('$', '"')); tiaomaStr.Clear(); sw.Flush(); sw.Close(); if (RunCmd("COPY " + path + " LPT1")) return string.Empty; else return "參數錯誤,打印失敗!"; } } catch { } finally { fs.Close(); } return "參數錯誤,打印失敗!"; } private bool RunCmd(string command) { //實例一個Process類,啟動一個獨立進程 Process p = new Process(); //Process類有一個StartInfo屬性,這個是ProcessStartInfo類,包括了一些屬性和方法,下面我們用到了他的幾個屬性: p.StartInfo.FileName = "cmd.exe";//設定程序名 p.StartInfo.Arguments = "/c " + command;//設定程式執行參數 p.StartInfo.UseShellExecute = false;//關閉Shell的使用 p.StartInfo.RedirectStandardInput = true;//重定向標准輸入 p.StartInfo.RedirectStandardOutput = true;//重定向標准輸出 p.StartInfo.RedirectStandardError = true;//重定向錯誤輸出 p.StartInfo.CreateNoWindow = true;//設置不顯示窗口 //p.StandardInput.WriteLine(command);//也可以用這種方式輸入要執行的命令 //p.StandardInput.WriteLine("exit");//不過要記得加上Exit要不然下一行程式執行的時候會當機 try { p.Start();//開始進程 return true; } catch { } finally { if (p != null) p.Close(); } return false; }
/* 中文或其它復雜設計成圖片,然后用ZPL命令發送給條碼打印機打印 //定義字體 Font drawFont = new Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Millimeter); //生成圖片 Bitmap img = CreateImage("出廠日期:" + DateTime.Now, drawFont); var imgCode = ConvertImageToCode(img); var t = ((img.Size.Width / 8 + ((img.Size.Width % 8 == 0) ? 0 : 1)) * img.Size.Height).ToString(); //圖形中的總字節數 var w = (img.Size.Width / 8 + ((img.Size.Width % 8 == 0) ? 0 : 1)).ToString(); //每行的字節數 string zpl = string.Format("~DGR:imgName.GRF,{0},{1},{2}", t, w, imgCode); //發送給打印機 */ /// <summary> /// 生成Bitmap /// </summary> /// <param name="data">字符串</param> /// <param name="f">文本格式</param> /// <returns></returns> protected Bitmap CreateImage(string data, Font f) { if (string.IsNullOrEmpty(data)) return null; var txt = new TextBox(); txt.Text = data; txt.Font = f; //txt.PreferredSize.Height只能取到一行的高度(連邊距) //所以需要乘以行數, 但是必須先減掉邊距, 乘了以后,再把邊距加上. //5是目測的邊距 var image = new Bitmap(txt.PreferredSize.Width, (txt.PreferredSize.Height - 5) * txt.Lines.Length + 5); var g = Graphics.FromImage(image); var b = new System.Drawing.Drawing2D.LinearGradientBrush(new Rectangle(0, 0, image.Width, image.Height), Color.Black, Color.Black, 1.2f, true); g.Clear(System.Drawing.Color.White); g.DrawString(data, f, b, 1, 1); return image; } /// <summary> /// 序列化圖片 /// </summary> /// <param name="img">Bitmap</param> /// <returns></returns> protected string ConvertImageToCode(Bitmap img) { var sb = new StringBuilder(); long clr = 0, n = 0; int b = 0; for (int i = 0; i < img.Size.Height; i++) { for (int j = 0; j < img.Size.Width; j++) { b = b * 2; clr = img.GetPixel(j, i).ToArgb(); string s = clr.ToString("X"); if (s.Substring(s.Length - 6, 6).CompareTo("BBBBBB") < 0) { b++; } n++; if (j == (img.Size.Width - 1)) { if (n < 8) { b = b * (2 ^ (8 - (int)n)); sb.Append(b.ToString("X").PadLeft(2, '0')); b = 0; n = 0; } } if (n >= 8) { sb.Append(b.ToString("X").PadLeft(2, '0')); b = 0; n = 0; } } sb.Append(System.Environment.NewLine); } return sb.ToString(); }
本文引自:http://blog.csdn.net/smartsmile2012/article/details/22181101