VB.NET Library for thermal printer

Timothy Franceschi 0 Reputation points
2023-03-18T13:37:31.5866667+00:00

Hi All,

I wasted a lot of time trying to print labels with a thermal printer sending ESC POS commands.

The problem is my printer has its own driver, but it does not use a COMx port, but a USBxxx port (in my case USB001) and so many tutorials I found online doesn't work with me.

I know there are many libraries online to manage thermal printer, but it seems there are not for VB.net but only for C.

I found that a possible solution would be to create a virtual COM port mapped to the USB001 port but I don't want to do so.

My problem was that using the thermal printer with its own driver has a very bad quality result, especially when printing something more complex than text, for example a Barcode.

I found a solution to this problem, and this is why I'm writing here. The solution I found is to use System.Drawing.Printing and sending raw data to the printer, not ESC POS codes.

So I made a library available on github (https://github.com/TimothyFran/Simple-.NET-POSPrinter) but I have some problems I would like to ask help with:

  • Alignment: The alignment of the text does not work correctly. At the moment I do this:
Public Sub PrintTextLn(testo As String, Optional align As String = "left")

        Dim textPos As PointF
        Select Case align
            Case "center"
                textPos = CenterPosition(testo)
            Case "right"
                textPos = RightPosition(testo)
            Case Else
                textPos = myPoint
        End Select
        e.Graphics.DrawString(testo, myFont, myBrush, textPos)

        myPoint.Y += lineHeight / 1.1
        myPoint.X = 0

    End Sub

    Private Function CenterPosition(testo As String) As PointF

        'Calcola dimensioni testo
        Dim textSize As SizeF = e.Graphics.MeasureString(testo, myFont)

        'Calcola coordinata X del testo
        Dim centerX As Single = e.MarginBounds.Left + ((e.MarginBounds.Width - textSize.Width) / 2)

        Return New PointF(centerX, myPoint.Y)

    End Function

    Private Function RightPosition(testo As String) As PointF

        ' Calcola le dimensioni del testo con il font specificato.
        Dim textSize As SizeF = e.Graphics.MeasureString(testo, myFont)

        ' Calcola le coordinate del punto di partenza per allineare il testo a destra nell'area di stampa.
        Dim rightX As Single = e.MarginBounds.Right - textSize.Width

        Return New PointF(rightX, myPoint.Y)

    End Function

When aligned on the Left the text is good. But if I try to align on center or right then the text is not correctly aligned. I leave a photo to explain better:

image pos printer result

"POSPrinter" and "Timothy Franceschi" should be centered.

  • Horizontal line: The second problem is with the horizontal line. It should take up the full width of the paper

The actual code is:

Public Sub PrintHLine()
        Dim myPen As New Pen(Color.Black)
        Dim startPoint As New PointF(0, myPoint.Y)
        Dim endPoint As New PointF(e.MarginBounds.Right, myPoint.Y)
        e.Graphics.DrawLine(myPen, startPoint, endPoint)
        myPoint = New PointF(0, myPoint.Y + (lineHeight * 0.8))
    End Sub

Do you have any ideas?

VB
VB
An object-oriented programming language developed by Microsoft that is implemented on the .NET Framework. Previously known as Visual Basic .NET.
2,637 questions
{count} votes

2 answers

Sort by: Most helpful
  1. LesHay 7,126 Reputation points
    2023-03-18T17:38:55.7166667+00:00

    Hi

    I don't have a Printer at the moment, I was using a Brother Thermal Label Printer and always managed to code for it quite straightforwardly.

    I have posted here some code that I created as an answer to a previous question and, I think I tested it on the Printer I mentioned. Of couse, you have no need for the overall function f this code to print contents of a folder.

    Anyway, I suspect that you already know how to do all that I show here, but the main point of interest for your question may be the Doc.Settings at line 26, where you may find if your Printer is actually set to the various size that you expect/think that it is. Worth a look anyway.

    ' Print all files if a folder
    ' either PDF or XPS
    Option Strict On
    Option Explicit On
    Imports System.Drawing.Printing
    Public Class Form1
    	Dim WithEvents PDoc As New PrintDocument
    	'	Dim PrinterName As String = "Microsoft XPS Document Writer"
    	Dim PrinterName As String = "Microsoft Print to PDF"
    	Dim stringToPrint As String = String.Empty
    	'Dim stringToPrint As String = IO.File.ReadAllText("C:\Users\lesha\Desktop\TestDoc.txt")
    
    	Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    		StartPrint(My.Computer.FileSystem.SpecialDirectories.Desktop)
    		Close()
    	End Sub
    	Sub StartPrint(f As String)
    		Dim OutFile As String = String.Empty
    		For Each d As String In IO.Directory.GetFiles(f, "*.txt")
    			stringToPrint = IO.File.ReadAllText(d)
    			Dim exten As String = ".txt"
    			If PrinterName.Contains("Print to PDF") Then exten = ".pdf"
    
    			OutFile = IO.Path.Combine(My.Computer.FileSystem.SpecialDirectories.Desktop, "TestData", IO.Path.GetFileNameWithoutExtension(d) & exten)
    			With PDoc
    				With .PrinterSettings
    					.PrinterName = PrinterName
    					.PrintFileName = OutFile
    					.Copies = 1
    					.PrintToFile = True
    				End With
    				.Print()
    			End With
    		Next
    	End Sub
    	Private Sub PrintDocument1_PrintPage(sender As Object, e As PrintPageEventArgs) Handles PDoc.PrintPage
    
    		' This example Prints the Text from a text
    		' File.  It can be made to print anything
    		' you just have to tell it what needs to
    		' be Printed (and take care of any further
    		' pages to be printed)
    
    		' ******* FROM MS DOCS *******
    
    		Dim charactersOnPage As Integer = 0
    		Dim linesPerPage As Integer = 0
    
    		' Sets the value of charactersOnPage to the number of characters 
    		' of stringToPrint that will fit within the bounds of the page.
    		e.Graphics.MeasureString(stringToPrint, Me.Font, e.MarginBounds.Size,
    				StringFormat.GenericTypographic, charactersOnPage, linesPerPage)
    
    		' Draws the string within the bounds of the page
    		e.Graphics.DrawString(stringToPrint, Me.Font, Brushes.Black,
    				e.MarginBounds, StringFormat.GenericTypographic)
    
    		' Remove the portion of the string that has been printed.
    		stringToPrint = stringToPrint.Substring(charactersOnPage)
    
    		' Check to see if more pages are to be printed.
    		e.HasMorePages = stringToPrint.Length > 0
    
    	End Sub
    End Class
    
    
    0 comments No comments

  2. Timothy Franceschi 0 Reputation points
    2023-03-20T18:09:27.9566667+00:00

    Don't know why. But this solved the problem:

    Public Sub PrintHLine()
            Dim myPen As New Pen(Color.Black)
            Dim startPoint As New PointF(0, myPoint.Y)
            Dim endPoint As New PointF(e.MarginBounds.Right, myPoint.Y)
            e.Graphics.DrawLine(myPen, startPoint, endPoint)
            myPoint = New PointF(0, myPoint.Y + (lineHeight * 0.8))
        End Sub
    
        Private Function CenterPosition(testo As String) As PointF
    
            'Calcola dimensioni testo
            Dim textSize As SizeF = e.Graphics.MeasureString(testo, myFont)
    
            Dim freeSpace As Single = e.PageSettings.PaperSize.Width - textSize.Width
    
            'Calcola coordinata X del testo
            Dim centerX As Single = ((e.PageSettings.PaperSize.Width - textSize.Width) / 2) - (e.PageSettings.Margins.Left / 2)
    
            Return New PointF(centerX, myPoint.Y)
    
        End Function
    
        Private Function RightPosition(testo As String) As PointF
    
            'Calcola dimensioni testo
            Dim textSize As SizeF = e.Graphics.MeasureString(testo, myFont)
    
            Dim freeSpace As Single = e.PageSettings.PaperSize.Width - textSize.Width
    
            'Calcola coordinata X del testo
            Dim centerX As Single = ((e.PageSettings.PaperSize.Width - textSize.Width) / 2)
    
            Return New PointF(centerX, myPoint.Y)
    
        End Function