使用GDI画图片生成合成图片并调用打印机进行图片打印

使用GDI画图片生成合成图片并调用打印机进行图片打印

新建窗体应用程序PrinterDemo,将默认的Form1重命名为FormPrinter,添加对

Newtonsoft.Json.dll用于读写Json字符串

zxing.dll,zxing.presentation.dll用于生成条形码,二维码

三个类库的引用。

一、新建打印配置类PrintConfig:

PrintConfig.cs源程序为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrinterDemo
{
    /// <summary>
    /// 打印某一个矩形Rectangle的配置,所有文本,图片,条码都认为是一个矩形区域,由(x,y,width,height)组成
    /// </summary>
    public class PrintConfig
    {
        /// <summary>
        /// 打印的具体内容,条形码,二维码对应的字符串内容
        /// </summary>
        public string PrintMessage { get; set; }
        /// <summary>
        /// 打印的左上角X坐标,以像素为单位
        /// </summary>
        public int X { set; get; }
        /// <summary>
        /// 打印的左上角Y坐标,以像素为单位
        /// </summary>
        public int Y { set; get; }
        /// <summary>
        /// 宽度,以像素为单位
        /// </summary>
        public int Width { set; get; }
        /// <summary>
        /// 高度,以像素为单位
        /// </summary>
        public int Height { set; get; }

        /// <summary>
        /// 打印模式枚举:条形码,二维码,纯文本,图片【显示枚举类型为字符串,而不是整数】
        /// </summary>
        [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
        public PrintMode PrintMode { set; get; }
        /// <summary>
        /// 字体大小
        /// </summary>
        public float FontSize { set; get; }
        /// <summary>
        /// 图片路径,当打印模式为图片PrintMode.Image时有效,其他默认为空
        /// </summary>
        public string ImagePath { get; set; }
    }

    /// <summary>
    /// 打印模式枚举
    /// </summary>
    [Flags]
    public enum PrintMode
    {
        /// <summary>
        /// 条形码Code128
        /// </summary>
        Code128 = 1,
        /// <summary>
        /// 二维码QRCode
        /// </summary>
        QRCode = 2,
        /// <summary>
        /// 纯文本
        /// </summary>
        Text = 4,
        /// <summary>
        /// 图片
        /// </summary>
        Image = 8
    }
}

二、新建打印配置读写类CommonUtil

CommonUtil.cs源程序如下:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrinterDemo
{
    public class CommonUtil
    {
        /// <summary>
        /// 打印配置json文件路径
        /// </summary>
        private static string configJsonPath = AppDomain.CurrentDomain.BaseDirectory + "printConfig.json";

        /// <summary>
        /// 读取打印配置
        /// </summary>
        /// <returns></returns>
        public static List<PrintConfig> ReadPrintConfig() 
        {
            List<PrintConfig> printConfigList = new List<PrintConfig>();
            if (!File.Exists(configJsonPath))
            {
                return printConfigList;
            }
            string contents = File.ReadAllText(configJsonPath, Encoding.UTF8);
            printConfigList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<PrintConfig>>(contents);
            return printConfigList;
        }

        /// <summary>
        /// 保存打印配置
        /// </summary>
        /// <param name="printConfigList"></param>
        /// <returns></returns>
        public static void SavePrintConfig(List<PrintConfig> printConfigList)
        {
            string contents = Newtonsoft.Json.JsonConvert.SerializeObject(printConfigList, Newtonsoft.Json.Formatting.Indented);
            File.WriteAllText(configJsonPath, contents, Encoding.UTF8);
        }
    }
}

三、对应的配置json文件 printConfig.json

 printConfig.json的测试内容是:

[
  {
    "PrintMessage": "Snake123456789ABCDEF",
    "X": 10,
    "Y": 10,
    "Width": 320,
    "Height": 80,
    "PrintMode": "Code128",
    "FontSize": 16.0,
    "ImagePath": ""
  },
  {
    "PrintMessage": "Snake123456789ABCDEF",
    "X": 80,
    "Y": 120,
    "Width": 180,
    "Height": 180,
    "PrintMode": "QRCode",
    "FontSize": 15.0,
    "ImagePath": ""
  },
  {
    "PrintMessage": "打印图片",
    "X": 370,
    "Y": 80,
    "Width": 120,
    "Height": 120,
    "PrintMode": "Image",
    "FontSize": 12.0,
    "ImagePath": "images\\test.png"
  },
  {
    "PrintMessage": "这是测试纯文本ABC8,需要在Paint事件中显示文字",
    "X": 10,
    "Y": 320,
    "Width": 400,
    "Height": 30,
    "PrintMode": "Text",
    "FontSize": 13.0,
    "ImagePath": ""
  }
]

四、新建关键类文件PrinterUtil,用于合成图片【文本,条形码均为图片】 

PrinterUtil.cs源程序如下:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZXing;
using ZXing.QrCode;

namespace PrinterDemo
{
    /// <summary>
    /// 调用打印机打印图片和文字
    /// </summary>
    public class PrinterUtil
    {
        /// <summary>
        /// 使用打印机打印由文本、二维码等合成的图片
        /// 自动生成图片后打印
        /// 斯内科 20240206
        /// </summary>
        /// <param name="printConfigList">打印设置列表</param>
        /// <param name="printerName">打印机名称</param>
        /// <returns></returns>
        public static bool PrintCompositePicture(List<PrintConfig> printConfigList, string printerName)
        {    
            try
            {
                Bitmap printImg = GeneratePrintImage(printConfigList);
                return PrintImage(printerName, printImg);
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show($"打印异常:{ex.Message}", "出错");
                return false;
            }
        }

        /// <summary>
        /// 生成需要打印的条码和文本等组合的图片
        /// </summary>
        /// <param name="listPrintset"></param>
        /// <returns></returns>
        public static Bitmap GeneratePrintImage(List<PrintConfig> printConfigList)
        {
            List<Bitmap> listbitmap = new List<Bitmap>();
            //合并图像
            for (int i = 0; i < printConfigList.Count; i++)
            {
                Bitmap bitmap = new Bitmap(10, 10);
                switch (printConfigList[i].PrintMode)
                {
                    case PrintMode.Code128:
                        bitmap = GenerateBarcodeImage(printConfigList[i].PrintMessage, printConfigList[i].Width, printConfigList[i].Height, BarcodeFormat.CODE_128, 1);
                        break;
                    case PrintMode.QRCode:
                        bitmap = GenerateBarcodeImage(printConfigList[i].PrintMessage, printConfigList[i].Width, printConfigList[i].Height, BarcodeFormat.QR_CODE, 1);
                        break;
                    case PrintMode.Text:
                        bitmap = GenerateStringImage(printConfigList[i].PrintMessage, printConfigList[i].Width, printConfigList[i].Height, printConfigList[i].X, printConfigList[i].Y, printConfigList[i].FontSize);
                        break;
                    case PrintMode.Image:
                        bitmap = (Bitmap)Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + printConfigList[i].ImagePath);
                        break;
                }
                listbitmap.Add(bitmap);
            }
            //创建要显示的图片对象,根据参数的个数设置宽度
            Bitmap backgroudImg = new Bitmap(600, 400);
            Graphics g = Graphics.FromImage(backgroudImg);
            //清除画布,背景设置为白色
            g.Clear(System.Drawing.Color.White);
            //设置为 抗锯齿 
            g.SmoothingMode = SmoothingMode.AntiAlias;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            for (int i = 0; i < printConfigList.Count; i++)
            {
                g.DrawImage(listbitmap[i], printConfigList[i].X, printConfigList[i].Y, listbitmap[i].Width, listbitmap[i].Height);
            }
            return backgroudImg;
        }

        /// <summary>
        /// 生成条码图片【barcodeFormat一维条形码,二维码】
        /// </summary>
        /// <param name="codeContent">打印条码对应的字符串</param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="barcodeFormat">条码格式:CODE_128代表一维条码,QR_CODE代表二维码</param>
        /// <param name="margin"></param>
        /// <returns></returns>
        public static Bitmap GenerateBarcodeImage(string codeContent, int width, int height, BarcodeFormat barcodeFormat, int margin = 1)
        {
            // 1.设置QR二维码的规格
            QrCodeEncodingOptions qrEncodeOption = new QrCodeEncodingOptions();
            qrEncodeOption.DisableECI = true;
            qrEncodeOption.CharacterSet = "UTF-8"; // 设置编码格式,否则读取'中文'乱码
            qrEncodeOption.Height = height;
            qrEncodeOption.Width = width;
            qrEncodeOption.Margin = margin; // 设置周围空白边距
            qrEncodeOption.PureBarcode = true;
            // 2.生成条形码图片
            BarcodeWriter wr = new BarcodeWriter();
            wr.Format = barcodeFormat; // 二维码 BarcodeFormat.QR_CODE
            wr.Options = qrEncodeOption;
            Bitmap img = wr.Write(codeContent);
            return img;
        }

        /// <summary>
        /// 生成字符串图片
        /// </summary>
        /// <param name="codeContent"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="emSize"></param>
        /// <returns></returns>
        public static Bitmap GenerateStringImage(string codeContent, int width, int height, int x, int y, float emSize = 9f)
        {
            Bitmap imageTxt = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(imageTxt);
            Font font = new Font("黑体", emSize, FontStyle.Regular);
            Rectangle destRect = new Rectangle(x, y, width, height);
            LinearGradientBrush brush = new LinearGradientBrush(destRect, Color.Black, Color.Black, 0, true);
            RectangleF rectangleF = new RectangleF(x, y, width, height);
            graphics.DrawString(codeContent, font, brush, rectangleF);
            return imageTxt;
        }

        /// <summary>
        /// 调用打印机 打印条码和文本 图片
        /// </summary>
        /// <param name="printerName">打印机名称</param>
        /// <param name="image"></param>
        /// <returns></returns>
        private static bool PrintImage(string printerName, Bitmap image)
        {
            if (image != null)
            {
                PrintDocument pd = new PrintDocument();
                //打印事件设置
                pd.PrintPage += new PrintPageEventHandler((w, e) =>
                {
                    int x = 0;
                    int y = 5;
                    int width = image.Width;
                    int height = image.Height;
                    Rectangle destRect = new Rectangle(x, y, width + 200, height + 200);
                    e.Graphics.DrawImage(image, destRect, 2, 2, image.Width, image.Height, System.Drawing.GraphicsUnit.Millimeter);
                });

                PrinterSettings printerSettings = new PrinterSettings
                {
                    PrinterName = printerName
                };
                pd.PrinterSettings = printerSettings;
                pd.PrintController = new StandardPrintController();//隐藏打印时屏幕左上角会弹出的指示窗
                try
                {
                    //设置纸张高度和大小
                    int w = 800;//(int)(PaperWidth * 40);原600,300
                    int h = 200;//(int)(PaperHeight * 40);20
                    pd.DefaultPageSettings.PaperSize = new PaperSize("custom", w, h);
                    pd.Print();
                    return true;
                }
                catch (Exception ex)
                {
                    pd.PrintController.OnEndPrint(pd, new PrintEventArgs());
                    System.Windows.Forms.MessageBox.Show($"【PrintImage】打印出错:{ex.Message}", "使用打印机打印");
                    return false;
                }
            }
            else
            {
                return false;
            }
        }
    }
}

