VB.NET: Mencetak dengan POS Printer

Rani lihat banyak yang tertarik dengan artikel print langsung ke printer.
Sejujurnya artikel itu buat catatan buat nge-print transaksi POS, tapi ya memang terlalu simple dan plain cuman text doank.

Sebenarnya dasar dari printing yang digunakan ini adalah objek PrintDocument, jadi klo temen-temen pengen lebih mengenal object ini bisa baca juga artikel:


Banyak pertanyaan masuk seperti gimana jika ingin menambahkan logo atau image saat mencetak, kalau jenis font nya beda-beda tiap baris, kalau begini dan kalau begitu hehehe...
Jadinya Rani mau rangkum jejak waktu coding aplikasi POS a.k.a aplikasi kasir dalam 2 class yang bisa teman-teman coder download pada link di bawah ini:


Notes: last update printer.vb 26 Mei 2020 (bug fix)

Class PrintingFormat bisa digunakan juga dalam pembuatan report atau printing dengan object PrintDocument, contoh nya ada di artikel printing dengan format tabel.

Langsung aja kita praktekin cara menggunakan class ini ya, kedua class harus include dalam project/solution. Di bawah ini Rani kasih contoh gimana biar file Printer.vb include ke dalam project. Copy paste dulu class yang sudah di download ke dalam folder project kalian yah


Lalu buka peoject kalian dan sorot Project di solution explorer dengan mouse, klik kanan dan pilih Add -> Existing item...

Browse dan pilih class yang mau kita include kemudian klik tombol Add.


File class yang ditambahkan akan muncul di solution explorer.
!!! Jangan lupa menambahkan kedua class ya, biar ga error !!!



UI Design yang kita pakai hanya menambahkan button pada form saja, saat click button proses printing akan dimulai.



Pada jendela code Form1, Imports System.Drawing.Printing

Imports System.Drawing.Printing

Untuk data yang akan dicetak, silahkan menyesuaikan dengan keperluan. Di sini Rani kasih contoh dalam bentuk variable dan datatable aja ya, biar gampang menjelaskan nya.

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 digunakan untuk menyimpan item jual, saya juga akan mengisi manual dalam sub sebagai berikut:
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

Dan penggunaan class printer akan dijelaskan secara lebih detail dengan contoh code dibawah event button1_click sebagai berikut:
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

Kode lengkapnya:


Mari kita coba run dan print.


Hasilnya kira-kira sebagai berikut:


Okay, I made a mistake haha... waktu update error pertama sepertinya ada yang terhapus. Sekarang insya Allah udah di update lagi. Dan sebagai permohonan maaf Rani buatkan sekalian project sample yang bisa di download:



Post a Comment

32 Comments

Anonymous said…
Halo Mbak Rani,

Artikelnya sangat membantu.

Kalo boleh minta petunjuknya, kl data yang dicetak diambil dari database codingnya harus bagaimana ya.

Thanks.
rani said…
tergantung cara yang kamu pakai buat narik/nampilin data dari database nya.
klo rani biasa nya ambil dan simpan dulu dalam bentuk datatable. Baru ambil value dari situ.
looping klo terdiri dari beberapa baris.
ahmfarisi said…
halo mbak rani, terimakasih atas tutorialnya, sangat membantu.

Mbak, mau tanya, adakah tutor untuk C# untuk print ke printer POS seperti yang mbak lakukan di VB pada artikel ini?
rani said…
untuk versi C# rani belum buat, Insya Allah klo ada kesempatan saya buatkan,
Asta said…
halo mbak rani, terimakasih tutorialnya, cuma saya mau bertanya untuk class printernya, ada bbrapa error list, 1. type 'cellalign' is not defined. 2. 'PrintCellText' is not declared.. mau bertanya ttg error listnya mbak, bagaimana cara benerin nya? terimakasih
rani said…
Coba baca lagi artikel nya. Ada 2 file yang harus di download dan di include dalam project yaitu PrintingFormat.vb dan Printer.vb. Sudah belum?
Unknown said…
iya sudah saya masukan kedua class sesuai intruksinya mbak, cuma muncul tulisan seperti itu setelah di debug. terimakasih
rani said…
Hallo @Asta,
Kayaknya emang ada kesalahan waktu rani update source file nya. Maafkaaan....Sekarang sudah diperbaiki lagi. Asta & temen2 coder lainnya juga bisa download project secara utuh di bagian paling bawah artikel. FYI, rani pakai VS2015.
Hinoob said…
iya mbak sama persis, saya contoh langkah2 nya mbak rani. tp untuk print yg ke2x ttp kosong. apanya ya mbak kira2 yang keliru?
rani said…
@Hinoob: variable row nya belum ke reset kayak nya. Coba di file Printer.vb di bawah sub NewPrint ditambahkan row = 0.

Public Shared Sub NewPrint()
PrintDatalist = New PrintDatalist
_myfont = New Font("Courier New", 8, FontStyle.Regular, GraphicsUnit.Point) 'Default
prn = New Printing.PrintDocument
row = 0
Dim PS1 As New System.Drawing.Printing.PageSettings
With PS1
.PaperSize = (From s As PaperSize In prn.PrinterSettings.PaperSizes.Cast(Of PaperSize)()).FirstOrDefault
.Margins.Left = 0
.Margins.Right = 0
.Margins.Top = 0
.Margins.Bottom = 0
End With
prn.DefaultPageSettings = PS1

