65.9K
CodeProject 正在变化。 阅读更多。
Home

POS 打印: 简单方法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.89/5 (13投票s)

2010年9月16日

CPOL

2分钟阅读

viewsIcon

201897

downloadIcon

12598

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 

结果

Code Results

需要注意的事项

  • 打印机名称是硬编码的,但可以轻松设置为从配置文件读取。
  • 打印机应已定义(已安装驱动程序)到系统中,尤其是在使用“打印预览”(bIsDebug 设置为 true)时,以便预览窗口反映打印机的实际属性(widthfont 等)。

关注点

以下几点可以视为该方法中的问题,并可用于文章的未来开发

  • 在打印时,会显示一个“打印对话框”,在我的案例中(打印小 POS 收据),这发生得足够快,然后消失,但它仍然可以阻止应用程序输入,直到它消失,对于更大的打印输出而言。

历史

  • 2010 年 9 月 16 日:初始发布
© . All rights reserved.