winform打印机控制程序记录

本文介绍了在Windows应用程序中如何进行跨线程访问控件,使用Invoke方法更新UI。同时,详细阐述了如何控制打印机打印,包括绘制表格、填充数据和启动打印过程。此外,还讨论了威纶通触摸屏通过MQTT发送打印指令的机制,以及打印机控制程序如何接收并解析这些指令来决定是否打印。最后,文章提到了配置特定打印机和读写配置文件的方法,以及打印记录的保存和读取。
摘要由CSDN通过智能技术生成

1.Invoke 跨线程访问

有些回调函数不能直接访问控件的属性,这时就需要用到这个。
用法:

Invoke(new Action(() =>
	{
		//正常代码
		receiveCount++;
		tb_recvCount.Text = Convert.ToString(receiveCount);
	}));
                

2.控制打印机打印

2.1.绘制表格

准备一个 panel ,在里面放入 label ,将 label 的宽度设置为 1 或者 2 ,背景色改为黑色,就能得到一根直线,再放入几个 label 作为文本容器。
在这里插入图片描述

2.2.填充数据

使用 label ,给 label.Text 赋值即可。

2.3.开始打印

在页面中添加如下两个控件。
在这里插入图片描述
将 printPreviewDialog 的 Document 属性设置为 刚刚添加的 printDocument 。
在这里插入图片描述
在 printDocument 的 PrintPage 事件中绘制打印的内容。
在这里插入图片描述

	private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            //打印内容 为 局部的 this.panel1
            Bitmap _NewBitmap = new Bitmap(panel_label.Width, panel_label.Height);
            panel_label.DrawToBitmap(_NewBitmap, new Rectangle(0, 0, _NewBitmap.Width, _NewBitmap.Height));
            e.Graphics.DrawImage(_NewBitmap, 0, 0, _NewBitmap.Width, _NewBitmap.Height);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            Pen pen01 = new Pen(Color.Black, 0.5f);
            //g.DrawLine(pen01, 5, 93, 233, 93);
        } 

3.威纶通触摸屏使用MQTT发送打印指令

  1. 触摸屏的MQTT发送的数据为 JSON 格式,带有 “d” 层和时间戳,值为数组格式,访问时应访问: json["d"]["SN"][0]
    在这里插入图片描述
  2. 触摸屏发送打印指令,使用位状态切换开关,操作模式为“设为ON”。这样点击打印按钮之后,直到 MQTT 发布完成, LB-20 都为 true ,如果设置为 “切换开关”,MQTT发送的时候 LB-20 很可能为 false ,为 false 不打印。
    在这里插入图片描述
  3. 以下是发送的 MQTT 主题,发送模式为触发式,触发地址为第 2 点提到的 LB-20 。
    在这里插入图片描述
  4. 发送的信息有 LB-20 ,打印机控制程序通过判断 Print 的值是否为 true 来判断是否打印这条讯息,如果点击打印之后,发送过去的 Print 为 false 。打印机就不会打印 。
    在这里插入图片描述

4.打印机控制程序接收打印信息

4.1.使用 MQTT 客户端订阅讯息

获得触摸屏发送到 MQTT 服务器的讯息,解析讯息为 JSON 格式。

4.2.判断 Print 是否为 true

为 true 则将数据填充到表格,切换默认打印机,开始打印。
切换默认打印机的代码如下:

    class SetPrinter
    {
        [DllImport("winspool.drv")]
        public static extern bool SetDefaultPrinter(String Name); //调用win api将指定名称的打印机设置为默认打印机
    }

5.打印机配置

5.1. 配置特定机台对应特定的打印机

如下图,以主题来区分机台。
在这里插入图片描述

5.2. 获取打印机列表

在这里插入图片描述

        private void mbtn_getPrinterList_Click(object sender, EventArgs e)//获取打印机列表
        {
            cbb_printerList.Items.Clear();
            int i;
            using (PrintDocument pd = new PrintDocument())
            {
                for (i = 0; i < PrinterSettings.InstalledPrinters.Count; i++)  //开始遍历
                {
                    printers = PrinterSettings.InstalledPrinters[i];  //取得名称
                    cbb_printerList.Items.Add(printers);               //加入ComboBox
                    //if (pd.PrinterSettings.IsDefaultPrinter)                     //判断是否为默认打印机
                    //{
                    //    textBox_actPrinter.Text = pd.PrinterSettings.PrinterName;
                    //    cmbPrinterList.Text = pd.PrinterSettings.PrinterName;    //显示默认打印机名称
                    //}
                }
                if (cbb_printerList.Items != null)
                {
                    cbb_printerList.SelectedItem = cbb_printerList.Items[0];
                }
            }
        }