五、新建打印内容配置窗体FormPrintSetting

窗体设计器源程序如下: 

FormPrintSetting.Designer.cs文件


namespace PrinterDemo
{
    partial class FormPrintSetting
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.btnSave = new System.Windows.Forms.Button();
            this.dgvConfig = new System.Windows.Forms.DataGridView();
            this.btnRead = new System.Windows.Forms.Button();
            this.dgvcPrintMessage = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dgvcX = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dgvcY = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dgvcWidth = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dgvcHeight = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dgvcPrintMode = new System.Windows.Forms.DataGridViewComboBoxColumn();
            this.dgvcFontSize = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.dgvcImagePath = new System.Windows.Forms.DataGridViewTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.dgvConfig)).BeginInit();
            this.SuspendLayout();
            // 
            // btnSave
            // 
            this.btnSave.Font = new System.Drawing.Font("宋体", 16F);
            this.btnSave.Location = new System.Drawing.Point(238, 3);
            this.btnSave.Name = "btnSave";
            this.btnSave.Size = new System.Drawing.Size(113, 32);
            this.btnSave.TabIndex = 0;
            this.btnSave.Text = "保存配置";
            this.btnSave.UseVisualStyleBackColor = true;
            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
            // 
            // dgvConfig
            // 
            this.dgvConfig.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dgvConfig.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
            this.dgvcPrintMessage,
            this.dgvcX,
            this.dgvcY,
            this.dgvcWidth,
            this.dgvcHeight,
            this.dgvcPrintMode,
            this.dgvcFontSize,
            this.dgvcImagePath});
            this.dgvConfig.Location = new System.Drawing.Point(3, 41);
            this.dgvConfig.Name = "dgvConfig";
            this.dgvConfig.RowTemplate.Height = 23;
            this.dgvConfig.Size = new System.Drawing.Size(1085, 397);
            this.dgvConfig.TabIndex = 1;
            this.dgvConfig.DataError += new System.Windows.Forms.DataGridViewDataErrorEventHandler(this.dgvConfig_DataError);
            // 
            // btnRead
            // 
            this.btnRead.Font = new System.Drawing.Font("宋体", 16F);
            this.btnRead.Location = new System.Drawing.Point(93, 3);
            this.btnRead.Name = "btnRead";
            this.btnRead.Size = new System.Drawing.Size(113, 32);
            this.btnRead.TabIndex = 2;
            this.btnRead.Text = "刷新配置";
            this.btnRead.UseVisualStyleBackColor = true;
            this.btnRead.Click += new System.EventHandler(this.btnRead_Click);
            // 
            // dgvcPrintMessage
            // 
            this.dgvcPrintMessage.HeaderText = "打印内容";
            this.dgvcPrintMessage.Name = "dgvcPrintMessage";
            this.dgvcPrintMessage.Width = 180;
            // 
            // dgvcX
            // 
            this.dgvcX.HeaderText = "X坐标";
            this.dgvcX.Name = "dgvcX";
            this.dgvcX.Width = 120;
            // 
            // dgvcY
            // 
            this.dgvcY.HeaderText = "Y坐标";
            this.dgvcY.Name = "dgvcY";
            this.dgvcY.Width = 120;
            // 
            // dgvcWidth
            // 
            this.dgvcWidth.HeaderText = "宽度";
            this.dgvcWidth.Name = "dgvcWidth";
            this.dgvcWidth.Width = 120;
            // 
            // dgvcHeight
            // 
            this.dgvcHeight.HeaderText = "高度";
            this.dgvcHeight.Name = "dgvcHeight";
            this.dgvcHeight.Width = 120;
            // 
            // dgvcPrintMode
            // 
            this.dgvcPrintMode.HeaderText = "打印模式枚举";
            this.dgvcPrintMode.Items.AddRange(new object[] {
            "Code128",
            "QRCode",
            "Text",
            "Image"});
            this.dgvcPrintMode.Name = "dgvcPrintMode";
            // 
            // dgvcFontSize
            // 
            this.dgvcFontSize.HeaderText = "字体大小";
            this.dgvcFontSize.Name = "dgvcFontSize";
            // 
            // dgvcImagePath
            // 
            this.dgvcImagePath.HeaderText = "图片路径";
            this.dgvcImagePath.Name = "dgvcImagePath";
            this.dgvcImagePath.Width = 180;
            // 
            // FormPrintSetting
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1093, 450);
            this.Controls.Add(this.btnRead);
            this.Controls.Add(this.dgvConfig);
            this.Controls.Add(this.btnSave);
            this.Name = "FormPrintSetting";
            this.Text = "打印内容配置";
            this.Load += new System.EventHandler(this.FormPrintSetting_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dgvConfig)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.Button btnSave;
        private System.Windows.Forms.DataGridView dgvConfig;
        private System.Windows.Forms.Button btnRead;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcPrintMessage;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcX;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcY;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcWidth;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcHeight;
        private System.Windows.Forms.DataGridViewComboBoxColumn dgvcPrintMode;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcFontSize;
        private System.Windows.Forms.DataGridViewTextBoxColumn dgvcImagePath;
    }
}

