C#直接发送打印机命令到打印机及ZPL常用打印命令 - 条码打印机

本文介绍了如何使用C#直接发送打印机命令,特别是针对条码打印机的ZPL语言进行详细讲解。MSCL超级工具类库为开发者提供了便捷的C#工具类,涵盖数据库操作、字符串处理、网络请求等多个领域,旨在提升编程效率和质量。通过提供的CHM文档和示例,开发者可以快速掌握并应用到实际项目中。
部署运行你感兴趣的模型镜像
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命令打印右侧. 
例如:
^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();
        } 

MSCL超级工具类库
基于C#开发的超强工具类,包含数据库操作,字符串处理,文件或者文件夹处理
网络请求,缓存处理,数据容器等上百个常用工具类封装,附带调用示例和参数说明,
提供CHM详细文档,上百个生产环境使用,稳定高效,简单易用。
真正做到“工具在手,一切尽有”,让你大幅度的提高编程效率,提高编程水平。
联系QQ:7400799(请备注 "MSCL")

 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

SmartPrinter 一款大家非常熟悉的经典产品,专为转换文件而研发的高品质打印驱动,以运行稳定、转换速度快和图像质量高而著称,通过虚拟打印技术可以完美的将任意可打印文档转换成 PDF、TIFF、JPEG,BMP、PNG、GIF、TXT格式。 1:手动转换 产品安装后系统会生成一个打印机 SmartPrinter ,将需要转换的文件打印到此打印机即可完成转换。 2:后台自动转换(使用文档转换通用接口 API 方式) 支持文件转换通用接口: ConvertAgent API。 只需几行代码更可在后台完全繁琐的转换工作,文件转换过程中让您体验其难以想像的速度。 强烈推荐:各类文档转换服务器或传真服务器,对打印速度和图象质量要求极高的场合下使用! 二. 安装包含主要内容 1:SmartPrinter (虚拟打印机) 2: ConvertAgent API Dll (文档转换接口 API) 3: ConvertAgent COM Interface (Easy use in .net C# or VB ) 4: PrinterSettings API Dll (打印机参数设置接口 API) (免费) 5: PrinterSettings COM Interface (Easy use in .net C# or VB ) (免费) 6: ConvertAgent API 和 PrinterSettings API 接口说明文档 参见 COM-Interface & C++ Library Interface.doc 7: Sample Code 三. SmartPrinter & COM Interface 安装方法 1: 运行 InstallPrinter.bat 安装虚拟打印机 (使用安装包安装可忽略此步骤)。 2: 运行 PrinterTools 管理打印机。 2: 运行 ConvertAgentDemo.exe 测试打印机 和 文档转换接口ConvertAgent API。 四. SDK Sample code 1: ConvertAgent Sample: (文档转换接口 API) VC++Sample: SmartPrinter\SDK Examples\VC++\ConvertAgentDemo VB COM Sample: SmartPrinter\ VB.NET(COM)\ConvertAgentDemo C# COM Sample: SmartPrinter\ C#.NET(COM) \ConvertAgentDemo 2: PrinterSettings Sample:(打印机参数设置接口 API) C++Sample: SmartPrinter\SDK Examples\VC++\PrinterSettings C# COM Sample: SmartPrinter\ C#.NET(COM) \ PrinterSettings 五.输入和输出 Smart Printer 输入: 虚拟打印机输入格式不限制,只要可以打印的文件便可以作为输入格式。 SmartPrinter 输出: 支持 PDF、TIFF、JPEG,BMP、PNG、GIF、TXT 最常用的格式。 ConvertAgent API 输入: 目前版本转换支持的输入格式 1: MS Office 系列 *.doc (Word 文件), *.xlw, *.xlc, *.xls (Excel 文件) , *.pps ,*.ppt (Power Point 文件),*.vsd (Visio 绘图文件) 2: WPS 系列 wps (wps 文字文件), et (wps 表格文件), ppt (wps 演示文件) 3: Acrobat 系列 pdf( Adobe PDF文件) 4: 图象格式系列 *.bmp , *.png , (*.tif) tiff , *.gif , *.jpg 5: 文本格式 系列 *.txt 文件 ,*.rtf 文件,*.log 文件 6: Auto CAD 文件 dwg文件 7: 其它格式 htm 文件, xml , *.shtm 文件,*.shtml 文件 ConvertAgent API 输出: 依赖你使用的打印机, ( InitAgent 函数的 PrinterName参数指出打印机名称) 六. 系统支持 Windows 2000、Windows XP、Windows 2003、Windows Vista、Windows 7 support@i-enet.com 电话: 021-58552860 网址:http://www.i-enet.com/ 逸铭软件
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

smartsmile2012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值