C#使用ESC指令控制POS机打印小票.docx
- 文档编号:9958872
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:103
- 大小:40.94KB
C#使用ESC指令控制POS机打印小票.docx
《C#使用ESC指令控制POS机打印小票.docx》由会员分享,可在线阅读,更多相关《C#使用ESC指令控制POS机打印小票.docx(103页珍藏版)》请在冰豆网上搜索。
C#使用ESC指令控制POS机打印小票
C#使用ESC指令控制POS打印机打印小票
1.前言
C#打印小票可以与普通打印机一样,调用PrintDocument实现。
也可以发送标注你的ESC指令实现。
由于调用PrintDocument类时,无法操作使用串口或TCP/IP接口连接的pos打印机,并且无法发送控制指令实现pos打印机的切纸、走纸等动作。
因此个人建议使用ESC指令进行打印会更通用。
本类需要调用ImageProcessor.cs
***************
2.POS机打印小票ReceiptHelper
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
usingSystem.Threading;
usingSystem.Drawing;
usingSystem.Management;
usingSystem.IO;
usingLaisonTech.MediaLib;
usingLaisonTech.CommonBLL;
usingMicrosoft.Win32.SafeHandles;
namespaceLaisonTech.MediaLib
{
#region结构体定义
[StructLayout(LayoutKind.Sequential)]
publicstructOVERLAPPED
{
intInternal;
intInternalHigh;
intOffset;
intOffSetHigh;
inthEvent;
};
[StructLayout(LayoutKind.Sequential)]
publicstructPRINTER_DEFAULTS
{
publicintpDatatype;
publicintpDevMode;
publicintDesiredAccess;
}
///
///对齐方式
///
publicenumeTextAlignMode
{
Left=0,
Middle=1,
Right=2
}
#endregion
///
///小票打印类
///使用方法:
///1GetPrinterList获取已经安装的所有打印机列表.
///Open打开指定打印机
///2控制打印机动作、执行打印内容之前,必须先调用StartPrint,准备向打印机发送控制指令
///3调用SetLeft,SetBold,SetAlignMode,SetFontSize......设置打印参数
///4PrintText打印内容.注意:
打印该行内容后会自动换行(本类会在该行内容末尾添加一个换行符)
///PrintImageFile或PrintBitMap打印图片
///5控制指令和打印内容都发送完毕后,调用EndPrint执行真正打印动作
///6退出程序前调用Close
///
publicclassReceiptHelper
{
#region指令定义
privatestaticByte[]Const_Init=newbyte[]{0x1B,0x40,
0x20,0x20,0x20,0x0A,
0x1B,0x64,0x10};
//设置左边距
privateconststringConst_SetLeft="1D4C";
//设置粗体
privateconststringConst_SetBold="1B45";
privateconstStringConst_Bold_YES="01";
privateconstStringConst_Bold_NO="00";
//设置对齐方式
privateconststringConst_SetAlign="1B61";
privateconstStringConst_Align_Left="30";
privateconstStringConst_Align_Middle="31";
privateconstStringConst_Align_Right="32";
//设置字体大小,与SetBigFont不能同时使用
privateconststringConst_SetFontSize="1D21";
//设置是否大字体,等同于SetFontSize=2
//privateconstStringConst_SetBigFontBold="1B2138";
//privateconstStringConst_SetBigFontNotBold="1B2130";
//privateconstStringConst_SetCancelBigFont="1B2100";
///
///打印并走纸
///
privatestaticByte[]Const_Cmd_Print=newbyte[]{0x1B,0x4A,0x00};
//走纸
privateconststringConst_FeedForward="1B4A";
privateconststringConst_FeedBack="1B6A";
//切纸
privatestaticByte[]Const_SetCut=newbyte[]{0x1D,0x56,0x30};
//查询打印机状态
privatestaticByte[]Const_QueryID=newbyte[]{0x1D,0x67,0x61};
//回复帧以ID开头
privatestaticStringConst_ResponseQueryID="ID";
///
///设置图标的指令
///
privatestaticByte[]Const_SetImageCommand=newByte[]{0x1B,0x2A,0x21};
#endregion
#region常量定义
///
///最大字体大小
///
publicconstInt32Const_MaxFontSize=8;
///
///最大走纸距离
///
publicconstInt32Const_MaxFeedLength=5000;
///
///最大高宽
///
publicconstInt32Const_MaxImageLength=480;
///
///每次通信最多打印的行数
///
publicconstInt32Const_OncePrintRowCount=24;
publicconstInt32Const_BrightnessGate=100;
///
///无效句柄
///
publicconstInt32Const_InvalidHandle=-1;
#endregion
#region私有成员
///
///打印机句柄
///
privateintm_Handle=-1;
///
///是否已经初始化
///
privateBooleanm_Inited=false;
#endregion
#region私有函数
[DllImport("winspool.Drv",EntryPoint="OpenPrinterA",SetLastError=true,CharSet=CharSet.Auto,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolOpenPrinter([MarshalAs(UnmanagedType.LPStr)]stringszPrinter,
outInt32hPrinter,IntPtrpd);
[DllImport("winspool.Drv",EntryPoint="StartDocPrinterA",SetLastError=true,CharSet=CharSet.Ansi,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolStartDocPrinter(Int32hPrinter,Int32level,[In,MarshalAs(UnmanagedType.LPStruct)]DOCINFOAdi);
[DllImport("winspool.Drv",EntryPoint="EndDocPrinter",SetLastError=true,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolEndDocPrinter(Int32hPrinter);
[DllImport("winspool.Drv",EntryPoint="StartPagePrinter",SetLastError=true,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolStartPagePrinter(Int32hPrinter);
[DllImport("winspool.Drv",EntryPoint="EndPagePrinter",SetLastError=true,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolEndPagePrinter(Int32hPrinter);
[DllImport("winspool.Drv",EntryPoint="WritePrinter",SetLastError=true,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolWritePrinter(Int32hPrinter,Byte[]pBytes,Int32dwCount,outInt32dwWritten);
[DllImport("winspool.Drv",EntryPoint="ClosePrinter",SetLastError=true,ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolClosePrinter(Int32hPrinter);
///
///发送指令
///
///
///
privateBooleanSendCommand(Byte[]cmd)
{
if(m_Handle==Const_InvalidHandle||cmd==null||cmd.Length<2)
{
returnfalse;
}
intwritelen=0;
Booleanbl=WritePrinter(m_Handle,cmd,cmd.Length,outwritelen);
if(!
bl)returnfalse;
return(writelen>=cmd.Length);
}
///
///发送文本格式的指令
///
///
///
privateBooleanSendCommand(Stringhexstrcmd)
{
if(m_Handle==Const_InvalidHandle||hexstrcmd==null||hexstrcmd.Length<4)
{
returnfalse;
}
byte[]mybyte=null;
Booleanbl=DataFormatProcessor.HexStringToBytes(hexstrcmd,outmybyte);
bl=SendCommand(mybyte);
returnbl;
}
#endregion
#region内部处理-打印图片
///
///把图片转换为指令字节,图片最大高宽不能超过480
///
///
///
///
publicstaticBooleanLoadImage(Bitmapimage,
refByte[]bitarray,refInt32datawidth,refInt32dataheight)
{
Int32newwidth=0;
Int32newheight=0;
Bitmapdestimage=image;
Booleanbl=false;
//如果高度超过范围,或宽度超过范围,需要进行缩小
if(image.Width>Const_MaxImageLength||image.Height>Const_MaxImageLength)
{
//按照高度和宽度,较大的那一边,进行缩放
if(image.Width>image.Height)
{
newwidth=Const_MaxImageLength;
newheight=(Int32)(image.Height*newwidth/(float)image.Width);
}
else
{
newheight=Const_MaxImageLength;
newwidth=(Int32)(newheight*image.Width/(float)image.Height);
}
bl=ImageProcessor.ResizeImage(image,newwidth,newheight,refdestimage);
}
//把数据转换为字节数组
bl=GetBitArray(image,refbitarray,refdatawidth,refdataheight);
returnbl;
}
///
///把图片转换为指令字节,图片最大高宽不能超过480
///如果图片的高度不是24的整数倍,则修改为24的整数倍
///
///
///
///
publicstaticBooleanLoadImageFromFile(Stringimagefilename,refByte[]bmpbytes,
refInt32width,refInt32height)
{
Bitmapimg=ImageProcessor.LoadBitImage(imagefilename);
if(img==null)
{
returnfalse;
}
Booleanbl=LoadImage(img,refbmpbytes,refwidth,refheight);
returnbl;
}
///
///把图片转换为位图数组,每个字节的每个比特位,对应当前像素是否需要打印
///
///
///
///
publicstaticBooleanGetBitArray(Bitmapimg,
refByte[]allbitary,refInt32width,refInt32height)
{
if(img==null)
{
returnfalse;
}
//ESC指令格式规定:
//1打印图片时,每条指令最多只打印24行;不足24行的,也要用全0填充满数据字节
//2打印24行数据时,按照光栅模式纵向获取数据
//即先获取所有x=0的点(第0列)转换为3个字节;
//再获取所有x=1的点转换为3个字节;...直到获取到最右侧一列的点
//3打印完当前24行数据后,再获取后续24行的数据内容,直到所有的数据获取完毕
//获取亮度数组
Boolean[]briary=null;
Booleanbl=ImageProcessor.ToBooleanArray(img,Const_BrightnessGate,refbriary);
if(!
bl)
{
returnfalse;
}
height=img.Height;//如果图像高度不是24整数倍,设置为24的整数倍
if(height%Const_OncePrintRowCount!
=0)
{
height=height+Const_OncePrintRowCount-height%Const_OncePrintRowCount;
}
width=img.Width;//如果图像宽度不是8的整数倍,设置为8的整数倍
if(width%8!
=0)
{
width=width+8-width%8;
}
Int32bytelen=height*width/8;//每个像素对应1个比特位,因此总字节数=像素位数/8
allbitary=newByte[bytelen];
Int32byteidxInCol=0;//当前列里首个像素,在目标字节数组里的下标
Int32byteidx=0;//当前像素在目标数组里的字节下标
Int32bitidx=0;//当前像素在目标数组里当前字节里的比特位下标
Int32pixidxInCol=0;//当前像素在当前列里的第几个位置
Int32pixidx=0;//当前像素在原始图片里的下标
Int32rowidx=0;//当前处理的像素点所在行,不能超过图像高度
Int32curprocrows=0;//当前需要处理的行数量
while(rowidx { //按照纵向次序,把当前列的24个数据,转换为3个字节 for(Int32colidx=0;colidx { //如果当前还剩余超过24行没处理,处理24行 if(rowidx+Const_OncePrintRowCount<=img.Height) { curprocrows=Const_OncePrintRowCount; } else { //已经不足24行,只处理剩余行数 curprocrows=img.Height-rowidx; } pixidxInCol=0;//本列里从像素0开始处理 for(Int32y=rowidx;y { //原始图片里像素位置 pixidx=y*img.Width+colidx; //获取当前像素的亮度值.如果当前像素是黑点,需要把数组里的对应比特位设置为1 if(briary[pixidx]) { bitidx=7-pixidxInCol%8;//最高比特位对应首个像素.最低比特位对应末个像素 byteidx=byteidxInCol+pixidxInCol/8;//由于最后一段可能不足24行,因此不能使用byteidx++ DataFormatProcessor.SetBitValue(bitidx,true,refallbitary[byteidx]); } pixidxInCol++; } byteidxInCol+=3;//每列固定24个像素,3个字节 } rowidx+=Const_OncePrintRowCount; } returntrue; } #endregion
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C# 使用 ESC 指令 控制 POS 打印