FormPrintSetting.cs文件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PrinterDemo
{
    public partial class FormPrintSetting : Form
    {
        
        public FormPrintSetting()
        {
            InitializeComponent();
        }

        private void FormPrintSetting_Load(object sender, EventArgs e)
        {
            btnRead_Click(null, null);
        }

        private void btnRead_Click(object sender, EventArgs e)
        {
            dgvConfig.Rows.Clear();
            List<PrintConfig> printConfigList = CommonUtil.ReadPrintConfig();
            for (int i = 0; i < printConfigList.Count; i++)
            {
                dgvConfig.Rows.Add(printConfigList[i].PrintMessage, printConfigList[i].X, printConfigList[i].Y, printConfigList[i].Width, printConfigList[i].Height,
                    printConfigList[i].PrintMode.ToString(), printConfigList[i].FontSize, printConfigList[i].ImagePath);
            }
        }

        /// <summary>
        /// 检查输入的配置信息
        /// </summary>
        /// <returns></returns>
        private bool CheckInput() 
        {
            int validCount = 0;
            for (int i = 0; i < dgvConfig.Rows.Count; i++)
            {
                string strPrintMessage = Convert.ToString(dgvConfig["dgvcPrintMessage", i].Value);
                string strX = Convert.ToString(dgvConfig["dgvcX", i].Value);
                string strY = Convert.ToString(dgvConfig["dgvcY", i].Value);
                string strWidth = Convert.ToString(dgvConfig["dgvcWidth", i].Value);
                string strHeight = Convert.ToString(dgvConfig["dgvcHeight", i].Value);
                string strPrintMode = Convert.ToString(dgvConfig["dgvcPrintMode", i].Value);
                string strFontSize = Convert.ToString(dgvConfig["dgvcFontSize", i].Value);
                string strImagePath = Convert.ToString(dgvConfig["dgvcImagePath", i].Value);
                if (string.IsNullOrWhiteSpace(strPrintMessage)) 
                {
                    continue;
                }
                int X;
                int Y;
                int Width;
                int Height;
                float FontSize;
                if (!int.TryParse(strX, out X)) 
                {
                    dgvConfig["dgvcX", i].Selected = true;
                    MessageBox.Show("X坐标必须为整数", "出错");
                    return false;
                }
                if (!int.TryParse(strY, out Y))
                {
                    dgvConfig["dgvcY", i].Selected = true;
                    MessageBox.Show("Y坐标必须为整数", "出错");
                    return false;
                }
                if (!int.TryParse(strWidth, out Width) || Width < 0)
                {
                    dgvConfig["dgvcWidth", i].Selected = true;
                    MessageBox.Show("宽度必须为正整数", "出错");
                    return false;
                }
                if (!int.TryParse(strHeight, out Height) || Height < 0)
                {
                    dgvConfig["dgvcHeight", i].Selected = true;
                    MessageBox.Show("高度必须为正整数", "出错");
                    return false;
                }
                if (!float.TryParse(strFontSize, out FontSize) || FontSize < 0)
                {
                    dgvConfig["dgvcFontSize", i].Selected = true;
                    MessageBox.Show("字体大小必须为正实数", "出错");
                    return false;
                }
                if (string.IsNullOrWhiteSpace(strPrintMode)) 
                {
                    dgvConfig["dgvcPrintMode", i].Selected = true;
                    MessageBox.Show("请选择打印模式", "出错");
                    return false;
                }
                if (Enum.TryParse(strPrintMode, out PrintMode printMode) && printMode == PrintMode.Image && string.IsNullOrWhiteSpace(strImagePath)) 
                {
                    dgvConfig["dgvcImagePath", i].Selected = true;
                    MessageBox.Show("已选择打印模式为Image,必须配置图片路径", "出错");
                    return false;
                }
                validCount++;
            }
            if (validCount == 0) 
            {
                MessageBox.Show("没有设置任何打印配置", "出错");
                return false;
            }
            return true;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (!CheckInput()) 
            {
                return;
            }
            List<PrintConfig> printConfigList = new List<PrintConfig>();
            for (int i = 0; i < dgvConfig.Rows.Count; i++)
            {
                string strPrintMessage = Convert.ToString(dgvConfig["dgvcPrintMessage", i].Value);
                string strX = Convert.ToString(dgvConfig["dgvcX", i].Value);
                string strY = Convert.ToString(dgvConfig["dgvcY", i].Value);
                string strWidth = Convert.ToString(dgvConfig["dgvcWidth", i].Value);
                string strHeight = Convert.ToString(dgvConfig["dgvcHeight", i].Value);
                string strPrintMode = Convert.ToString(dgvConfig["dgvcPrintMode", i].Value);
                string strFontSize = Convert.ToString(dgvConfig["dgvcFontSize", i].Value);
                string strImagePath = Convert.ToString(dgvConfig["dgvcImagePath", i].Value);
                if (string.IsNullOrWhiteSpace(strPrintMessage))
                {
                    continue;
                }
                printConfigList.Add(new PrintConfig()
                {
                    PrintMessage = strPrintMessage.Trim(),
                    X = int.Parse(strX),
                    Y = int.Parse(strY),
                    Width = int.Parse(strWidth),
                    Height = int.Parse(strHeight),
                    PrintMode = (PrintMode)Enum.Parse(typeof(PrintMode), strPrintMode),
                    FontSize = float.Parse(strFontSize),
                    ImagePath = strImagePath.Trim()
                });
            }
            CommonUtil.SavePrintConfig(printConfigList);
            //重新刷新
            btnRead_Click(null, null);
            MessageBox.Show("保存打印配置信息成功", "提示");
        }

        private void dgvConfig_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            MessageBox.Show($"出错的列索引【{e.ColumnIndex}】,行索引【{ e.RowIndex}】,{e.Exception.Message}");
        }
    }
}

