C#编程直接发送打印机命令到打印机及ZPL常用的打印命令详解
小标 2018-08-13 来源 : 阅读 5410 评论 0

摘要:本文主要向大家介绍了C#编程直接发送打印机命令到打印机及ZPL常用的打印命令详解,通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

本文主要向大家介绍了C#编程直接发送打印机命令到打印机及ZPL常用的打印命令详解,通过具体的内容向大家展示,希望对大家学习C#编程有所帮助。

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 name="f">文本格式

/// <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

/// <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();

}

   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C#.NET频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved