Imports System.Drawing.Printing
Imports System.Text
Public Class Form1
Inherits System.Windows.Forms.Form
Private Structure EmployeeData
Dim EmployeeName As String
Dim NRIC As String
Dim AccountNumber As String
Dim Salary As String
End Structure
Private myCollection As New Collection()
Private subtotals As Decimal = 0
Private pagetotal As Decimal = 0
[+Windows Designer Generated Code]
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
'setup a collection representing some test values
Dim myEmployeedata As EmployeeData
myEmployeedata.AccountNumber = "1232322"
myEmployeedata.EmployeeName = "Thai Xung"
myEmployeedata.NRIC = "???"
myEmployeedata.Salary = "1232.23"
Dim i As Integer
For i = 0 To 23
myCollection.Add(myEmployeedata)
Next
myEmployeedata.AccountNumber = "999999999"
myEmployeedata.EmployeeName = "Hu Vouh"
myEmployeedata.NRIC = "XX"
myEmployeedata.Salary = "5232.23"
myCollection.Add(myEmployeedata)
'signal to print
OutputData()
End Sub
Private Sub OutputData()
Dim printdoc As PrintDocument = New PrintDocument()
AddHandler printdoc.PrintPage, AddressOf printdoc_printpage
Dim dlgPrintPreview As PrintPreviewDialog = New PrintPreviewDialog()
' Set any optional properties of dlgPrintPreview here...
dlgPrintPreview.Size = New Size(700, 700)
dlgPrintPreview.Document = printdoc
dlgPrintPreview.ShowDialog()
End Sub
Private Shadows Sub printdoc_printpage(ByVal sender As Object, _
ByVal pEvents As PrintPageEventArgs)
pEvents.Graphics.PageUnit = GraphicsUnit.Pixel
Dim AddressFont As New Font("Courier New", 12, FontStyle.Bold, GraphicsUnit.Point)
Dim RowFont As New Font("Courier New", 8, FontStyle.Bold, GraphicsUnit.Point)
Dim defaultBrush As New SolidBrush(Color.Black)
Dim pageboundaries As RectangleF = New RectangleF(pEvents.PageBounds.X, _
pEvents.PageBounds.Y, pEvents.PageBounds.Width, pEvents.PageBounds.Height)
'call function to draw name and address
DrawNameAndAddress(pEvents.Graphics, AddressFont, defaultBrush, "Name and Address", _
New RectangleF(pageboundaries.X, pageboundaries.Y, _
pageboundaries.Width * 0.4, pageboundaries.Height * 0.2))
'call function to draw the rows of data
pagetotal = DrawRowData(pEvents, RowFont, defaultBrush, New RectangleF(0, _
pageboundaries.Height * 0.25, pageboundaries.Width, _
pageboundaries.Height * 0.7), myCollection)
'draw the salary total for this page
drawtotals(pagetotal, pEvents.Graphics, AddressFont, defaultBrush, _
New PointF(500, 500))
'adds totals of salaries for that page to the grand total
subtotals += pagetotal
If pEvents.HasMorePages = False Then
drawtotals(subtotals, pEvents.Graphics, AddressFont, defaultBrush, _
New PointF(0, pageboundaries.Height - pageboundaries.Height * 0.05))
End If
AddressFont.Dispose()
RowFont.Dispose()
defaultBrush.Dispose()
'reset pagetotal
pagetotal = 0
End Sub
Private Function DrawRowData(ByRef ev As PrintPageEventArgs, ByRef f As Font, _
ByRef b As Brush, ByVal lrect As RectangleF, _
ByVal lData As Collection) As Decimal
'from the rectangleF passed , we need to take its height, and / it by 20,
'so we have 20 smaller rectangles that fit within the height of the rectangle passed
Dim g As Graphics = ev.Graphics
Dim rowRectangle As New RectangleF(lrect.X, lrect.Y, lrect.Width, lrect.Height * 0.05)
'rowRectangle represents on row of data
'but we also need to divide that row into columns
'to represent the four items we print on each row:
'Name, NRIC, Account number, salary
Dim subRectangle As New RectangleF(rowRectangle.X, _
rowRectangle.Y, rowRectangle.Width * 0.25, rowRectangle.Height)
'We need to define a variable that will keep track
'of what Y position to print the next line at
Dim Yoffset As Integer = rowRectangle.Height
''''''this declaration to help Ctype from the collection
Dim myemployee As EmployeeData
''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim salarytotals As Decimal = 0
Dim i As Integer
Do Until myCollection.Count = 0 OrElse i > 20
i = i + 1
myemployee = CType(myCollection(1), EmployeeData)
g.DrawString(myemployee.EmployeeName, f, b, subRectangle)
subRectangle.Offset(subRectangle.Width, 0)
g.DrawString(myemployee.NRIC, f, b, subRectangle)
subRectangle.Offset(subRectangle.Width, 0)
g.DrawString(myemployee.AccountNumber, f, b, subRectangle)
subRectangle.Offset(subRectangle.Width, 0)
g.DrawString(myemployee.Salary, f, b, subRectangle)
'add salary to subtotal
salarytotals += Convert.ToDecimal(myemployee.Salary)
'remove the item from the collection
myCollection.Remove(1)
'move to next row
subRectangle.X = rowRectangle.X 'CR
subRectangle.Offset(0, Yoffset) 'LF
Loop
'release reference to the passed eventargs.graphics object
g.Dispose()
'if more data to print, signal the delegate
If myCollection.Count > 0 Then
ev.HasMorePages = True
Else
ev.HasMorePages = False
End If
Return salarytotals
End Function
Private Sub DrawNameAndAddress(ByRef g As Graphics, ByRef f As Font, _
ByRef b As Brush, ByVal s As String, ByVal lRect As RectangleF)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'normally we would pass a structured string into this function,
'for this sample project, we build it within this function
'create a structured string (string with carriage returns)
Dim sb As New StringBuilder()
Dim CR() As Char = {Chr(13), Chr(10)}
sb.Append("Boon Boon Trading Company")
sb.Append(CR)
sb.Append("N0 80 JALAN BUNDA RAYA")
sb.Append(CR)
sb.Append("75100 MELAKA")
sb.Append(CR)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'StringFormat class allows us to wrap text within confines of
'a rectangle.. this is helpful in case the text on a line exceeds
'the width alloted on a single line for this text area (Name and Address).
Dim strFormat As New StringFormat()
strFormat.Alignment = StringAlignment.Near
strFormat.LineAlignment = StringAlignment.Near
strFormat.Trimming = StringTrimming.Word
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'draw the information to the page
g.DrawString(sb.ToString, f, b, lRect, strFormat)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
End Sub
Private Sub drawtotals(ByVal lTotal As Decimal, ByRef g As Graphics, _
ByRef f As Font, ByRef b As Brush, ByVal lPointF As PointF)
'Draw the totals of all salaries on the last page
'g.DrawString("hi", f, b, lPointF.X, lPointF.Y)
End Sub
End Class