六、窗体 FormPrinter设计器与源程序如下:

FormPrinter.Designer.cs文件


namespace PrinterDemo
{
    partial class FormPrinter
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// <summary>
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
            this.lblCode = new System.Windows.Forms.Label();
            this.pictureBox1 = new System.Windows.Forms.PictureBox();
            this.btnConfig = new System.Windows.Forms.Button();
            this.btnManualPrint = new System.Windows.Forms.Button();
            this.rtxtMessage = new System.Windows.Forms.RichTextBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
            this.SuspendLayout();
            // 
            // lblCode
            // 
            this.lblCode.AutoSize = true;
            this.lblCode.Font = new System.Drawing.Font("宋体", 12F);
            this.lblCode.Location = new System.Drawing.Point(12, 429);
            this.lblCode.Name = "lblCode";
            this.lblCode.Size = new System.Drawing.Size(152, 16);
            this.lblCode.TabIndex = 27;
            this.lblCode.Text = "NG1234567890ABCDEF";
            // 
            // pictureBox1
            // 
            this.pictureBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
            this.pictureBox1.Location = new System.Drawing.Point(3, 9);
            this.pictureBox1.Name = "pictureBox1";
            this.pictureBox1.Size = new System.Drawing.Size(600, 400);
            this.pictureBox1.TabIndex = 26;
            this.pictureBox1.TabStop = false;
            this.pictureBox1.Paint += new System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
            // 
            // btnConfig
            // 
            this.btnConfig.Font = new System.Drawing.Font("宋体", 16F);
            this.btnConfig.Location = new System.Drawing.Point(125, 524);
            this.btnConfig.Name = "btnConfig";
            this.btnConfig.Size = new System.Drawing.Size(171, 41);
            this.btnConfig.TabIndex = 70;
            this.btnConfig.Text = "打印模板配置";
            this.btnConfig.UseVisualStyleBackColor = true;
            this.btnConfig.Click += new System.EventHandler(this.btnConfig_Click);
            // 
            // btnManualPrint
            // 
            this.btnManualPrint.Font = new System.Drawing.Font("宋体", 16F);
            this.btnManualPrint.Location = new System.Drawing.Point(95, 460);
            this.btnManualPrint.Name = "btnManualPrint";
            this.btnManualPrint.Size = new System.Drawing.Size(306, 52);
            this.btnManualPrint.TabIndex = 69;
            this.btnManualPrint.Text = "根据打印模板配置进行打印";
            this.btnManualPrint.UseVisualStyleBackColor = true;
            this.btnManualPrint.Click += new System.EventHandler(this.btnManualPrint_Click);
            // 
            // rtxtMessage
            // 
            this.rtxtMessage.Location = new System.Drawing.Point(620, 9);
            this.rtxtMessage.Name = "rtxtMessage";
            this.rtxtMessage.ReadOnly = true;
            this.rtxtMessage.Size = new System.Drawing.Size(553, 559);
            this.rtxtMessage.TabIndex = 71;
            this.rtxtMessage.Text = "";
            // 
            // FormPrinter
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(1185, 580);
            this.Controls.Add(this.rtxtMessage);
            this.Controls.Add(this.btnConfig);
            this.Controls.Add(this.btnManualPrint);
            this.Controls.Add(this.lblCode);
            this.Controls.Add(this.pictureBox1);
            this.Name = "FormPrinter";
            this.Text = "条码打印示教";
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label lblCode;
        private System.Windows.Forms.PictureBox pictureBox1;
        private System.Windows.Forms.Button btnConfig;
        private System.Windows.Forms.Button btnManualPrint;
        private System.Windows.Forms.RichTextBox rtxtMessage;
    }
}

