c# 小票打印
c# 在进行小票打印时大致有三种方法。
1. 使用水晶报表进行打印。可以参考:https://www.cnblogs.com/aitong/p/10717786.html
2. 在 PrintDocument 对象上进行绘图,然后使用其打印方法直接打印。
using CrystalDecisions.CrystalReports.Engine;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms; namespace CrTest
{
public partial class Form1 : Form
{
string title = "标题标题标题标题标题标题标题标题标题标题标题";
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
//打印预览
PrintPreviewDialog ppd = new PrintPreviewDialog();
PrintDocument pd = new PrintDocument();
//设置边距
Margins margin = new Margins(, , , );
pd.DefaultPageSettings.Margins = margin;
int height = ;
if (title.Length > )
{
height = ;
}
//纸张设置默认
PaperSize pageSize = new PaperSize("First custom size", (int)( * / 25.4), height);//58mm 转绘图宽度
pd.DefaultPageSettings.PaperSize = pageSize;
//打印事件设置
pd.PrintPage += new PrintPageEventHandler(pd_PrintPage);
ppd.Document = pd;
ppd.ShowDialog();
//try
//{
// pd.Print();
//}
//catch (Exception ex)
//{
// MessageBox.Show(ex.Message, "打印出错", MessageBoxButtons.OK, MessageBoxIcon.Error);
// pd.PrintController.OnEndPrint(pd, new PrintEventArgs());
//}
} private void pd_PrintPage(object sender, PrintPageEventArgs e)
{
Font font = new Font("Arial", , System.Drawing.FontStyle.Regular);
string text = title;
int yLocation = e.MarginBounds.Y;
int center = e.PageSettings.PaperSize.Width / ;
int heightStep = ;
while (text.Length > )
{
string printStr;
if (text.Length > )
{
printStr = text.Substring(, );
text = text.Substring();
}
else
{
printStr = text;
text = "";
}
SizeF size = e.Graphics.MeasureString(printStr, font);
heightStep =Convert.ToInt32( size.Height * 1.3);
e.Graphics.DrawString(printStr, font, System.Drawing.Brushes.Black, center - size.Width / , yLocation);
yLocation += heightStep;
}
}
}
}
3. 使用 ESC/POS 控制指令
注意 SendStringToPrinter 这个接口。
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
//https://www.cnblogs.com/QiuTianBaBa/p/6730829.html
//https://blog.csdn.net/andrewniu/article/details/80353655
namespace Evet2Basic.Model.Print.Report
{
public class RawPrint
{
// Structure and API declarions:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd); [DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di); [DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "StartPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "EndPagePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndPagePrinter(IntPtr hPrinter); [DllImport("winspool.Drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten); // SendBytesToPrinter()
// When the function is given a printer name and an unmanaged array
// of bytes, the function sends those bytes to the print queue.
// Returns true on success, false on failure.
private static bool SendBytesToPrinter(string szPrinterName, IntPtr pBytes, Int32 dwCount)
{
Int32 dwError = , dwWritten = ;
IntPtr hPrinter = new IntPtr();
DOCINFOA di = new DOCINFOA();
bool bSuccess = false; // Assume failure unless you specifically succeed. di.pDocName = "XiaoPiao";
di.pDataType = "RAW"; // Open the printer.
if (OpenPrinter(szPrinterName.Normalize(), out hPrinter, IntPtr.Zero))
{
// Start a document.
if (StartDocPrinter(hPrinter, , di))
{
// Start a page.
if (StartPagePrinter(hPrinter))
{
// Write your bytes.
bSuccess = WritePrinter(hPrinter, pBytes, dwCount, out dwWritten);
EndPagePrinter(hPrinter);
}
EndDocPrinter(hPrinter);
}
ClosePrinter(hPrinter);
}
// If you did not succeed, GetLastError may give more information
// about why not.
if (bSuccess == false)
{
dwError = Marshal.GetLastWin32Error();
}
return bSuccess;
} private static bool SendFileToPrinter(string szPrinterName, string szFileName)
{
// Open the file.
FileStream fs = new FileStream(szFileName, FileMode.Open);
// Create a BinaryReader on the file.
BinaryReader br = new BinaryReader(fs);
// Dim an array of bytes big enough to hold the file's contents.
Byte[] bytes = new Byte[fs.Length];
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr();
int nLength; nLength = Convert.ToInt32(fs.Length);
// Read the contents of the file into the array.
bytes = br.ReadBytes(nLength);
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(nLength);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(bytes, , pUnmanagedBytes, nLength);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, nLength);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
} public static bool SendBytesToPrinter(string szPrinterName, byte[] buf)
{
bool bSuccess = false;
// Your unmanaged pointer.
IntPtr pUnmanagedBytes = new IntPtr();
// Allocate some unmanaged memory for those bytes.
pUnmanagedBytes = Marshal.AllocCoTaskMem(buf.Length);
// Copy the managed byte array into the unmanaged array.
Marshal.Copy(buf, , pUnmanagedBytes, buf.Length);
// Send the unmanaged bytes to the printer.
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, buf.Length);
// Free the unmanaged memory that you allocated earlier.
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
} /// <summary>
/// 切纸
/// </summary>
/// <param name="szPrinterName">打印机名</param>
/// <returns></returns>
public static bool Cut(string szPrinterName)
{
bool bSuccess = false; IntPtr pUnmanagedBytes = new IntPtr(); byte[] data = new byte[] { 0x1B, 0x69 };
pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length);
Marshal.Copy(data, , pUnmanagedBytes, data.Length);
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, data.Length);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return true;
} public static bool SendBytesToPrinterImg(string szPrinterName, Bitmap bmp, bool needWarning)
{
bool bSuccess = false; //Byte[] byte_send = Encoding.GetEncoding("GB2312").GetBytes("\x1b\x40");
IntPtr pUnmanagedBytes = new IntPtr();
//pUnmanagedBytes = Marshal.AllocCoTaskMem(byte_send.Length);
//Marshal.Copy(byte_send, 0, pUnmanagedBytes, byte_send.Length);
//bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, byte_send.Length);
//Marshal.FreeCoTaskMem(pUnmanagedBytes); byte[] data = new byte[] { 0x1B, 0x33, 0x00 };
//pUnmanagedBytes = new IntPtr(0);
pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length);
Marshal.Copy(data, , pUnmanagedBytes, data.Length);
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, data.Length);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
data[] = (byte)'\x00';
data[] = (byte)'\x00';
data[] = (byte)'\x00'; Color pixelColor; // ESC * m nL nH 点阵图
byte[] escBmp = new byte[] { 0x1B, 0x2A, 0x00, 0x00, 0x00 };
escBmp[] = (byte)'\x21';
//nL, nH
escBmp[] = (byte)(bmp.Width % );
escBmp[] = (byte)(bmp.Width / ); // data
for (int i = ; i < (bmp.Height / ) + ; i++)
{
//pUnmanagedBytes = new IntPtr(0);
pUnmanagedBytes = Marshal.AllocCoTaskMem(escBmp.Length);
Marshal.Copy(escBmp, , pUnmanagedBytes, escBmp.Length);
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, escBmp.Length);
Marshal.FreeCoTaskMem(pUnmanagedBytes); byte[] temptype = new byte[bmp.Width * ];
int lengthNow = ;
for (int j = ; j < bmp.Width; j++)
{
for (int k = ; k < ; k++)
{
if (((i * ) + k) < bmp.Height) // if within the BMP size
{
pixelColor = bmp.GetPixel(j, (i * ) + k);
if (pixelColor.R == )
{
data[k / ] += (byte)( >> (k % ));
}
}
}
data.CopyTo(temptype, lengthNow);
lengthNow += ; data[] = (byte)'\x00';
data[] = (byte)'\x00';
data[] = (byte)'\x00';
} //pUnmanagedBytes = new IntPtr(0);
pUnmanagedBytes = Marshal.AllocCoTaskMem(temptype.Length);
Marshal.Copy(temptype, , pUnmanagedBytes, temptype.Length);
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, temptype.Length);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
System.Threading.Thread.Sleep();
}
byte[] dataClear = new byte[] { 0x1B, 0x40 };
pUnmanagedBytes = Marshal.AllocCoTaskMem(dataClear.Length);
Marshal.Copy(dataClear, , pUnmanagedBytes, dataClear.Length);
bSuccess = SendBytesToPrinter(szPrinterName, pUnmanagedBytes, dataClear.Length);
Marshal.FreeCoTaskMem(pUnmanagedBytes);
return bSuccess;
} public static bool SendStringToPrinter(string szPrinterName, string szString)
{
try
{
//指令见打印机官方文档 http://www.xprinter.net/index.php/Server/index/cid/3
byte[] smallArray = new byte[] { , , };
List<byte> list = new List<byte>(); list.AddRange(smallArray);
while (szString.Contains("<B>") || szString.Contains("<A>"))
{
if (!szString.Contains("<B>"))
{
ReplaceAB(ref szString, ref list, );
}
else if (!szString.Contains("<A>"))
{
ReplaceAB(ref szString, ref list, );
}
else
{
int indexA = szString.IndexOf("<A>");
int indexB = szString.IndexOf("<B>");
if (indexA < indexB)
{
ReplaceAB(ref szString, ref list, );
}
else
{
ReplaceAB(ref szString, ref list, );
}
}
}
Encoding enc = Encoding.GetEncoding("gb2312");
list.AddRange(enc.GetBytes(szString));
return RawPrint.SendBytesToPrinter(szPrinterName, list.ToArray());
}
catch (Exception)
{
return false;
}
} private static void ReplaceAB(ref string szString, ref List<byte> list, int mul)
{
//指令见打印机官方文档 http://www.xprinter.net/index.php/Server/index/cid/3
string replaceStr1 = "<B>";
string replaceStr2 = "</B>";
byte[] smallArray = new byte[] { , , };
byte[] bigArray = new byte[] { , , }; //放大三倍 //29, 33字体放大指令 34放大倍数 ( 0一倍 17两倍 34三倍 51四倍 68五倍 85六倍)
if (mul == )
{
replaceStr1 = "<A>";
replaceStr2 = "</A>";
bigArray = new byte[] { , , }; //放大两倍
}
Encoding enc = Encoding.GetEncoding("gb2312");
int index = szString.IndexOf(replaceStr1);
string first = szString.Substring(, index);
list.AddRange(enc.GetBytes(first));//第一段
list.AddRange(bigArray);//变成大写
szString = szString.Substring(index + );
int index2 = szString.IndexOf(replaceStr2);
string second = szString.Substring(, index2);
list.AddRange(enc.GetBytes(second));//大写段
list.AddRange(smallArray);//变小写
szString = szString.Substring(index2 + );
}
}
}
c# 小票打印的更多相关文章
- 更好的小票打印体验,huanent.printer2.0发布
huanent.printer2.0是一个专注消费小票打印的类库.拥有许多先进的特性例如居中打印.自动换行等特性,可以通过简洁的代码来打印出复杂的消费小票.huanent.printer通过MIT方式 ...
- Android 小票打印USB
第一步USB通信: Usb设备有两种,Host与Accessory 简单来说是主模式与从模式,主模式则android设备给外设供电,反之,外设给android设备充电,对于小票打印,使用的是Host模 ...
- 关于一体机打印新加菜按钮更改为下单小票打印设置FAQ(适用正餐6.0.1.0+,轻餐4.0.6.2+)
适用版本:正餐6.0.1.0+,轻餐4.0.6.2+ 实际场景:更新后小票设置中的打印新加菜按钮更换为下单小票打印设置,更换后,设置中,有3个选项: 1.仅打印新加菜 (选中后,订单加菜后前台小 ...
- linux下使用小票打印
linux下使用小票打印 打印机: Xprinter XP-58IIH指令支持: ESC/POS接口: USB, 蓝牙 Linux系统: Centos7 蓝牙配对很快, 配对好后就是连接状态. 但很快 ...
- Delphi 10 Seattle 小票打印控件TQ_Printer
TQ_Printrer控件,是一个为方便需要控制打印命令而设计的跨平台专用控件,已包含标准ESC/POS打印控制的基本指令在内(这些基本指令已能很好的满足多数项目使用). TQ_Printrer控件让 ...
- Android打印机--小票打印格式及模板设置
小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式须要去查询相应打印机的API文档,这里我把经常使用的api给封装了一下 文字对齐方式 打印字体大小 字体是否加粗 打印二维码 打印条形码 ...
- Atitit.收银机小票打印功能的设计 java php c#.net版本
Atitit.收银机小票打印功能的设计 java php c#.net版本 1. 1. 打印方式有4种:1 1.1. 1.1. 一是不经过任何修改,直接调用javascript中的window.pr ...
- 重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印
重复造轮子系列——基于FastReport设计打印模板实现桌面端WPF套打和商超POS高度自适应小票打印 一.引言 桌面端系统经常需要对接各种硬件设备,比如扫描器.读卡器.打印机等. 这里介绍下桌面端 ...
- 怎样做出通用的pos小票打印程序
POS小票打印机分为热敏和针式俩种. 打印纸的宽度分为58毫米.76毫米和80毫米三种. 打印接口分为:串口.并口.USB和网口(以太网). 热敏打印机速度较快,打印的时候噪音少,针打可以使用多联纸自 ...
随机推荐
- CodeForces 342A Xenia and Divisors (水题)
题意:给定 n 个数(小于等于7),让你把它分成 m 组,每组有三个数,且满足,a < b < c,并且 a 能整除 b,b 能整除 c. 析:对于这个题,因为题目说了是不大于7的,那么一 ...
- unity小记
1.window下的Occlusion Culling是实现遮挡剔除效果,即不再摄像机里出现的物体使其不被渲染. 这样做要使物体为静态的,而且效果在设计时只在Occlusion面板下有效 2.wind ...
- sublime Text2常见插件介绍
zen coding 一种快速编写HTML/CSS代码的方法,已改名为Emmet,并且搭建了一个新的网站:docs.emmet.io Sublime Text 2安装插件Emmet后,打开sublim ...
- Class Loading Deadlocks
By tomas.nilsson on Feb 28, 2010 Mattis keeps going strong, in this installment you get to learn eve ...
- Android-Observer(内容观察者)
内容提供者应用暴露的数据,是被多个其他应用访问(insert,update,delete,query),但如果L应用要查询(内容提供者应用暴露的数据),难道要开启子线程一直循环去查询 ? 答:开启子线 ...
- java中介者模式
中介者模式也是用来降低类类之间的耦合的,因为如果类类之间有依赖关系的话,不利于功能的拓展和维护,因为只要修改一个对象,其它关联的对象都得进行修改.如果使用中介者模式,只需关心和Mediator类的关系 ...
- ibatis 参数之 String
<select id="query_cust_name" resultClass="_custForm" parameterClass="Str ...
- Reporting Service服务SharePoint集成模式安装配置(3、4、安装sharepoint 2010必备组件及产品)
Reporting Service服务SharePoint集成模式安装配置 第三步和第四部 第三步 安装sharepoint 2010必备组件 1.安装SharePoint2010必备组件,执行Pre ...
- 长按tools Icon 弹出Tips音效
快速点击,还没弹出tips,bubble音效已播放 在 Widget_ToolsTips 的 OnAwake 函数加一个延时 transform:DOScale(1, 0.1):OnComlete(f ...
- 魅力 .NET:从 Mono、.NET Core[转]
前段时间,被问了这样一个问题:.NET 应用程序是怎么运行的? 当时大概愣了好久,好像也没说出个所以然,得到的回复是:这是 .NET 程序员最基本的...呵呵! 微软开源,其实不只是对 .NET 本身 ...