zoukankan      html  css  js  c++  java
  • c# 小票打印

    c# 在进行小票打印时大致有三种方法。

    1. 使用水晶报表进行打印。可以参考:https://www.cnblogs.com/aitong/p/10717786.html

    2. 在 PrintDocument 对象上进行绘图,然后使用其打印方法直接打印。

    using CrystalDecisions.CrystalReports.Engine;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Printing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    namespace CrTest
    {
        public partial class Form1 : Form
        {
            string title = "标题标题标题标题标题标题标题标题标题标题标题";
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                //打印预览            
                PrintPreviewDialog ppd = new PrintPreviewDialog();
                PrintDocument pd = new PrintDocument();
                //设置边距
                Margins margin = new Margins(10, 10, 10, 10);
                pd.DefaultPageSettings.Margins = margin;
                int height = 30;
                if (title.Length > 13)
                {
                    height = 60;
                }
                //纸张设置默认
                PaperSize pageSize = new PaperSize("First custom size", (int)(58 * 100 / 25.4), height);//58mm   转绘图宽度
                pd.DefaultPageSettings.PaperSize = pageSize;
                //打印事件设置            
                pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
                ppd.Document = pd;
                ppd.ShowDialog();
                //try
                //{
                //    pd.Print();
                //}
                //catch (Exception ex)
                //{
                //    MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                //    pd.PrintController.OnEndPrint(pd, new PrintEventArgs());
                //}
            }
    
            private void pd_PrintPage(object sender, PrintPageEventArgs e)
            {
                Font font = new Font("Arial", 10, System.Drawing.FontStyle.Regular);
                string text = title;
                int yLocation = e.MarginBounds.Y;
                int center = e.PageSettings.PaperSize.Width / 2 ;
                int heightStep = 0;
                while (text.Length > 0)
                {
                    string printStr;
                    if (text.Length > 13)
                    {
                        printStr = text.Substring(0, 13);
                        text = text.Substring(13);
                    }
                    else
                    {
                        printStr = text;
                        text = "";
                    }
                    SizeF size = e.Graphics.MeasureString(printStr, font);
                    heightStep =Convert.ToInt32( size.Height * 1.3);
                    e.Graphics.DrawString(printStr, font, System.Drawing.Brushes.Black, center - size.Width / 2, yLocation);
                    yLocation += heightStep;
                }
            }
        }
    }

    3. 使用 ESC/POS 控制指令

    注意 SendStringToPrinter 这个接口。

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.IO;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    //https://www.cnblogs.com/QiuTianBaBa/p/6730829.html
    //https://blog.csdn.net/andrewniu/article/details/80353655
    namespace Evet2Basic.Model.Print.Report
    {
        public class RawPrint
        {
            // 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.
            private 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 = "XiaoPiao";
                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;
            }
    
            private 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 SendBytesToPrinter(string szPrinterName, byte[] buf)
            {
                bool bSuccess = false;
                // Your unmanaged pointer.
                IntPtr pUnmanagedBytes = new IntPtr(0);
                // Allocate some unmanaged memory for those bytes.
                pUnmanagedBytes = Marshal.AllocCoTaskMem(buf.Length);
                // Copy the managed byte array into the unmanaged array.
                Marshal.Copy(buf, 0, pUnmanagedBytes, buf.Length);
                // Send the unmanaged bytes to the printer.
                bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, buf.Length);
                // Free the unmanaged memory that you allocated earlier.
                Marshal.FreeCoTaskMem(pUnmanagedBytes);
                return bSuccess;
            }
    
            /// <summary>
            /// 切纸
            /// </summary>
            /// <param name="szPrinterName">打印机名</param>
            /// <returns></returns>
            public static bool Cut(string szPrinterName)
            {
                bool bSuccess = false;
    
                IntPtr pUnmanagedBytes = new IntPtr(0);
    
                byte[] data = new byte[] { 0x1B, 0x69 };
                pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length);
                Marshal.Copy(data, 0, pUnmanagedBytes, data.Length);
                bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, data.Length);
                Marshal.FreeCoTaskMem(pUnmanagedBytes);
                return true;
            }
    
    
            public static bool SendBytesToPrinterImg(string szPrinterName, Bitmap bmp, bool needWarning)
            {
                bool bSuccess = false;
    
                //Byte[] byte_send = Encoding.GetEncoding("GB2312").GetBytes("x1bx40");
                IntPtr pUnmanagedBytes = new IntPtr(0);
                //pUnmanagedBytes = Marshal.AllocCoTaskMem(byte_send.Length);
                //Marshal.Copy(byte_send, 0, pUnmanagedBytes, byte_send.Length);
                //bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, byte_send.Length);
                //Marshal.FreeCoTaskMem(pUnmanagedBytes);
    
                byte[] data = new byte[] { 0x1B, 0x33, 0x00 };
                //pUnmanagedBytes = new IntPtr(0);
                pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length);
                Marshal.Copy(data, 0, pUnmanagedBytes, data.Length);
                bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, data.Length);
                Marshal.FreeCoTaskMem(pUnmanagedBytes);
                data[0] = (byte)'x00';
                data[1] = (byte)'x00';
                data[2] = (byte)'x00';
    
                Color pixelColor;
    
                // ESC * m nL nH 点阵图  
                byte[] escBmp = new byte[] { 0x1B, 0x2A, 0x00, 0x00, 0x00 };
                escBmp[2] = (byte)'x21';
                //nL, nH  
                escBmp[3] = (byte)(bmp.Width % 256);
                escBmp[4] = (byte)(bmp.Width / 256);
    
                // data  
                for (int i = 0; i < (bmp.Height / 24) + 1; i++)
                {
                    //pUnmanagedBytes = new IntPtr(0);
                    pUnmanagedBytes = Marshal.AllocCoTaskMem(escBmp.Length);
                    Marshal.Copy(escBmp, 0, pUnmanagedBytes, escBmp.Length);
                    bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, escBmp.Length);
                    Marshal.FreeCoTaskMem(pUnmanagedBytes);
    
                    byte[] temptype = new byte[bmp.Width * 3];
                    int lengthNow = 0;
                    for (int j = 0; j < bmp.Width; j++)
                    {
                        for (int k = 0; k < 24; k++)
                        {
                            if (((i * 24) + k) < bmp.Height)   // if within the BMP size  
                            {
                                pixelColor = bmp.GetPixel(j, (i * 24) + k);
                                if (pixelColor.R == 0)
                                {
                                    data[k / 8] += (byte)(128 >> (k % 8));
                                }
                            }
                        }
                        data.CopyTo(temptype, lengthNow);
                        lengthNow += 3;
    
                        data[0] = (byte)'x00';
                        data[1] = (byte)'x00';
                        data[2] = (byte)'x00';
                    }
    
                    //pUnmanagedBytes = new IntPtr(0);
                    pUnmanagedBytes = Marshal.AllocCoTaskMem(temptype.Length);
                    Marshal.Copy(temptype, 0, pUnmanagedBytes, temptype.Length);
                    bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, temptype.Length);
                    Marshal.FreeCoTaskMem(pUnmanagedBytes);
                    System.Threading.Thread.Sleep(10);
                }
                byte[] dataClear = new byte[] { 0x1B, 0x40 };
                pUnmanagedBytes = Marshal.AllocCoTaskMem(dataClear.Length);
                Marshal.Copy(dataClear, 0, pUnmanagedBytes, dataClear.Length);
                bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, dataClear.Length);
                Marshal.FreeCoTaskMem(pUnmanagedBytes);
                return bSuccess;
            }
    
            public static bool SendStringToPrinter(string szPrinterName, string szString)
            {
                try
                {
                    //指令见打印机官方文档    http://www.xprinter.net/index.php/Server/index/cid/3
                    byte[] smallArray = new byte[] { 29, 33, 0 };
                    List<byte> list = new List<byte>();
    
                    list.AddRange(smallArray);
                    while (szString.Contains("<B>") || szString.Contains("<A>"))
                    {
                        if (!szString.Contains("<B>"))
                        {
                            ReplaceAB(ref szString, ref list, 2);
                        }
                        else if (!szString.Contains("<A>"))
                        {
                            ReplaceAB(ref szString, ref list, 3);
                        }
                        else
                        {
                            int indexA = szString.IndexOf("<A>");
                            int indexB = szString.IndexOf("<B>");
                            if (indexA < indexB)
                            {
                                ReplaceAB(ref szString, ref list, 2);
                            }
                            else
                            {
                                ReplaceAB(ref szString, ref list, 3);
                            }
                        }
                    }
                    Encoding enc = Encoding.GetEncoding("gb2312");
                    list.AddRange(enc.GetBytes(szString));
                    return RawPrint.SendBytesToPrinter(szPrinterName, list.ToArray());
                }
                catch (Exception)
                {
                    return false;
                }
            }
    
            private static void ReplaceAB(ref string szString, ref List<byte> list, int mul)
            {
                //指令见打印机官方文档    http://www.xprinter.net/index.php/Server/index/cid/3
                string replaceStr1 = "<B>";
                string replaceStr2 = "</B>";
                byte[] smallArray = new byte[] { 29, 33, 0 };
                byte[] bigArray = new byte[] { 29, 33, 34 };   //放大三倍    //29, 33字体放大指令  34放大倍数 ( 0一倍    17两倍   34三倍     51四倍    68五倍     85六倍)
                if (mul == 2)
                {
                    replaceStr1 = "<A>";
                    replaceStr2 = "</A>";
                    bigArray = new byte[] { 29, 33, 17 };   //放大两倍
                }
                Encoding enc = Encoding.GetEncoding("gb2312");
                int index = szString.IndexOf(replaceStr1);
                string first = szString.Substring(0, index);
                list.AddRange(enc.GetBytes(first));//第一段
                list.AddRange(bigArray);//变成大写
                szString = szString.Substring(index + 3);
                int index2 = szString.IndexOf(replaceStr2);
                string second = szString.Substring(0, index2);
                list.AddRange(enc.GetBytes(second));//大写段
                list.AddRange(smallArray);//变小写
                szString = szString.Substring(index2 + 4);
            }
        }
    }
  • 相关阅读:
    hdu4277 暴力
    hdu4271 Find Black Hand 2012长春网络赛E题 最短编辑距离
    poj3356 字符串的最小编辑距离 dp
    HDU4267 A Simple Problem with Integers 线段树/树状数组
    树链剖分 模版
    SPOJ375 Query on a tree 树链剖分
    Orz_panda cup I题 (xdoj1117) 状压dp
    27号的十道离线线段树
    The 2015 "Orz Panda" Cup Programming Contest
    codeforces #274 C. Riding in a Lift dp+前缀和优化
  • 原文地址:https://www.cnblogs.com/aitong/p/10730264.html
Copyright © 2011-2022 走看看