FormPrinter.cs文件

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PrinterDemo
{
    public partial class FormPrinter : Form
    {
        public FormPrinter()
        {
            InitializeComponent();
        }

        FormPrintSetting formPrintSetting;
        private void btnConfig_Click(object sender, EventArgs e)
        {
            if (formPrintSetting == null || formPrintSetting.IsDisposed)
            {
                formPrintSetting = new FormPrintSetting();
                formPrintSetting.Show();
            }
            else
            {
                formPrintSetting.Activate();
            }
        }

        /// <summary>
        /// 显示推送消息
        /// </summary>
        /// <param name="msg"></param>
        private void DisplayMessage(string msg)
        {
            this.BeginInvoke(new Action(() =>
            {
                if (rtxtMessage.TextLength > 20480)
                {
                    rtxtMessage.Clear();
                }
                rtxtMessage.AppendText($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}->{msg}\n");
                rtxtMessage.ScrollToCaret();
            }));
        }

        private async void btnManualPrint_Click(object sender, EventArgs e)
        {
            List<PrintConfig> printConfigList = CommonUtil.ReadPrintConfig();
            Task<int> task = Task.Run(() =>
            {
                pictureBox1.Tag = printConfigList;//为标签Tag赋值,用于PictureBox对文字的显示处理【Paint重绘事件】
                DisplayMessage($"即将打印【{printConfigList.Count}】个内容,该内容描述集合为:\n{string.Join(",\n", printConfigList.Select(x => x.PrintMessage))}");
                int okCount = 0;
                try
                {
                    string printContents = string.Join(",", printConfigList.Select(x => x.PrintMessage));
                    //开始打印
                    this.BeginInvoke(new Action(() =>
                    {
                        lblCode.Text = printContents;
                        pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
                        Bitmap bitmap = PrinterUtil.GeneratePrintImage(printConfigList);
                        pictureBox1.Image = bitmap;
                    }));
                    bool rst = PrinterUtil.PrintCompositePicture(printConfigList, printerName: "Zebra 8848T");
                    DisplayMessage($"条码打印{(rst ? "成功" : "失败")}.打印内容:{printContents}");
                    if (rst)
                    {
                        okCount++;
                    }
                }
                catch (Exception ex)
                {
                    DisplayMessage($"条码打印出错,原因:{ex.Message}");
                }
                return okCount;
            });
            await task;
            DisplayMessage($"条码打印已完成,打印成功条码个数:{task.Result}");
        }

        /// <summary>
        /// 在PictureBox上显示文本,需要在Paint重绘事件中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            PictureBox pictureBox = sender as PictureBox;
            if (pictureBox == null || pictureBox.Tag == null) 
            {
                return;
            }
            List<PrintConfig> printConfigList = pictureBox.Tag as List<PrintConfig>;
            for (int i = 0; printConfigList != null && i < printConfigList.Count; i++)
            {
                //因PictureBox不能直接显示文本,需要在Paint事件中独自处理文字显示
                if (printConfigList[i].PrintMode == PrintMode.Text) 
                {
                    Graphics graphics = e.Graphics;
                    Font font = new Font("黑体", printConfigList[i].FontSize, FontStyle.Regular);
                    Rectangle destRect = new Rectangle(printConfigList[i].X, printConfigList[i].Y, printConfigList[i].Width, printConfigList[i].Height);
                    System.Drawing.Drawing2D.LinearGradientBrush brush = new System.Drawing.Drawing2D.LinearGradientBrush(destRect, Color.Black, Color.Black, 0, true);
                    RectangleF rectangleF = new RectangleF(printConfigList[i].X, printConfigList[i].Y, printConfigList[i].Width, printConfigList[i].Height);
                    graphics.DrawString(printConfigList[i].PrintMessage, font, brush, rectangleF);
                }
            }
        }
    }
}

