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:
- PrintingFormat.vb --> for formating printing object
- Printer.vb --> for sending a print command Directly to printer
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.
21 Comments
Thank You sir for the reply.
I am trying to create a project which will use Epson TM U220 and would like the printer font to be used as It will be fast and not send font from the code. Can you help me with how to tweak the code.
How can I adjust the width of the print area to taker up a whole receipt? 80mm> Currently it's only using about 75% of the usable width of the paper.
Also, how can I reduce white space at the top and bottom of the receipt. When printing, there is roughly 4 inches of blank space at the top and about 10 inches of white space at the bottom.
Printer.Print(Img, 200, 100) '-- 200 is width
or for table layout
arrWidth = {90, 40, 50, 70} 'array for column width
Printer.Print("item;qty;price;subtotal", arrWidth, arrFormat)
each column set by the array value.
For paper/page size I use default setting from printer, because here we're targeting mini printer for POS that has continous paper and also has special setting. Please check your printer setting otherwise you have to modify PageSettings in printer class.
Does this has a C# version .. can you post the link
how to limit or cut item character when character exceed the limit on arrWidth...
thanks
But if you want to limit just use the Left string as below:
Dim str As String = "Ultra Milk UHT 100 ml plain low fat"
str = Microsoft.VisualBasic.Left(str, 10)
Try to change code in Printer.vb
On SUb DoPrint as below:
Public Shared Sub DoPrint()
prn.PrinterSettings.PrinterName = "doPDF 7"
prn.Print()
End Sub
"doPDF 7" is a printer name, change it to yours.
arrWidth = {250}
arrFormat = {c.MidCenter}
Printer.Print("Your Text", arrWidth, arrFormat)