Hi guys, this article contains a sample on how to make a table using PrintDocument for printing. 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. 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 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 '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: Imports System.Drawing.Printing Public Class Form1 Dim dt As DataTable '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 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 '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 End Sub 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 To make it works with multiline text in cell, read also this article: PrintDocument, Creating/Printing Table with Multiline Cell Sumber http://rani-irsan.blogspot.com
pop
Jumat, 21 Agustus 2020
Langganan:
Posting Komentar (Atom)
EmoticonEmoticon