七、程序运行如图:

打印内容配置 

显示图片与打印界面 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/374267.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LLMs之miqu-1-70b:miqu-1-70b的简介、安装和使用方法、案例应用之详细攻略

LLMs之miqu-1-70b&#xff1a;miqu-1-70b的简介、安装和使用方法、案例应用之详细攻略 目录 miqu-1-70b的简介 miqu-1-70b的安装和使用方法 1、安装 2、使用方法 miqu-1-70b的案例应用 miqu-1-70b的简介 2024年1月28日&#xff0c;发布了miqu 70b&#xff0c;潜在系列中的…

leecode172 | 阶乘后的零 | 傻瓜GPT

题意 给定一个整数 n &#xff0c;返回 n! 结果中尾随零的数量。提示 n! n * (n - 1) * (n - 2) * ... * 3 * 2 * 1//题解 class Solution { public:int trailingZeroes(int n) { // ...*(1*5)*...*(x*5)*...*(1*5*5)*...*(x*5*5)*...*n 然后倒过来 //...∗(1∗5)∗...∗…

我的世界Java版服务器如何搭建并实现与好友远程联机Minecarft教程

文章目录 1. 安装JAVA2. MCSManager安装3.局域网访问MCSM4.创建我的世界服务器5.局域网联机测试6.安装cpolar内网穿透7. 配置公网访问地址8.远程联机测试9. 配置固定远程联机端口地址9.1 保留一个固定tcp地址9.2 配置固定公网TCP地址9.3 使用固定公网地址远程联机 本教程主要介…

