Skip to main content

PrintDocument dalam Bentuk Tabel

VB.NET : PrintDocument dalam Bentuk Tabel

Halo Semuanyah. Sebelum lanjut baca artikel ini, baiknya baca dulu 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 seperti di bawah ini:
Public Function PrintCellText(ByVal strValue As StringByVal As Integer, _
                              ByVal As IntegerByVal As Integer, _
                              ByVal As System.Drawing.Printing.PrintPageEventArgs, _
                              Font As Font, Format As StringFormat, _
                              Optional Border As Boolean False, _
                              Optional Fill As Brush Nothing, _
                              Optional 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 menambahkan 3 parameter optional yang memberikan pilihan 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 sebagai berikut:
Imports System.Drawing.Printing

Public Class PrintingFormat

    Private mTopLeft As StringFormat = New StringFormat()
    Private mTopCenter As StringFormat = New StringFormat()
    Private mTopRight As StringFormat = New StringFormat()
    Private mMidLeft As StringFormat = New StringFormat()
    Private mMidCenter As StringFormat = New StringFormat()
    Private mMidRight As StringFormat = New StringFormat()
    Private mBotLeft As StringFormat = New StringFormat()
    Private mBotCenter As StringFormat = New StringFormat()
    Private mBotRight As StringFormat = New StringFormat()

    Public ReadOnly Property FntTitle() As Font
        Get
            Return New Font("Arial", 12, FontStyle.Bold, GraphicsUnit.Point)
        End Get
    End Property

    Public ReadOnly Property FntTableHeader() As Font
        Get
            Return New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)
        End Get
    End Property

    Public ReadOnly Property FntTableCell() As Font
        Get
            Return New Font("Arial", 10, FontStyle.Regular, GraphicsUnit.Point)
        End Get
    End Property


    Public ReadOnly Property TopLeft As StringFormat
        Get
            mTopLeft.LineAlignment = StringAlignment.Near
            mTopLeft.Alignment = StringAlignment.Near
            Return mTopLeft
        End Get
    End Property

    Public ReadOnly Property TopCenter As StringFormat
        Get
            mTopCenter.LineAlignment = StringAlignment.Near
            mTopCenter.Alignment = StringAlignment.Center
            Return mTopCenter
        End Get
    End Property

    Public ReadOnly Property TopRight As StringFormat
        Get
            mTopRight.LineAlignment = StringAlignment.Near
            mTopRight.Alignment = StringAlignment.Far
            Return mTopRight
        End Get
    End Property

    Public ReadOnly Property MidLeft As StringFormat
        Get
            mMidLeft.LineAlignment = StringAlignment.Center
            mMidLeft.Alignment = StringAlignment.Near
            Return mMidLeft
        End Get
    End Property

    Public ReadOnly Property MidCenter As StringFormat
        Get
            mMidCenter.LineAlignment = StringAlignment.Center
            mMidCenter.Alignment = StringAlignment.Center
            Return mMidCenter
        End Get
    End Property

    Public ReadOnly Property MidRight As StringFormat
        Get
            mMidRight.LineAlignment = StringAlignment.Center
            mMidRight.Alignment = StringAlignment.Far
            Return mMidRight
        End Get
    End Property

    Public ReadOnly Property BotLeft As StringFormat
        Get
            mBotLeft.LineAlignment = StringAlignment.Far
            mBotLeft.Alignment = StringAlignment.Near
            Return mBotLeft
        End Get
    End Property

    Public ReadOnly Property BotCenter As StringFormat
        Get
            mBotCenter.LineAlignment = StringAlignment.Far
            mBotCenter.Alignment = StringAlignment.Center
            Return mBotCenter
        End Get
    End Property

    Public ReadOnly Property BotRight As StringFormat
        Get
            mBotRight.LineAlignment = StringAlignment.Far
            mBotRight.Alignment = StringAlignment.Far
            Return mBotRight
        End Get
    End Property


    Public Function PrintCellText(ByVal strValue As String, ByVal x As Integer, ByVal y As Integer,
                              ByVal w As Integer, ByVal e As System.Drawing.Printing.PrintPageEventArgs,
                              Font As Font, Format As StringFormat, Optional ByVal 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

End Class
Class PrintingFormat bisa kamu download di   iLink ni.

Dalam class PrintingFormat, Kita hanya menambahkan 3 jenis font saja yang dibuat dalam bentuk property class, yaitu:

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

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


Sebagai contoh kasus kita akan menampilkan data yang ditampung dalam sebuah object DataTable. Kitai memilih cara ini karena database apapun yang akan dipakai nantinya dapat ditampung kedalam DataTable. Untuk contoh di artikel ini kita buat data yang ditambahkan secara manual ke dalam DataTable. Saya asumsikan kalian sudah paham tentang pemrograman database yang menampung 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 memanggil sub ini di event form_load.

Private Sub Form1_Load(sender As Object, e As EventArgsHandles MyBase.Load

    Data_Load()

End Sub

Kita juga akan mendeklarasikan beberapa variable yang akan 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 diatur 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 kode 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 jika 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 menghitung posisi awal kolom
    Dim totColWidth As Integer = xZero

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

    For As Integer = 0 To ColWidth.Length - 1
        'menghitung 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

        'jika 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

kode "Imports System.Drawing.Printing" jangan sampai lupa dan kelewat ya.
Kode lengkap dibalik Form1 adalah sebagai berikut:
Imports System.Drawing.Printing

Public Class Form1

    Dim dt As DataTable

    '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 r As Integer'menampung urutan row

    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

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

        Data_Load()

    End Sub

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

        PrintDocument1.Print()

    End Sub

    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

    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 jika 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 menghitung posisi awal kolom
        Dim totColWidth As Integer = xZero

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

        For i As Integer = 0 To ColWidth.Length - 1
            'menghitung 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

            'jika 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

End Class

Kita coba run dan print:


Hasilnya:


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

PrintDocument dalam Bentuk Tabel Multiline

Maksudnya Sayai jelasin step by step biar temen2 pada paham tentang kode selanjutnya yang akan ditambahin. 

Comments

Popular posts from this blog

Download Berbagai Font Notasi Angka Terbaik dan Cara Penulisan di MS Word

Font Notasi Angka Untuk membuat Partitur Lagu Not Angka

16+ Font dan Kode untuk Membuat Simbol Musik di Word