Something like this:
It will be easier to understand if you read previous articles.
Introducing PrintDocument Component
Setting Font for PrintDocument Printing
Setting Vertical (Y) Position Automatically on PrintDocument
Setting Alignment
We're getting to an intermediate level. Let's modify PrintCellText Function into the following code:
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 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
See the highlighted text for detail of changes. I also add 3 optional parameters. Border, fill (for fill color), and h for the height that manually set.
Next, we're going to tidy up the code into a class file. We're still using our previous project. Add a class by selecting menu Project -> Add Class...
Name it with PrintingFormat, then click Add.
This code is written in the class, you may copy it. But hopefully, you try to understand each code in it.
You can also download PrintingFormat Class here.
In this class, I only put 3 type of font to be used.
- FntTitle untuk judul
- FntTableHeader untuk header tabel
- FntTableCell untuk isi cell
You can add your own font type if needed. Then for UI still using this following:
For example, printing data that contain in DataTable. In this case, I'll manually add ItemRow into DataTable. I use DataTable so you can adjust into your own project using any database. I assume that you've already familiar with database programming. Especially fill data into DataTable.
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
Call sub procedure in form_load event.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Data_Load()
End Sub
We'll also declare some variable that used for this printing process.
'declaring class printing
Dim pf As PrintingFormat = New PrintingFormat
'declaring veriable for default setting
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 'variable for saving row number
The values of those variables will be set on print_begin event.
Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) _
Handles PrintDocument1.BeginPrint
PS = PrintDocument1.DefaultPageSettings 'get default setting
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 'indicate page number
r = 0
End Sub
Last in PrintDocument1_PrintPage event. I put comment in code for its descriptions. (green colored)
Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) _
Handles PrintDocument1.PrintPage
'get starting point of y from top margin
Dim CurY As Integer = yZero
'print title only on the first page.
If iPage = 0 Then
CurY = pf.PrintCellText("Member Data", CurY, xZero, PWArea, e, pf.FntTitle, pf.MidCenter)
End If
'give space between title and table
CurY = CurY + 10
'code to handle if more than one page
If iPage > 0 Then CurY = yZero
'for saving header text in array
Dim ColHeader() As String = {"Member Code", "Member Name", "Address"}
'for saving columns width in array
'get width with proportional of printing area width
Dim ColWidth() As Integer = {CInt(PWArea * 0.3), CInt(PWArea * 0.3), CInt(PWArea * 0.4)}
'starting position of x for each columns
Dim ColX(ColWidth.Length - 1) As Integer
'width value that already used in 1 loop
'for counting starting point on each columns
Dim totColWidth As Integer = xZero
'variable to save height of character that printed
Dim iResult As Integer
For i As Integer = 0 To ColWidth.Length - 1
'ounting starting point on each columns
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
'get y position from the height of last text printed
CurY = iResult
Do While r <= dt.Rows.Count - 1
'print text value each 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)
'get y position from the height of last text printed
CurY = iResult
'create and go to the next page if already reached 90% height of printing area.
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
Don't forget to add "Imports System.Drawing.Printing", and this below is the complete code:
Try to run and print.
Result:
I give you step by step tutorial so it's clearer to understand each code in it. For this step, I only show you how to display single-line text in each cell.
To make it works with multiline text in cell, read also this article:
PrintDocument, Creating/Printing Table with Multiline Cell
0 Comments