网络安全大赛

网络安全大赛 网络安全大赛的类型有很多&#xff0c;比赛类型也参差不齐&#xff0c;这里以国内的CTF网络安全大赛里面著名的的XCTF和强国杯来介绍&#xff0c;国外的话用DenCon CTF和Pwn2Own来举例 CTF CTF起源于1996年DEFCON全球黑客大会&#xff0c;以代替之前黑客们通过互相…

idea(2023.3.3 ) spring boot热部署,修改热部署延迟时间

1、添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional> </dependency>载入依赖 2、设置编辑器 设置两个选项 设置热部署更新延迟时…

肯尼斯·里科《C和指针》第10章 结构和联合(2)结构、指针和成员

想吐槽的一点是如果我们当时上课也是这样讲就好了&#xff0c;&#xff0c;&#xff0c; 直接或通过指针访问结构和它们的成员的操作符是相当简单的&#xff0c;但是当它们应用于复杂的情形时就有可能引起混淆。这里有几个例子&#xff0c;能帮助大家更好地理解这两个操作符的工…

Three.js学习6:透视相机和正交相机

一、相机 相机 camera&#xff0c;可以理解为摄像机。在拍影视剧的时候&#xff0c;最终用户看到的画面都是相机拍出来的内容。 Three.js 里&#xff0c;相机 camera 里的内容就是用户能看到的内容。从这个角度来看&#xff0c;相机其实就是用户的视野&#xff0c;就像用户的眼…

Sentinel(理论版)

