POS 打印: 简单方法






4.89/5 (13投票s)
VB6 打印对象也支持打印到 POS 打印机。 在本文中,我们将了解为什么以及如何实现。
引言
这是一个帮助开发者以简单的方式设计 POS 打印表单的类。 开发者可以添加图像(徽标、广告等);可以轻松使用任何语言和任何方向(从右到左、从左到右);并且可以使用打印预览来节省为测试打印的纸张。
背景
使用 EPS/POS 标准进行 POS 打印被证明很困难,在花费数天设计打印类后,我无法写出阿拉伯文字,原因不明。 打印图像需要大量的代码,并且由于您可能需要构建一个引擎来解析这些特定的标准代码以在屏幕上显示它们,因此打印预览几乎是不可能的。
一个更简单的解决方案是使用经典的 VB 打印对象,不熟悉打印对象的人可以阅读更多相关信息 此处。
要在 VB.NET 代码中使用 VB 6.0 的经典打印类,您需要使用 PowerPack 兼容性库,可以从 此处 下载。
Using the Code
首先,将 Microsoft.VisualBasic.PowerPacks
添加到项目的引用中。
在整个代码中需要一些导入
Imports System.Drawing
Imports Microsoft.VisualBasic.PowerPacks.Printing.Compatibility.VB6
一些声明和需要的 Enum
Private p As Printer
Private _Path As String
Private _Align As TextAlignment = TextAlignment.Default
Private bIsDebug As Boolean = True
Public Enum TextAlignment As Byte
[Default] = 0
Left
Center
Right
End Enum
现在,类构造函数将打印机名称作为参数,以及应用程序路径,用于构造要使用的图像的路径(如果有的话),您可以传递 Application.StartupPath
用于此目的。
#Region "Constructors"
Public Sub New(ByVal AppPath As String)
SetPrinterName("GP-80220II (USB2)", AppPath)
End Sub
Public Sub New(ByVal strPrinterName As String, ByVal AppPath As String)
SetPrinterName(strPrinterName, AppPath)
End Sub
Private Sub SetPrinterName(ByVal PrinterName As String, ByVal AppPath As String)
Dim prnPrinter As Printer
For Each prnPrinter In Printers
If prnPrinter.DeviceName = PrinterName Then
p = prnPrinter
Exit For
End If
Next
p.DocumentName = "ERP System"
Me.Path = AppPath
If bIsDebug Then
p.PrintAction = Printing.PrintAction.PrintToPreview
End If
End Sub
#End Region
我使用了以下字体大小,这对于我的情况是合适的。 请根据您的需要随意更改。
- 常规字体:9.5
- 大字体:15
- 小字体:6
以下代码显示了控制字体的属性
#Region "Font"
Public Property Alignment() As TextAlignment
Get
Return _Align
End Get
Set(ByVal value As TextAlignment)
_Align = value
End Set
End Property
Public Sub AlignLeft()
_Align = TextAlignment.Left
End Sub
Public Sub AlignCenter()
_Align = TextAlignment.Center
End Sub
Public Sub AlignRight()
_Align = TextAlignment.Right
End Sub
Public Property FontName() As String
Get
Return p.FontName
End Get
Set(ByVal value As String)
p.FontName = value
End Set
End Property
Public Property FontSize() As Single
Get
Return p.FontSize
End Get
Set(ByVal value As Single)
p.FontSize = value
End Set
End Property
Public Property Bold() As Boolean
Get
Return p.FontBold
End Get
Set(ByVal value As Boolean)
p.FontBold = value
End Set
End Property
Public Sub DrawLine()
p.DrawWidth = 2
p.Line(p.Width, p.CurrentY)
p.CurrentY += 20 ' to move under the drawn line
End Sub
Public Sub NormalFont()
Me.FontSize = 9.5F
End Sub
Public Sub BigFont()
Me.FontSize = 15.0F
End Sub
Public Sub SmallFont()
Me.FontSize = 6.0F
End Sub
Public Sub SetFont(Optional ByVal FontSize As Single = 9.5F, _
Optional ByVal FontName As String = "FontA1x1", _
Optional ByVal BoldType As Boolean = False)
Me.FontSize = FontSize
Me.FontName = FontName
Me.Bold = BoldType
End Sub
#End Region
对于图像打印,我使用了 PrintLogo sub
,但您可以使用通用方法(例如下面的 PrintImage
)。
#Region "Images"
Public Property Path() As String
Get
Return _Path
End Get
Set(ByVal value As String)
_Path = value
End Set
End Property
Public Sub PrintLogo()
Me.PrintImage(_Path & "\Logo.bmp")
End Sub
Private Sub PrintImage(ByVal FileName As String)
Dim pic As Image
pic = pic.FromFile(FileName)
p.PaintPicture(pic, p.CurrentX, p.CurrentY)
p.CurrentY = p.CurrentY + pic.Height
End Sub
#End Region
现在,对于我的情况,我将纸张分成 6 个部分(六分之一)以便于控制。 这可能适合您的案例,但如果不是,您可以轻松更改它。
另外请注意,我的打印机以常规字体打印 48 个字符,因此我也将纸张分成 48 列。
#Region "Control"
Public Sub NewPage()
p.NewPage()
End Sub
Public Property RTL() As Boolean
Get
Return p.RightToLeft
End Get
Set(ByVal value As Boolean)
p.RightToLeft = value
End Set
End Property
Public Sub FeedPaper(Optional ByVal nlines As Integer = 3)
For i As Integer = 1 To nlines
Me.WriteLine("")
Next
End Sub
Public Sub GotoCol(Optional ByVal ColNumber As Integer = 0)
Dim ColWidth As Single = p.Width / 48
p.CurrentX = ColWidth * ColNumber
End Sub
Public Sub GotoSixth(Optional ByVal nSixth As Integer = 1)
Dim OneSixth As Single = p.Width / 6
p.CurrentX = OneSixth * (nSixth - 1)
End Sub
Public Sub UnderlineOn()
p.FontUnderline = True
End Sub
Public Sub UnderlineOff()
p.FontUnderline = False
End Sub
Public Sub EndDoc()
p.EndDoc()
End Sub
Public Sub EndJob()
Me.EndDoc()
End Sub
Public Sub WriteLine(ByVal Text As String)
Dim sTextWidth As Single = p.TextWidth(Text)
Select Case _Align
Case TextAlignment.Default
'do nothing
Case TextAlignment.Left
p.CurrentX = 0
Case TextAlignment.Center
p.CurrentX = (p.Width - sTextWidth) / 2
Case TextAlignment.Right
p.CurrentX = (p.Width - sTextWidth)
End Select
p.Print(Text)
End Sub
Public Sub WriteChars(ByVal Text As String)
p.Write(Text)
End Sub
Public Sub CutPaper()
p.NewPage()
End Sub
#End Region
为了使用该类,正在创建一个示例收据,请参阅代码和生成的打印输出。
Dim P As New PrinterClass(Application.StartupPath)
With P
'Printing Logo
.RTL = False
.PrintLogo()
'Printing Title
.FeedPaper(4)
.AlignCenter()
.BigFont()
.Bold = True
.WriteLine("Sales Receipt")
'Printing Date
.GotoSixth(1)
.NormalFont()
.WriteChars("Date:")
.WriteLine(DateTime.Now.ToString)
.DrawLine()
.FeedPaper(2)
'Printing Header
.GotoSixth(1)
.WriteChars("#")
.GotoSixth(2)
.WriteChars("Description")
.GotoSixth(5)
.WriteChars("Count")
.GotoSixth(6)
.WriteChars("Total")
.WriteLine("")
.DrawLine()
'.FeedPaper(1)
'Printing Items
.SmallFont()
Dim i As Integer
For i = 1 To 6
.GotoSixth(1)
.WriteChars(i)
.GotoSixth(2)
.WriteChars("Item# " & (Rnd() * 100) \ 1)
.GotoSixth(5)
.WriteChars(Rnd() * 10 \ 1)
.GotoSixth(6)
.WriteChars((Rnd() * 50 \ 1) & " JD(s)")
.WriteLine("")
Next
'Printing Totals
.NormalFont()
.DrawLine()
.GotoSixth(1)
.UnderlineOn()
.WriteChars("Total")
.UnderlineOff()
.GotoSixth(5)
.WriteChars((Rnd() * 300 \ 1) & " JD(s)")
.CutPaper() ' Can be used with real printer to cut the paper.
'Ending the session
.EndDoc()
End With
结果

需要注意的事项
- 打印机名称是硬编码的,但可以轻松设置为从配置文件读取。
- 打印机应已定义(已安装驱动程序)到系统中,尤其是在使用“打印预览”(
bIsDebug
设置为true
)时,以便预览窗口反映打印机的实际属性(width
、font
等)。
关注点
以下几点可以视为该方法中的问题,并可用于文章的未来开发
- 在打印时,会显示一个“打印对话框”,在我的案例中(打印小 POS 收据),这发生得足够快,然后消失,但它仍然可以阻止应用程序输入,直到它消失,对于更大的打印输出而言。
历史
- 2010 年 9 月 16 日:初始发布