Minggu, 02 Agustus 2020

Vb.Net : Printdocument Dalam Bentuk Tabel

Halo Semuanyah. Sebelum lanjut baca postingan ini, baiknya baca dahulu artikel sebelum nya yah. Biar nyambung gitu.
Mengenal Komponen PrintDocument
Mengatur Font Printing
Mengatur Jarak Antar Baris secara Otomatis
Mengatur Alignment

Dari basic, kita melangkah ke intermediate. Function PrintCellText kita lengkapi menjadi mirip di bawah ini:
Public Function PrintCellText(ByVal strValue As StringByVal x As Integer, _
                              ByVal y As IntegerByVal w As Integer, _
                              ByVal e As System.Drawing.Printing.PrintPageEventArgs, _
                              Font As Font, Format As StringFormat, _
                              Optional Border As Boolean = False, _
                              Optional Fill As Brush = Nothing, _
                              Optional h As Integer = 0) As Integer

    Dim cellRect As RectangleF = New RectangleF()
    cellRect.Location = New Point(x, y)

    If h > 0 Then
        cellRect.Size = New Size(w, h)
    Else
        cellRect.Size = New Size(w, 10 +
                             (CInt(e.Graphics.MeasureString(strValue, Font, w - 10,
                              StringFormat.GenericTypographic).Height)))
    End If

    If IsNothing(Fill) = False Then
        e.Graphics.FillRectangle(Fill, Rectangle.Round(cellRect))
    End If

    e.Graphics.DrawString(strValue, Font, Brushes.Black, cellRect, Format)

    If Border = True Then
        e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(cellRect))
    Else
        e.Graphics.DrawRectangle(Pens.Transparent, Rectangle.Round(cellRect))
    End If

    Return y + cellRect.Size.Height
End Function

Saya menyertakan 3 parameter optional yang memperlihatkan opsi untuk menambahkan garis yang mengelilingi teks (border), memberi warna (fill), dan tinggi yang dapat di setting manual (h).

Selanjutnya mari kita merapikan code kita dengan mengumpulkan function dan format dalam 1 file Class. Kita pakai project yang sudah kita buat sebelumnya lalu tambahkan file class.


Kita beri nama Class ini dengan PrintingFormat, kemudian Add.


Isi dari code dari class ini adalah selaku berikut:


Class PrintingFormat mampu kamu download di link ini.

Dalam class PrintingFormat, Rani cuma menyertakan 3 jenis font saja yang dibuat dalam bentuk property class, ialah:

  • FntTitle untuk judul
  • FntTableHeader untuk header tabel
  • FntTableCell untuk isi cell

Kalian bisa tambahkan atau ubah jenis font sesuai kebutuhan. Untuk design UI masih tetep pakai yang ini:


Sebagai contoh kasus kita akan menampilkan data yang ditampung dalam suatu object DataTable. Rani memilih cara ini karena database apapun yang mau digunakan nantinya dapat ditampung kedalam DataTable. Untuk pola di postingan ini rani buat data yang disertakan secara manual ke dalam DataTable. Saya asumsikan kalian telah paham ihwal pemrograman database yang memuat data ke dalam DataTable, sehingga dapat menyesuaikan code nya.

Dim dt As DataTable

Sub Data_Load()
    dt = New DataTable
    With dt.Columns
        .Add("code", Type.GetType("System.String"))
        .Add("name"Type.GetType("System.String"))
        .Add("address"Type.GetType("System.String"))
    End With

    Dim ItemRow As DataRow

    ItemRow = dt.NewRow()
    ItemRow("code") = "A001"
    ItemRow("name") = "Dwi Nuraeni"
    ItemRow("address") = "Bandung"
    dt.Rows.Add(ItemRow)

    ItemRow = dt.NewRow()
    ItemRow("code") = "A002"
    ItemRow("name") = "Kania Desiani"
    ItemRow("address") = "Jakarta"
    dt.Rows.Add(ItemRow)

    ItemRow = dt.NewRow()
    ItemRow("code") = "A002"
    ItemRow("name") = "Naufal Hartanto"
    ItemRow("address") = "Medan"
    dt.Rows.Add(ItemRow)

End Sub

Dan mengundang sub ini di event form_load.

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Data_Load()

End Sub

Kita juga akan mendeklarasikan beberapa variable yang hendak digunakan untuk mendukung proses printing.

'deklarasi class printing
 Dim pf As PrintingFormat = New PrintingFormat

'Deklarasi untuk mengambil setting default
 Dim PS As System.Drawing.Printing.PageSettings
 Dim PWArea As Integer
 Dim PHArea As Integer
 Dim xZero As Integer
 Dim yZero As Integer
 Dim iPage As Integer
 Dim As Integer 'menampung urutan row

