使用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_CODEwr.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,300int h = 200;//(int)(PaperHeight * 40);20pd.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);}#endregionprivate 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();}#endregionprivate 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);}}}}
}

七、程序运行如图:

打印内容配置 

显示图片与打印界面 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DHCP配置

拓扑图 接口地址池 PC5通过接口地址池获取地址&#xff0c;DHCP服务器和VLAN40的网关为SW4 10.0.40.254 SW4 # sysname Huawei # vlan batch 10 20 30 40 # dhcp enable # interface Vlanif40ip address 10.0.40.254 255.255.255.128dhcp select interface # interface Giga…

frp新版toml配置

从frp v0.52.0 版本开始&#xff0c;frp 将TOML作为配置文件格式。INI 格式已被弃用&#xff0c;并将在未来的发布中移除。因此&#xff0c;frp v0.52.0 及更高版本的配置文件默认为TOML格式。 项目地址 GitHub&#xff1a;https://github.com/fatedier/frp/releases 服务端…

做跨境电商为什么需要使用住宅代理IP?

住宅代理IP是近年来跨境电商领域日益受到重视的技术工具&#xff0c;不仅可以保护隐私、优化网络速度&#xff0c;还能助推跨境电商的精细化管理。接下来&#xff0c;我们将深入探讨利用住宅代理IP如何为跨境电商业务带来竞争优势。 一、住宅代理IP与跨境电商 住宅代理IP&…

「深度学习」门控循环单元GRU

一、梯度消失问题 梯度消失&#xff1a; 基础的 RNN 模型不善于处理长期依赖关系&#xff0c;有很多局部影响&#xff0c;很难调整自己前面的计算。y^{<i>} 仅仅受自己附近的值影响。 解决方法&#xff1a;GRU 或 LSTM 梯度爆炸&#xff1a; 反向传播时&#xff0c;随着…

【数据分享】1929-2023年全球站点的逐日降水量数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;说到常用的降水数据&#xff0c;最详细的降水数据是具体到气象监测站点的降水数据&#xff01; 有关气象指标的监测站点数据&#xff0c;之前我们分享过1929-2023年全…

JavaScript中闭包的定义、原理及应用场景

JavaScript是一门以函数为核心的编程语言&#xff0c;其独特的闭包特性是众多开发者所喜爱的特点之一。闭包是一种非常强大的概念&#xff0c;可以帮助我们实现许多复杂的功能和逻辑。本篇博客将为大家深入介绍JavaScript中闭包的定义、原理及应用场景&#xff0c;并通过示例代…

SpringCloud--Gateway解析

一、Gateway简介 Gateway是Spring Cloud官方推出的第二代微服务网关&#xff0c;它旨在提供统一的路由方式以及为微服务应用提供强大的负载均衡能力。与第一代Spring Cloud Netflix Zuul相比&#xff0c;Spring Cloud Gateway在性能、可扩展性、易用性等方面都有了显著的提升。…

【VS2022】运行cmake项目

在这里插入代码片https://github.com/kitamstudios/rust-analyzer.vs/blob/master/PREREQUISITES.md Latest rustup (Rust Toolchain Installer). Install from here. Welcome to Rust!This will download and install the official compiler for the Rust programming langua…

go语言每日一练——链表篇(六)

传送门 牛客面试必刷101题—— 判断链表中是否有环 牛客面试必刷101题—— 链表中环的入口结点 题目及解析 题目一 代码 package mainimport . "nc_tools"/** type ListNode struct{* Val int* Next *ListNode* }*//**** param head ListNode类* return bool…

vue3-内置组件-TransitionGroup

<TransitionGroup> 是一个内置组件&#xff0c;用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。 与 <Transition> 的区别 <TransitionGroup> 支持和 <Transition> 基本相同的 props、CSS 过渡 class 和 JavaScript 钩子监听器&…

代驾应用系统(ssm)

登录首页 管理员界面 代驾司机界面 普通用户界面 前台页面 1、系统说明 &#xff08;1&#xff09; 框架&#xff1a;spring、springmvc、mybatis、mysql、jsp &#xff08;2&#xff09; 系统分为前台系统、后端管理系统 2、欢迎留言联系交流学习讨论&#xff1a;qq 97820625…

wsl 安装minikube

Minikube是一种轻量化的Kubernetes集群&#xff0c;专为开发者和学习者设计&#xff0c;以便他们能够更好地学习和体验Kubernetes的功能。它利用个人PC的虚拟化环境&#xff0c;实现了Kubernetes的快速构建和启动。目前&#xff0c;Minikube已经支持在macOS、Linux和Windows平台…

部署 Spring 项目到 Linux 云服务器上

关于 Linux 服务器安装 JDK ,Mysql&#xff0c;配置安全组&#xff08;这些都是必要的&#xff09; 推荐看在 Linux 上搭建 Java Web 项目环境&#xff08;最简单的进行搭建&#xff09; 流程 1.上传Jar包到服务器 要想部署 Spring 项目&#xff0c;先要将 Spring 项目打成 J…

Linux--文件

文件的基本信息 文件是计算机系统中存储数据的一种单位。 它可以是文本、图像、音频、视频等信息的载体。文件通常以特定的格式和拓展名来表示其内容和类型。 在计算机系统中&#xff0c;文件使用文件名来唯一标识和访问。文件可以被创建、读取、写入、复制、移动、删除等操作…

相机图像质量研究(8)常见问题总结:光学结构对成像的影响--工厂调焦

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

Python程序员面试题精选(1)

本文精心挑选了10道Python程序员面试题&#xff0c;覆盖了Python的多个核心领域&#xff0c;包括装饰器、lambda函数、列表推导式、生成器、全局解释器锁(GIL)、单例模式以及上下文管理器等。每道题都附有简洁的代码示例&#xff0c;帮助读者更好地理解和应用相关知识点。 题目…

嵌入式中IPv5去哪了?

只要使用过电脑的人&#xff0c;99%应该都知道IP地址&#xff0c;前几个月有一个重大的新闻“全球IPv4地址耗尽”相信大家都听说了。 然后IPv6就成了当下发展的趋势&#xff0c;包括有些手机APP会重点标注“兼容IPv6”等信息。那么问题来了&#xff1a;IPv4之后直接是IPv6&…

高灵敏比色法IgG2a (mouse) ELISA kit

用于检测IgG2a&#xff08;小鼠&#xff09;的高灵敏度ELISA试剂盒&#xff0c;仅需90分钟即可得到实验结果 免疫球蛋白G&#xff08;IgG&#xff09;是一种免疫球蛋白单体&#xff0c;由两条&#xff08;γ&#xff09;重链和两条轻链组成。每个IgG分子包含两个抗原结合域和一…

修改JDK文件路径或名称(以及修改后jJRE文件变红的解决)

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

Vue中对虚拟DOM的理解

作为现代前端开发中的主流框架之一&#xff0c;Vue.js是一个非常流行的JavaScript框架&#xff0c;其核心概念之一就是虚拟DOM&#xff08;Virtual DOM&#xff09;。在本篇文章中&#xff0c;我们将深入探讨Vue中虚拟DOM的概念&#xff0c;并讨论为什么它在前端开发中如此重要…