c# 小票打印功能

时间:2021-07-16 01:00:40
using System;
using System.Collections.Generic;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;

namespace PrintCore
{
    public static class PrintQueueHelper
    {
        public static IEnumerable<PrintQueue> GetPrintQueue()
        {
            var localPrintServer = new LocalPrintServer();
            var printQueues = localPrintServer.GetPrintQueues().GetEnumerator();
            while (printQueues.MoveNext())
            {
                yield return printQueues.Current;
            }

        }

        public static IEnumerable<string> GetPrintQueueName()
        {
            return GetPrintQueue().Select(s => s.Name);
        }
    }
}
c# 小票打印功能c# 小票打印功能
using Huanent.Printer.Models;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.Text;
using System.Linq;

namespace PrintCore
{
    public class Printer : IPrinter
    {

        #region fields
        PrintDocument _printDoc = new PrintDocument();

        /// <summary>
        /// 打印对象打印宽度(根据英寸换算而来,paperWidth * 3.937)
        /// </summary>
        readonly int _paperWidth;
        const float _charProportion = 0.7352f;
        const float _lineHeightProportion = 1.6f;
        const string _fontName = "SimHei";

        IList<Action<Graphics>> _printActions = new List<Action<Graphics>>();

        /// <summary>
        /// 当前的打印高度,当调用换行或者图片打印时会增加此字段值
        /// </summary>
        float _currentheight = 0;

        float NewLineOffset { get; set; } // = (int)FontSize.Normal * _lineHeightProportion;

        #endregion

        #region ctor

        /// <summary>
        /// 初始化机打印对象
        /// </summary>
        /// <param name="PrinterName">打印机名称</param>
        /// <param name="paperWidth">打印纸宽度</param>
        /// <param name="paperHight">打印纸高度</param>
        internal Printer(string PrinterName, double paperWidth, int paperHight)
        {
            //3.937为一个打印单位(打印单位:80(实际宽度72.1),58(实际宽度48))
            _paperWidth = Convert.ToInt32(Math.Ceiling(paperWidth * 3.937));
            _printDoc.PrinterSettings.PrinterName = PrinterName;
            _printDoc.PrintPage += PrintPageDetails;
            _printDoc.DefaultPageSettings.PaperSize = new PaperSize("", _paperWidth, paperHight);
            _printDoc.PrintController = new StandardPrintController();
        }


        #endregion

        #region eventHandler
        void PrintPageDetails(object sender, PrintPageEventArgs e)
        {
            foreach (var item in _printActions)
            {
                item(e.Graphics);
            }
        }
        #endregion

        #region IPrinterImplement
        public void NewRow()
        {
            _printActions.Add((g) =>
            {
                _currentheight += NewLineOffset;
                NewLineOffset = (int)FontSize.Normal * _lineHeightProportion;
            });
        }

        public void PrintText(string content, FontSize fontSize = FontSize.Normal, StringAlignment stringAlignment = StringAlignment.Near, float width = 1, float offset = 0)
        {
            int rowNum = 0;
            _printActions.Add((g) =>
            {
                float contentWidth = width == 1 ? _paperWidth * (1 - offset) : width * _paperWidth;
                string newContent = ContentWarp(content, fontSize, contentWidth, out rowNum);
                var font = new Font(_fontName, (int)fontSize, FontStyle.Regular);
                var point = new PointF(offset * _paperWidth, _currentheight);
                var size = new SizeF(contentWidth, (int)fontSize * _lineHeightProportion * rowNum);
                var layoutRectangle = new RectangleF(point, size);
                var format = new StringFormat
                {
                    Alignment = stringAlignment,
                    FormatFlags = StringFormatFlags.NoWrap
                };
                g.DrawString(newContent, font, Brushes.Black, layoutRectangle, format);
                float thisHeightOffset = rowNum * (int)fontSize * _lineHeightProportion;
                if (thisHeightOffset > NewLineOffset) NewLineOffset = thisHeightOffset;
            });
        }

        public void Finish()
        {
            _printDoc.Print();
            _printDoc.Dispose();
            _printDoc = new PrintDocument();
            _printActions.Clear();
        }