Variable-variable tersebut akan dikontrol pada event print_begin

Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) _
    Handles PrintDocument1.BeginPrint
    PS = PrintDocument1.DefaultPageSettings 'Kita mengambil setting default
    PWArea = PS.PaperSize.Width - (PS.Margins.Left + PS.Margins.Right)
    PHArea = PS.PaperSize.Height - (PS.Margins.Left + PS.Margins.Right)
    xZero = PS.Margins.Left
    yZero = PS.Margins.Top
    iPage = 0 'indikasi nomor halaman
    r = 0 
End Sub

Terakhir instruksi di event PrintDocument1_PrintPage. Penjelasannya ada di code nya dalam bentuk comment ya.

Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) _
    Handles PrintDocument1.PrintPage

    'titik awal diambil dari margin top
    Dim CurY As Integer = yZero

    'print judul hanya di halaman pertama
    If iPage = 0 Then
        CurY = pf.PrintCellText("Member Data", CurY, xZero, PWArea, e, pf.FntTitle, pf.MidCenter)
    End If

    'memberi jarak judul dan tabel
    CurY = CurY + 10

    'code untuk handle jikalau lebih dari satu halaman
    If iPage > 0 Then CurY = yZero

    'menyimpan teks header dalam array
    Dim ColHeader() As String = "Member Code", "Member Name", "Address"

    'menyimpan lebar kolom dalam array
    'lebar diambil dari proporsi lebar area printing
    Dim ColWidth() As Integer = CInt(PWArea * 0.3), CInt(PWArea * 0.3), CInt(PWArea * 0.4)

    'posisi x awal tiap kolom
    Dim ColX(ColWidth.Length - 1) As Integer

    'lebar yang telah digunakan dalam putaran
    'untuk mengkalkulasikan posisi awal kolom
    Dim totColWidth As Integer = xZero

    'variable untuk menampung nilai tinggi abjad yang di-print
    Dim iResult As Integer

    For i As Integer = 0 To ColWidth.Length - 1
        'mengkalkulasikan posisi x awal tiap kolom
        ColX(i) = totColWidth : totColWidth = totColWidth + ColWidth(i)
        'print table header
        iResult = pf.PrintCellText(ColHeader(i), ColX(i), CurY, ColWidth(i), e, _
                  pf.FntTableHeader, pf.MidCenter, True)
    Next

    'ambil posisi y dari tinggi char yang terakhir di-print
    CurY = iResult

    Do While r <= dt.Rows.Count - 1
        'print nilai masing-masing cell
        iResult = pf.PrintCellText(dt.Rows(r)("code"), ColX(0), CurY, ColWidth(0), e, _
                  pf.FntTableCell, pf.MidLeft, True)
        iResult = pf.PrintCellText(dt.Rows(r)("name"), ColX(1), CurY, ColWidth(1), e, _
                  pf.FntTableCell, pf.MidLeft, True)
        iResult = pf.PrintCellText(dt.Rows(r)("address"), ColX(2), CurY, ColWidth(2), e, _
                  pf.FntTableCell, pf.MidLeft, True)

        'ambil posisi y dari tinggi char yang terakhir di-print
        CurY = iResult

        'kalau sudah 90% hari tinggi print area, halaman baru
        If CurY >= 0.9 * PHArea Then
            e.HasMorePages = True
            iPage += 1
            r += 1
            Return
        End If

        r += 1
    Loop

    If r = dt.Rows.Count Then e.HasMorePages = False

End Sub

arahan "Imports System.Drawing.Printing" jangan hingga lupa dan kelewat ya.
Kode lengkap dibalik Form1 adalah selaku berikut:



Kita coba run dan print:


Hasilnya:


Temen-temen coder, khusus di postingan ini diasumsikan cell cuma akan punya 1 baris nilai saja. Karena klo nilainya hingga 2 baris atau lebih, dijamin berantakan hehehe...
Makara gimana klo pengen multiline? Jawabannya di postingan selanjutnya yah.

PrintDocument dalam Bentuk Tabel Multiline

Maksudnya Rani jelasin step by step biar temen2 pada paham tentang aba-aba berikutnya yang hendak Rani tambahin.




Sumber http://rani-irsan.blogspot.com


EmoticonEmoticon

:)
:(
hihi
:-)
:D
=D
:-d
;(
;-(
@-)
:o
:>)
(o)
:p
:-?
(p)
:-s
8-)
:-t
:-b
b-(
(y)
x-)
(h)