5.3.将配置写入配置文件。使用 ConfigHelper 类。
public class ConfigHelper
    {
        [DllImport("kernel32")]
        private static extern long GetPrivateProfileString(string section, string key, string def, StringBuilder retval, int size, string filepath);
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filepath);
        /// <summary>
        /// 读配置文件
        /// </summary>
        /// <param name="section">选择读取的部分</param>
        /// <param name="key">键</param>
        /// <param name="def">默认值</param>
        /// <param name="size"></param>
        /// <param name="filepath"></param>
        /// <returns></returns>
        public static String ReadIni(string section, string key, string def, int size, string filepath)
        {
            StringBuilder sb = new StringBuilder();
            GetPrivateProfileString(section, key, def, sb, size, filepath);
            return sb.ToString();
        }
        /// <summary>
        /// 写入数据到配置文件
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="val"></param>
        /// <param name="filepath"></param>
        /// <returns></returns>
        public static long WriteIni(string section, string key, string val, string filepath)
        {
            return WritePrivateProfileString(section, key, val, filepath);
        }
        // 删除ini文件下所有段落
        public void ClearAllSection(string filepath)
        {
            WriteIni(null, null, null, filepath);
        }
        //删除ini文件下personal段落下的所有键
        public void ClearSection(string Section, string filepath)
        {
            WriteIni(Section, null, null, filepath);
        }
    }

用法:

		private void writeConfig()//配置写入
        {
            string path = Application.StartupPath + "/config.ini";
            ConfigHelper.WriteIni("part1", "Machine1_printer", tb_printer1.Text, path);
         }

效果:
在这里插入图片描述

5.4.读取配置文件到JSON,同时将数据写入控件
   private void readConfig(JObject configJson)//配置读取
   {
       string path = Application.StartupPath + "/config.ini";
       
       for(int i = 1; i <= 50; i++)
       {
           string key1=string.Empty, value1=string.Empty;
           //读取主题名
           string tb_topic = $"tb_topic{i}";
           Control[] tb_topics = Controls.Find(tb_topic, true);
           foreach (var tbt in tb_topics)
           {
               if(tbt.Name == tb_topic)
               {
                   tbt.Text = ConfigHelper.ReadIni("part2", $"Machine{i}_topic", "空数据", 1024, path);
                   key1 = tbt.Text;
               }
           }
           //读取打印机名
           string tb_printer = $"tb_printer{i}";
           Control[] tb_printers = Controls.Find(tb_printer, true);
           foreach (var tbp in tb_printers)
           {
               if (tbp.Name == tb_printer)
               {
                   tbp.Text = ConfigHelper.ReadIni("part1", $"Machine{i}_printer", "空数据", 1024, path);
                   value1 = tbp.Text;
               }
           }
           if(configJson.ContainsKey(key1) == false)
           {
               configJson.Add(key1, value1);
           }
       }
   }

6.打印记录

6.1.写入 .csv 文件
        public static void writeRecord(string line)
        {
            string path = Application.StartupPath + $"/PrintRecord/PrintRecord-{DateTime.Now.ToString("yyyy-MM")}.csv";
            //导出到文件的具体位置
            FileInfo fi = new FileInfo(path);
            if (!fi.Directory.Exists)	//如果文件不存在则创建文件
            {
                fi.Directory.Create();
            }
            FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine(line);	//按行写入文件中
            sw.Close();
            fs.Close();
        }
6.2.从 .csv 文件读取
  1. 准备一个空 DataGridView ,不要添加列。
  2. 使用 LoadCSV 方法读取 .csv 文件,得到一个 DataTable 。
        public static DataTable LoadCSV(string data,string tableHead)
        {
            DataTable resultTable = new DataTable();//创建空DataTable
            //在下面写解析代码
            data = data.Replace("\r", string.Empty);//清除一些必须清理的东西
            string[] lines = data.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);//分离每一行,StringSplitOptions.RemoveEmptyEntries:返回值不包含空字符串
            string[] dataHeads = tableHead.Split(',');//获取表头
            foreach (string dataHead in dataHeads)
            {
                resultTable.Columns.Add(new DataColumn { ColumnName = dataHead });//把文件头中的元素加入dataTable的列中
            }
            foreach (string line in lines)//对每一行数据进行操作
            {
                if (string.IsNullOrEmpty(line)) continue;
                string[] items = line.Split(',');//以分号分离每一行数据

                这一块用于读取文件头
                //if (line == lines[0])//如果在读取文件头
                //{
                //    dataHead = new string[items.Length];
                //    dataHead = items;//将文件头数据赋值给dataHead
                //    foreach (string item in items)
                //    {
                //        resultTable.Columns.Add(new DataColumn { ColumnName = item });//把文件头中的元素加入dataTable的列中
                //    }
                //}
                //else//这一块用于读取数据并将数据写入表格
                {
                    DataRow row = resultTable.NewRow();//添加行进入dataTable
                    for (int i = 0; i < items.Length; i++)//向行中添加数据(除类名)
                    {
                        row[dataHeads[i]] = items[i];//dataHead[i]为文件头元素,item[i]为文件头元素对应值
                    }
                    resultTable.Rows.Add(row);//添加行进入dataTable
                }
            }
            return resultTable;
        }
  1. 将 DataGridView.DataSource 设置为这个 DataTable
string tableHead = "日期,时间,班次,机台编号,开机员";//设置表头,以‘,’分隔
string path = Application.StartupPath + "/PrintRecord/"+ cbb_printRecordList.Text;
Encoding encoding = Encoding.GetEncoding("UTF-8");//编码
string csv = File.ReadAllText(path, encoding);
dGV_printRecord.DataSource = UserClass1.LoadCSV(csv, tableHead);

效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值