Sentinel 1.什么是Sentinel Sentinel 是一个开源的流量控制组件&#xff0c;它主要用于在分布式系统中实现稳定性与可靠性&#xff0c;如流量控制、熔断降级、系统负载保护等功能。简单来说&#xff0c;Sentinel 就像是一个交通警察&#xff0c;它可以根据系统的实时流量&…

电力负荷预测 | 基于TCN的电力负荷预测(Python)———模型构建

文章目录 效果一览文章概述源码设计参考资料效果一览 文章概述 基于TCN的电力负荷预测(Python) python3.8 keras2.6.0 matplotlib3.5.2 numpy1.19.4 pandas1.4.3 tensorflow==2.6.0

停止内耗,做有用的事

很多读者朋友跟我交流的时候&#xff0c;都以为我有存稿&#xff0c;于是听到我说每周四现写的时候都很惊讶。其实没什么好惊讶的&#xff0c;每周四我都会把自己关在书房里一整天&#xff0c;断掉一切电话、微信、邮件&#xff0c;从中午写到晚上&#xff0c;直到写完为止。 这…

力扣● 62.不同路径 ● 63. 不同路径 II

● 62.不同路径 单解这道题的话&#xff0c;发现第一行或者第一列的这些位置&#xff0c;都只有一条路径走到&#xff0c;所以路径条数都是1。这就是初始化。坐标大于第一行第一列的这些位置&#xff0c;因为机器人只能向下/向右走&#xff0c;所以只能从上个位置向下走和从左…

用友U8 Cloud ReportDetailDataQuery SQL注入漏洞复现(QVD-2023-47860)

0x01 产品简介 用友U8 Cloud 提供企业级云ERP整体解决方案,全面支持多组织业务协同,实现企业互联网资源连接。 U8 Cloud 亦是亚太地区成长型企业最广泛采用的云解决方案。 0x02 漏洞概述 用友U8 cloud ReportDetailDataQuery 接口处存在SQL注入漏洞,攻击者未经授权可以访…

【Docker】了解Docker Desktop桌面应用程序,TA是如何管理和运行Docker容器(2)

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Docker容器》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

redis源码之:集群创建与节点通信(2)

在上一篇redis源码之&#xff1a;集群创建与节点通信&#xff08;1&#xff09;我们可知&#xff0c;在集群中&#xff0c;cluster节点之间&#xff0c;通过meet将对方加入到本方的cluster->nodes列表中&#xff0c;并在后续过程中&#xff0c;不断通过clusterSendPing发送p…

2 月 5 日算法练习- 动态规划

DP&#xff08;动态规划&#xff09;全称Dynamic Programming&#xff0c;是运筹学的一个分支&#xff0c;是一种将复杂问题分解成很多重叠的子问题、并通过子问题的解得到整个问题的解的算法。 在动态规划中有一些概念&#xff1a; n<1e3 [][] &#xff0c;n<100 [][][…

文心一言4.0API接入指南

概述 文心一言是百度打造出来的人工智能大语言模型&#xff0c;具备跨模态、跨语言的深度语义理解与生成能力&#xff0c;文心一言有五大能力&#xff0c;文学创作、商业文案创作、数理逻辑推算、中文理解、多模态生成&#xff0c;其在搜索问答、内容创作生成、智能办公等众多…

租游戏服务器多少钱1个月?一年价格多少?

游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;游戏服务器配置从4核16G、4核32G、8核32G、16核64G等配置可选&#xff0c;可以选择轻量应用服务器和云服务器&#xff0c;阿腾云atengyu…

42、WEB攻防——通用漏洞文件包含LFIRFI伪协议编码算法代码审计

文章目录 文件包含文件包含原理攻击思路文件包含分类 sessionPHP伪协议进行文件包含 文件包含 文件包含原理 文件包含其实就是引用&#xff0c;相当于C语言中的include <stdio.h>。文件包含漏洞常出现于php脚本中&#xff0c;当include($file)中的$file变量用户可控&am…

Oracle笔记-为表空间新增磁盘(ORA-01691)

如下报错&#xff1a; 原因是Oracle表空间满了&#xff0c;最好是新增一个存储盘。 #查XXX命名空间目前占用了多大的空间 select FILE_NAME,BYTES/1024/1024 from dba_data_files where tablespace_name XXXX #这里的FILE_NAME能查到DBF的存储位置#将对应的datafile设置为30g…

C++中的析构函数

一、析构函数概念 析构函数不是完成对象的销毁&#xff0c;对象的销毁是由编译器完成的。析构函数完成的是对象中资源的清理工作。通常是对对象中动态开辟的空间进行清理。 二、析构函数特性 1.析构函数的函数名是 ~类名 2.析构函数无参数无返回值 3.一个类中只能有一个析…