AddHandler prn.PrintPage, AddressOf Document_PrintPage
End Sub
Hinoob said…
Wihhhhh mantap mbak rani, sudah bisa print berkali2, smooth pula :D
Maturnuwun
Andre said…
Mba Rani mau nanya dong..
Kalo data item barangnya dari datagridview gimana yak mba..
Makasih
rani said…
sama aja pas looping ambil data dari cell value. Misalnya datagridview namanya grdData.

grdData.Rows(r).Cells(c).Value

r - index baris
c - index kolom
Arya Isfandiari said…
Kalau saya print dengan menggunakan ASP.Net apakah sama cara nya? karena contoh ini menggunakan Windows Form.

Mohon bantuannya bu, karena saya baru ini mengerjakan proyek tersebut, proyek saya menggunakan ASP.Net WebForms dan kebetulan bahasa nya sama VB.NET

Maaf saya komen di artikel ibu yang lain juga, yang pakai bahasa inggris
rani said…
@Arya: bisa, saya udah coba. Tapi perlu sedikit modifikasi.
Di masing-masing file bagian atas kan ada Imports System.Drawing.Printing
nah di bawahnya ditambahin Imports System.Drawing

trus untuk image, klo ambil dari url:
Dim tClient As Net.WebClient = New Net.WebClient
Dim Img As Image = Image.FromStream(New IO.MemoryStream(tClient.DownloadData("https://cdn.iconscout.com/icon/free/png-256/youtube-85-226402.png")))
Arya Isfandiari said…
Wah terima kasih bu untuk jawabannya, akan langsung saya coba. saya berjam-jam cari sana-sini enggak dapet2 caranya. terima kasih banyak sekali lagi
Arya Isfandiari said…
Halo bu, terima kasih banyak, saya sudah bisa print ke printer thermal, mantap!
Oiya tapi saya mau tanya, kalau untuk setting di kertas 58mm itu bagaimana caranya ya?
Unknown said…
halo mba rani,
saya sudah ikutin sesuai instruksi mba rani, tapi muncul keterangan Expression Expected di value arraynya yah.
Printer.Print(StoreAddress & ";", {280}, 0) 'Store Address | Alamat Toko


solusinya bagaimana yah mba?
saya pakai visual basic express edition 2008/

mkasih mba...,
rani said…
apa file yang harus di download nya udah include ke project?
coba lebih detail lagi keterangan nya
Unknown said…
Udah mba. Printer.vb sama printinhformat.vb

Keterangan errornya hanya expression expected aja mba.

Printer.Print(StoreAddress & ";", {280}, 0) 'Store Address | Alamat Toko

Disimbol kurung kurawal {280} mba
rani said…
rani blom coba di VS2008 sih, itu pakai 2015 dan 2017. Mungkin blom support penulisan array seperti itu.
Coba aja array nya dideklarasikan dulu diatas nya baru di tulis variable nya disitu:
arrWidth = {280}
Printer.Print(StoreAddress & ";", arrWidth, 0)
Unknown said…
terimakasih bu rani, sudah saya coba class printer nya, keren banget.. ini saya asta yg 6 bulan lalu balas pesan disini.. baru saya coba hari ini
Wendra said…
This comment has been removed by the author.
Wendra said…
Kalau ingin mencetak menggunakan font bawaan printer Epson LX310, misalnya font Draft 17cpi yang size-nya sudah fixed, gimana ya, Mbak Rani?
rani said…
@wendra: code di artikel diatas di bawah event Button1_Click ada untuk setting font.
'Setting Font
Printer.SetFont("Courier New", 11, FontStyle.Bold)
Printer.Print(StoreName) 'Store Name | Nama Toko

Artikel printing ini lebih cocok dipakai di printer semacam Epson TMU.
Klo printer EpsonLX yang ukuran kertas nya sudah fix (tidak continous) enakan pake RDLC sih.
Wendra said…
Kalau Courier New bukan bawaan printer, Mbak Rani. Saya mau pakai font Draft 17Cpi, Draft 20Cpi, yang hanya ada di printer Epson dor matrix. Ukuran font-nya ya 17 Cpi (character per inch) yang tidak bisa diubah-ubah. Kalau saya paksakan dgn perintah ini misalnya: Printer.SetFont("Draft 17Cpi", 11, FontStyle.Bold), font yang kecetak malah jadi Arial.
Wendra said…
Oh iya, jenis font itu (Draft 15Cpi, Draft 17Cpi, Draft 20Cpi) hanya keluar jika komputer terhubung dengan printer Epson jenis dot-matrix. Jika koneksi dengan printer terputus, font-nya juga akan menghilang dari daftar font Windows. Mengapa saya ingin menggunakan font ini? Karena selain hasil printernya rapi, proses cetaknya juga sangat cepat.
rani said…
Trial error printer, mesti langsung ada printer nya sih. Klo di printer nya sih settingan printernya kayak gini:
Klik buat lihat foto printer nya
HSD
Draft
Roman
Sans Serif

Setahu rani, font default printer nya sesuai dengan nyala lampu indikator itu.
Boleh juga dicoba pakai default font system.
Private defaultFont As Font = SystemFonts.DefaultFont

Semoga berhasil.
Eli Shu said…
Ka,kalo logonya biar rata tengah gimana ya caranya
Belajar Coding said…
mbak inikan data ngambil dari form,klo datanya ngambil dari database mysql gmn ya, untuk keperluan cetak ulang,trims
siswanto said…
halo mba, saya mau tanya bagaimna caranya supaya text rata tengah
Terimakasih
admin said…
Mau rata tengah gunakan rumus matematika dengan menghitung lebar kertas di bagi dengan yang mau di print pasti rata tengah