c#热敏票据打印机

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace JBPrinter
{
    public partial class Form1 : Form
    {
        private IntPtr Gp_IntPtr;                   //驱动打印句柄
        private libUsbContorl.UsbOperation NewUsb = new libUsbContorl.UsbOperation();
        private string iPaddress;
        private System.Windows.Forms.PrintPreviewDialog printv_pos = null;
        private System.Drawing.Printing.PrintDocument printd_pos = null;
        public Form1()
        {
            InitializeComponent();
            iPaddress = txt_Ip1.Text.Trim() + "." + txt_Ip2.Text.Trim() + "." + txt_Ip3.Text.Trim() + "." + txt_Ip4.Text.Trim();
        }
        private void btn_dk_Click(object sender, EventArgs e)
        {
            LoadPOSDll PosPrint = new LoadPOSDll();
            //POS_COM_DTR_DSR 0x00 流控制为DTR/DST
            //POS_COM_RTS_CTS 0x01 流控制为RTS/CTS
            //POS_COM_XON_XOFF 0x02 流控制为XON/OFF
            //POS_COM_NO_HANDSHAKE 0x03 无握手
            //POS_OPEN_PARALLEL_PORT 0x12 打开并口通讯端口
            //POS_OPEN_BYUSB_PORT 0x13 打开USB通讯端口
            //POS_OPEN_PRINTNAME 0X14 打开打印机驱动程序
            //POS_OPEN_NETPORT 0x15 打开网络接口 
            if (PosPrint.OpenNetPort(iPaddress))//当参数nParam的值为POS_OPEN_NETPORT时,表示打开指定的网络接口,如“192.168.10.251”表示网络接口IP地址,打印时参考
            {
                Gp_IntPtr = PosPrint.POS_IntPtr;
                txt_OPenState.Text = "打开网口成功!";
            }
            else
            {
                txt_OPenState.Text = "失败!";
            }
        }
        #region 端口地址修改
        private void txt_Ip1_TextChanged(object sender, EventArgs e)
        {
            iPaddress = txt_Ip1.Text.Trim() + "." + txt_Ip2.Text.Trim() + "." + txt_Ip3.Text.Trim() + "." + txt_Ip4.Text.Trim();
        }
        private void txt_Ip2_TextChanged(object sender, EventArgs e)
        {
            iPaddress = txt_Ip1.Text.Trim() + "." + txt_Ip2.Text.Trim() + "." + txt_Ip3.Text.Trim() + "." + txt_Ip4.Text.Trim();
        }
        private void txt_Ip3_TextChanged(object sender, EventArgs e)
        {
            iPaddress = txt_Ip1.Text.Trim() + "." + txt_Ip2.Text.Trim() + "." + txt_Ip3.Text.Trim() + "." + txt_Ip4.Text.Trim();
        }
        private void txt_Ip4_TextChanged(object sender, EventArgs e)
        {
            iPaddress = txt_Ip1.Text.Trim() + "." + txt_Ip2.Text.Trim() + "." + txt_Ip3.Text.Trim() + "." + txt_Ip4.Text.Trim();
        }
        #endregion
        #region 打印机状态检测(请先检网关)
        private void btn_QueryStatus_Click(object sender, EventArgs e)
        {
            Byte res = new Byte();
            int ret = LoadPOSDll.POS_NETQueryStatus(iPaddress, out res);
            StringBuilder sb = new StringBuilder();
            if ((res & 0x10) == 0x10)
                sb.AppendLine("打印机出错!");
            if ((res & 0x02) == 0x02)
                sb.AppendLine("打印机脱机!");
            if ((res & 0x04) == 0x04)
                sb.AppendLine("上盖打开!");
            if ((res & 0x20) == 0x20)
                sb.AppendLine("切刀出错!");
            if ((res & 0x40) == 0x40)
                sb.AppendLine("纸将尽!");
            if ((res & 0x80) == 0x80)
                sb.AppendLine("缺纸!");
            if (sb.Length > 0)
                MessageBox.Show(sb.ToString());
        }
        #endregion
        #region 简单打印1
        private void btn_Print1_Click(object sender, EventArgs e)
        {
            //LoadPOSDll PosPrint = new LoadPOSDll();
            //POS_COM_DTR_DSR 0x00 流控制为DTR/DST
            //POS_COM_RTS_CTS 0x01 流控制为RTS/CTS
            //POS_COM_XON_XOFF 0x02 流控制为XON/OFF
            //POS_COM_NO_HANDSHAKE 0x03 无握手
            //POS_OPEN_PARALLEL_PORT 0x12 打开并口通讯端口
            //POS_OPEN_BYUSB_PORT 0x13 打开USB通讯端口
            //POS_OPEN_PRINTNAME 0X14 打开打印机驱动程序
            //POS_OPEN_NETPORT 0x15 打开网络接口 
            //            if (LoadPOSDll.POS_StartDoc())
            //            {
            //                byte[] by_SendData = System.Text.Encoding.Default.GetBytes("今天到此一游~~\r\n");
            //                LoadPOSDll.POS_WriteFile(PosPrint.POS_IntPtr, by_SendData, (uint)by_SendData.Length);
            //                LoadPOSDll.POS_WriteFile(PosPrint.POS_IntPtr, new byte[] { 0x0a }, 1);
            //                LoadPOSDll.POS_EndDoc();
            //            }
            print();
        }
        #endregion
        #region 先预览后打印
        private void button1_Click(object sender, EventArgs e)
        {
            //打印预览            
            PrintPreviewDialog ppd = new PrintPreviewDialog();
            PrintDocument pd = new PrintDocument();
            //设置边距
            Margins margin = new Margins(15, 15, 15, 15);
            pd.DefaultPageSettings.Margins = margin;
            纸张设置默认
            PaperSize pageSize = new PaperSize("First custom size", getYc(70), 420);
            pd.DefaultPageSettings.PaperSize = pageSize;
            //打印事件设置            
            pd.PrintPage += new PrintPageEventHandler(printDocument1_PrintPage);
            ppd.Document = pd;
            ppd.ShowDialog();
            try
            {
                //print();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
                pd.PrintController.OnEndPrint(pd, new PrintEventArgs());
            }
        }
        #endregion
        private int getYc(double cm)
        {
            return (int)(cm / 25.4) * 100;
        }
        #region 打印的内容
        #region 标题
        public string GetPrintHead()
        {
            StringBuilder sb = new StringBuilder();
            string tou = "重庆洞子老火锅";
            sb.Append("        " + tou + "     \n");
            return sb.ToString();
        }
        #endregion
        #region 内容
        public string GetPrintStr()
        {
            StringBuilder sb = new StringBuilder();
            string address = "重庆涪陵XXX号";
            string saleID = "2010930233330";
            string item = "商品";
            decimal price = 25.00M;
            int count = 1;
            decimal total = 0.00M;
            decimal fukuan = 500.00M;
            //sb.Append("          " + tou + "     \n");
            sb.Append("--------------------------------------------------\n");
            sb.Append("日期:" + DateTime.Now.ToString("yyyy/MM/dd hh:mm:ss") + "\n" + "单号:" + saleID + "\n");
            sb.Append("--------------------------------------------------\n");
            sb.Append("项目" + "\t" + "数量" + "\t" + "单价" + "\t" + "小计" + "\n");
            for (int i = 0; i < count; i++)
            {
                decimal xiaoji = (i + 1) * price;
                sb.Append(item + (i + 1) + "\t" + (i + 1) + "\t" + price + "\t" + xiaoji);
                total += xiaoji;
                if (i != (count))
                    sb.Append("\n");
            }
            sb.Append("--------------------------------------------------\n");
            sb.Append("数量: " + count + " 合计: " + total + "\n");
            sb.Append("付款: " + fukuan);
            sb.Append(" 现金找零: " + (fukuan - total) + "\n");
            sb.Append("--------------------------------------------------\n");
            sb.Append("地址:" + address + "\n");
            sb.Append("电话:123456789   123456789\n");
            sb.Append("      谢谢惠顾欢迎下次光临 ");
            return sb.ToString();
        }
        #endregion
        #endregion
        /// POS打印
        /// </summary>
        public void print()
        {
            this.printv_pos = new System.Windows.Forms.PrintPreviewDialog();
            this.printd_pos = new System.Drawing.Printing.PrintDocument();
            this.printv_pos.AutoScrollMargin = new System.Drawing.Size(0, 0);    //获取或设置自动滚动边距的大小
            this.printv_pos.AutoScrollMinSize = new System.Drawing.Size(0, 0);   //获取或设置自动滚动条的最小大小
            this.printv_pos.ClientSize = new System.Drawing.Size(400, 300);     //获取或设置窗体工作区的大小
            this.printv_pos.Document = this.printd_pos;                         //获取或设置要预览的文档
            this.printv_pos.Enabled = true;
            this.printv_pos.Name = "printPreviewDialog1";
            this.printv_pos.Visible = false;
            this.printd_pos.PrintController = new System.Drawing.Printing.StandardPrintController();
            this.printd_pos.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
            //设置边距
            System.Drawing.Printing.Margins margins = new System.Drawing.Printing.Margins(5, 5, 5, 5);
            this.printd_pos.DefaultPageSettings.Margins = margins;
            this.printd_pos.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("First custom size", getYc(70), 420);
            //this.printDocument1.PrinterSettings.PrinterName = "";
            //Margins margins = new Margins(
            //this.printv_pos.Document = this.printd_pos;
            printv_pos.PrintPreviewControl.AutoZoom = false;
            printv_pos.PrintPreviewControl.Zoom = 1;
            // this.printv_pos.ShowDialog(win);
            try
            {
                printd_pos.Print();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                printd_pos.PrintController.OnEndPrint(printd_pos, new PrintEventArgs());
            }
        }
        #region (页面设置事件)字体设置
        private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
        {
            Graphics g = e.Graphics;
            //头部
            string strHeader = GetPrintHead();
            Font ft = new Font("微软雅黑", 12.5F, FontStyle.Bold);    //字体
            Point pt = new Point(0, 0);                               //顶部
            g.DrawString(strHeader, ft, new SolidBrush(Color.Black), pt);
            //Graphics.MeasureString 方法 (String, Font)
            //MeasureString测量用指定的 System.Drawing.Font 绘制的指定字符串
            Size headSize = Size.Round(g.MeasureString(strHeader, ft));  //头部的Size(宽和高)
            headSize.Width = 0;                                          //设置宽为0,是因为只需要向y移动,不需要x移动
            //内容
            string strFile = GetPrintStr();
            ft = new Font("宋体", 8.5F, FontStyle.Regular);
            pt = new Point(headSize);                                  //Point(Size size)
            g.DrawString(strFile, ft, new SolidBrush(Color.Black), pt);
            SizeF strSize = g.MeasureString(strHeader, ft);
        }
        #endregion
    }
}

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可能感兴趣的项目设计:应用于 POS 机、收银机等80mm 高速微型打印机(原理图、上位机、程序源码) 附件内容截图: 字库改组: 为了便于处理,我们对字模进行如下改组: 把 16 X 16 汉字,分成左边从上到下16个字节,和右边16个字节,目的是可以把一个汉字当成两个 16X8 字母或数字处理。 改组后,字模数据从 RAM 读出送往打印机时,无论是汉字还是字母或数字,第n行点的 "字节数据" 就是: n, n+16, n+16*2, n+16*3......一行取48个字节, 8*48=384 个点。 把 24 X 24 汉字,分成左边从上到下 24行 X 12列, 和右边 24 X 12 数据,一行 12bit 数据存放在半字 16bit 中的低12bit, 左右半边都有 24个"半字",或 48 个字节,一个24X24汉字变成96个字节了。如此处理字模时,把一个汉字当成两个 24 X 12 字母或数字来处理。 不管汉字字母或数字,第n行点的 ”半字数据“ 就是 n,n+24,n+24*2,n+24*3......取32个"半字",刚好够 12bit*32=384 个点,即一行可打 32个字母,或16个汉字。 字模写入 SPI FLASH 时,完成以上变换。打印时,NUC123 从 SPI FLASH 读出的字模,认为是上述变换后的格式。 高速 SPI 接口传输数据 打印时,字模数据要从 W25Q16 中通过 SPI 接口读取,再通过 SPI 接口移入打印头。 一行 16个 24 X 24 汉字有 16*96 = 1536 个字节。字符行与行之间一般有一到三个空行,走纸最快时 90mm/秒,694us 走一行,在这个时间内要读取所有 1536个字节,放入 RAM 打印缓冲区。代码中,把 SPI 配置成 28.8Mbps 从FLASH 中读取字模,为便于用示波器查看波形,每次收发 16bit 中间,插入一个空闲 CLK,收发完 1536 Byte 要经过 1536/2 = 768 次 17bit 时钟,时间为 768*17/28.8 = 453us。关键是 SPI 收发 16bit 中间不能再有额外间隙,否则 28.8Mbps 失去意义,所以代码中,使能 SPI 的 FiFo,同时配置 PDMA 来完成 SPI 收发。 点数据移入打印头,SPI 速率配置为 4.8Mbps,384个点。数据传输时间约为 384/4.8 = 80us,走纸最快 90毫米/秒 时 694us走一行,数据早传完了。走纸速度再快一倍也来得及。 USB 打印机模式 USB 打印模式,上位机传输过来的,是图形点阵数据与命令混在一起,无需从 SPI FLASH 中读字模,只要把点数据从USB数据流里分离出来,移入打印头即可。代码中定义了一个 4096 字节的环形缓冲区。 USB 数据中断: 分析数据流,见函数 PTR_Data_Receive(), 遇图形点阵数据流,写入环形缓冲区。遇命令立即执行,或为执行做好准备。若有打印命令或走纸命令,就把 “走纸行数” 通过全局变量 StepIncrease 传给主循环代码。 主循环里,1>若传过来的走纸行数 StepIncrease 不为0,就启动走纸。2>若已在走纸,就检查环形缓冲区是否有待打印数据——比较写入指针与读出指针的值可得知,若有待打印数据,就会在纸每走过一行时,把数据送入打印头并加打印。 走纸,加和数据传输,三者同时处理的时序 需要走纸时,只要设定速度值全局变量 pStepM_TimLimit,然后调用走纸启动函数 PaperRollStart() 就开始走纸了,何时走下一行,何时停止,都在 Timer1 中断代码里处理。中断外面无需再处理走纸的事。 需要说明的是:有一个走纸剩余行数全局变量 RemainderStep, 在此变量非0时,可以随时加大这个值,加长走纸行数。 再来看何时把数据串入打印头,何时加,下图用鼠标点击可放大。 打印开始时,先启动走纸,前面空一两行没事,一行只有 0.0625mm。 把第一行点数据,串入打印头后,就等待走纸到第三行——由剩余步数全局变量 RemainderStep 的值可得知。只要一走到第三行,立即输出点数据到加头,并启动加定时。然后就去处理下一行点数据。 每次在走到新的一行时(实际是两行), 都立即启动已准备好的、这一行数据的加,接着代码去准备下一行点数据。 何时加停止呢? 不用担心,由 Timer2 中断代码处理了。 打印开始时,必须知道要走几行, 两行一个点,一行 16 X 16 字符,要走 32行,一般还要加上开头和结尾的空行。 连续打印时,只要剩余行数 RemainderStep 不为0——走纸未停,可以随时增加这个值,加长走纸行数,继续打

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值