I once discussed printing directly to the printer in the article below:

Indeed the results in the article are still relatively simple, just plain text. That's why now I want to discuss more about direct printing which is often used to print cashier receipts through the POS (Point of Sales) application.

The basic is PrintDocument. If you want to know about it please check this article.
I created 2 classes for supporting printing process. These classes also allow us to print images or logos and arrange fonts as desired. The classes can be downloaded using below link:
Last updated files on 5/26/2020 

Now, I'll show you how to use them. After downloading those 2 files, copy them into your project/solution as below image.


Open your project on Visual Studio, go to solution explorer. Right-click on your project node then choose Add -> Existing item...

Browse and choose files that we need. Those are Printer.vb and PrintingFormat.vb then click Add button.


Files are added and shown on Solution Explorer.
!!! Make sure you added those 2 files to prevent errors !!!

On UI Design we'll only add a button into the Form1. Printing will be triggered by Button1_Click()



Add Imports System.Drawing.Printing on  the top of Form's code.

Imports System.Drawing.Printing

On this article I use dummy data for printing. Creating some variable and a DataTable for saving detail. Please adjust with your own needed.

Dim StoreName As String = "SERBA ADA STORE"
Dim StoreAddress As String = "Jl. Kehidupan No. 100"
Dim Img As Image = Image.FromFile("c:\logo.jpg")
Dim TransNo As String = "TCN10-20191204-001"
Dim TransDate As String = Format(Now, "yyyy-MM-dd HH:mm:ss")

'for item sales | untuk item penjualan
Dim dtItem As DataTable
Dim arrWidth() As Integer
Dim arrFormat() As StringFormat

'declaring printing format class
Dim c As New PrintingFormat

'for subtotal & qty total
Dim dblSubtotal As Double = 0
Dim dblQty As Double = 0
Dim dblPayment As Double = 50000

DataTable is used to save sales items. I'll fill it manually under Data_Load procedure.

Sub Data_Load()
    dtItem = New DataTable
    With dtItem.Columns
        .Add("itemname", Type.GetType("System.String"))
        .Add("qty", Type.GetType("System.String"))
        .Add("price", Type.GetType("System.String"))
    End With

    Dim ItemRow As DataRow

    ItemRow = dtItem.NewRow()
    ItemRow("itemname") = "Taro Snack"
    ItemRow("qty") = "1"
    ItemRow("price") = "5000"
    dtItem.Rows.Add(ItemRow)

    ItemRow = dtItem.NewRow()
    ItemRow("itemname") = "Kopi Ice"
    ItemRow("qty") = "2"
    ItemRow("price") = "7000"
    dtItem.Rows.Add(ItemRow)

    ItemRow = dtItem.NewRow()
    ItemRow("itemname") = "Lolipop"
    ItemRow("qty") = "5"
    ItemRow("price") = "1000"
    dtItem.Rows.Add(ItemRow)

End Sub

And code sample of using Printer class will be described on below sample code under button1_click event:

Private Sub Button1_Click(sender As Object, e As EventArgs) _
        Handles Button1.Click

    Data_Load()

    Printer.NewPrint()

    Printer.Print(Img, 200, 100)

    'Setting Font
    Printer.SetFont("Courier New", 11, FontStyle.Bold)
    Printer.Print(StoreName) 'Store Name | Nama Toko

    'Setting Font
    Printer.SetFont("Courier New", 8, FontStyle.Regular)
    Printer.Print(StoreAddress & ";", {280}, 0) 'Store Address | Alamat Toko

    'spacing
    Printer.Print(" ")

    Printer.Print(TransNo) ' Transaction No | Nomor transaksi
    Printer.Print(TransDate) ' Trans Date | Tanggal transaksi

    Printer.Print(" ") 'spacing
    Printer.SetFont("Courier New", 8, FontStyle.Bold) 'Setting Font
    arrWidth = {90, 40, 50, 70} 'array for column width | array untuk lebar kolom
    arrFormat = {c.MidLeft, c.MidRight, c.MidRight, c.MidRight} 'array alignment 

    'column header split by ; | nama kolom dipisah dengan ;
    Printer.Print("item;qty;price;subtotal", arrWidth, arrFormat)
    Printer.SetFont("Courier New", 8, FontStyle.Regular) 'Setting Font
    Printer.Print("------------------------------------"'line

    dblSubtotal = 0
    dblQty = 0
    'looping item sales | loop item penjualan
    For r = 0 To dtItem.Rows.Count - 1
        Printer.Print(dtItem.Rows(r).Item("itemname") & ";" & _
                      dtItem.Rows(r).Item("qty") & ";" & _
                      dtItem.Rows(r).Item("price") & ";" & _
                     (dtItem.Rows(r).Item("qty") * _
                      dtItem.Rows(r).Item("price")), arrWidth, arrFormat)
        dblQty = dblQty + CSng(dtItem.Rows(r).Item("qty"))
        dblSubtotal = dblSubtotal + (dtItem.Rows(r).Item("qty") * dtItem.Rows(r).Item("price"))
    Next

    Printer.Print("------------------------------------")
    arrWidth = {130, 120} 'array for column width | array untuk lebar kolom
    arrFormat = {c.MidLeft, c.MidRight} 'array alignment 

    Printer.Print("Total;" & dblSubtotal, arrWidth, arrFormat)
    Printer.Print("Payment;" & dblPayment, arrWidth, arrFormat)
    Printer.Print("------------------------------------")
    Printer.Print("Change;" & dblPayment - dblSubtotal, arrWidth, arrFormat)
    Printer.Print(" ")
    Printer.Print("Item Qty;" & dblQty, arrWidth, arrFormat)

    'Release the job for actual printing
    Printer.DoPrint()

End Sub

Full code:


Let's run and print.


Printing result (I'm using pdf printer)



Okay, I made a mistake while updating file for bug fix. So, As my apologize please download the full source code below. I wrote it using VS2015.