        public void PrintImage(Image image, StringAlignment stringAlignment = StringAlignment.Near)
        {
            _printActions.Add((g) =>
            {
                int x = 0;
                switch (stringAlignment)
                {
                    case StringAlignment.Near:
                        break;
                    case StringAlignment.Center:
                        x = (_paperWidth - image.Width) / 2;
                        break;
                    case StringAlignment.Far:
                        x = _paperWidth - image.Width;
                        break;
                    default:
                        break;
                }
                var point = new Point(x, Convert.ToInt32(_currentheight));
                var size = new Size(image.Width, image.Height);
                var rectangle = new Rectangle(point, size);
                g.DrawImage(image, rectangle);
                NewLineOffset = image.Height;
            });
        }

        public void PrintLine(FontSize fontSize = FontSize.Normal)
        {
            int charNum = (int)(_paperWidth / ((int)fontSize * _charProportion));
            var builder = new StringBuilder();
            for (int i = 0; i < charNum; i++)
            {
                builder.Append('-');
            }
            PrintText(builder.ToString(), fontSize, StringAlignment.Center);
        }
        #endregion

        #region methods
        /// <summary>
        /// 对内容进行分行,并返回行数
        /// </summary>
        /// <param name="content">内容</param>
        /// <param name="fontSize">文字大小</param>
        /// <param name="width">内容区宽度</param>
        /// <returns>行数</returns>
        static string ContentWarp(string content, FontSize fontSize, float width, out int row)
        {
            content = content.Replace(Environment.NewLine, string.Empty);

            //0.7282 字符比例
            var builder = new StringBuilder();
            float nowWidth = 0;
            row = 1;
            foreach (char item in content)
            {
                int code = Convert.ToInt32(item);
                float charWidth = code < 128 ? _charProportion * (int)fontSize : _charProportion * (int)fontSize * 2;
                nowWidth += charWidth;
                if (nowWidth > width)
                {
                    builder.Append(Environment.NewLine);
                    nowWidth = charWidth;
                    row++;
                }
                builder.Append(item);
            }
            return builder.ToString();
        }

        #endregion
    }

}
View Code
c# 小票打印功能c# 小票打印功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Huanent.Printer.Models
{
    public enum FontSize
    {
        micro = 4,
        Small = 6,
        Normal = 10,
        Large = 14,
        Huge = 16
    }
}
View Code
c# 小票打印功能c# 小票打印功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrintCore
{
    public enum PaperWidth
    {
        /// <summary>
        /// 80mm
        /// </summary>
        Paper80mm = 80,
        /// <summary>
        /// 76mm
        /// </summary>
        Paper76mm = 76,
        /// <summary>
        /// 58mm
        /// </summary>
        Paper58mm = 58
    }
}
View Code
using Huanent.Printer.Models;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace PrintCore
{
    public interface IPrinter
    {
        void PrintText(
            string content,
            FontSize fontSize = FontSize.Normal,
            StringAlignment stringAlignment = StringAlignment.Near,
            float width = 1,
            float offset = 0
            );

        void PrintImage(
            Image image,
            StringAlignment stringAlignment = StringAlignment.Near);

        void PrintLine(FontSize fontSize = FontSize.Normal);

        void NewRow();

        /// <summary>
        /// invoke this method when you ready to print document
        /// </summary>
        void Finish();
    }
}
c# 小票打印功能c# 小票打印功能
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrintCore
{
    public static class PrinterFactory
    {
        public static Printer GetPrinter(string printerName, double paperWidth, int? pagerHeight = null)
        {
            //if (string.IsNullOrEmpty(printerName)) throw new ArgumentException(nameof(printerName));
            return new Printer(printerName, paperWidth, pagerHeight ?? 10000);
        }

        public static Printer GetPrinter(string printerName, PaperWidth paperWidth, int? pagerHeight = null)
        {
            switch (paperWidth)
            {
                case PaperWidth.Paper80mm:
                    //80打印纸扣去两边内距实际可打的宽度为72.1
                    return GetPrinter(printerName, 72.1, pagerHeight);
                case PaperWidth.Paper76mm:
                    //76打印纸扣去两边内距实际可打的宽度为63.5
                    return GetPrinter(printerName, 63.5, pagerHeight);
                case PaperWidth.Paper58mm:
                    //58打印纸扣去两边内距实际可打的宽度为48
                    return GetPrinter(printerName, 48, pagerHeight);
                default:
                    //throw new ArgumentException(nameof(paperWidth));
                    throw new Exception("error");
            }

        }
    }
}
View Code