KnowDotNet

.NET Printing is Different, but much more Powerful and Flexible than in VB6

CPrintReportString - A Complete Class for Printing a Report

by Les Smith

Why Migrate to .NET?  Printing is completely different, but much more powerful and flexible than VB6.  Once you get over the obvious (printing is different in .NET), you will see that it is much more powerful than you have been used to in VB6.

In this article, I will present a complete class for printing a report from a string created in memory.  I have previously written an article on this same subject, but I have since made some major enhancements to the Print Class and I am providing a complete demonstration project for demonstrating the use of the class.  Although, this is a base class, which you can enhance, it is a powerful class, in that it automatically creates a Title, 1-4 SubTitles, Footer, and from 1-4 column headers.  It also provides several keywords that allow you to force page breaks, underline print lines, change headers on page breaks, etc.  You will find a description of these keywords in the PrintDoc event of the class.

In VB6, printing was done lineraly through the Printer Object.  In .NET, there is no Printer Object.  Printing is done through Event Handling methodology.  The user initiates the printing and then the PrintDocument object calls the PrintPage event to get a page of data to print.  Not to worry, this class will handle all of the interfacing with the .NET PrintDocument object for you.  This is a large class, and it is documented with comments in the code, so I will not attempt to describe it further.  I will show you a simple call to it.  This call assumes that the complete report has been built as a string, delimited by CRLFs, and you simply call the class to handle the printing.  You can change this paradigm by putting code in the PrintPage event to retrieve your data from database, etc.

Figure 1 shows a method for creating and calling the CPrintReportString Class.  This demo method creates data in a string, along with two of a possible four column header lines.  After printing one hundred report lines, I force a page break to simulate a control break.  I also change the sub title as you might be printing from a different department, etc., after the control break.  There is even an option to allow reseting the page counter.  The PrintOrPreview method has five overloads allowing you to pass 0 to 4 column headers.  You can also box the report in a rectangle.  Finally, you can set the Left, Right, Top, and Bottom margins of the print page.  All of this is demonstrated by the demo project.

At this time the Class is written in VB.NET.  If you want to use it in C#, simply create a DLL using the class in a separate project.  There are no Optional parameters, so calling the DLL will be no problem in C#.

Figure 1 - Calling the Print Method.

   Private Sub GenerateReport(ByVal Preview As Boolean)
      
Dim sb As New System.Text.StringBuilder
      
' create two column headers, can have max of 4

      Try
         Dim ch1 As String = _
            "Field1".PadRight(15) & _
            "Longer Field2".PadRight(28) & _
            "Field3 Heading".PadRight(25) & _
            "Counter".PadRight(12)
        
Dim ch2 As String = _
            "Header".PadRight(15) & _
            "Line2 of Heading".PadRight(28) & _
            "Heading Line 2".PadRight(25) & _
            "Of Lines".PadRight(12)
        
Dim total As Integer = 5

        
' generate the detail lines (Dummy Data)
         ' This string would normally be created from a datatable from
         ' from a database query, so that the For Loop would be processing
         ' data from a datatable, dataset,....
         For i As Integer = 1 To 100
            sb.Append(("Col" & i.ToString & "Data").PadRight(15) & _
                      ("Field 2 Data for Line " & i.ToString).PadRight(28) & _
                      ("Data Field 3 for Line " & i.ToString).PadRight(25) & _
                      total.ToString.PadLeft(12) & vbCrLf)
            total += 5
        
Next
         sb.Append(vbCrLf & Space(63) & "Total" & total.ToString.PadLeft(12) & _
            vbCrLf)

        
' now we will pretend to have had a total break and change the
         ' subtitle, after forcing a page change
         sb.Append("<:SUBTITLE1>My New SubTitle Heading Line" & vbCrLf)
         sb.Append("<:SUBTITLE2>New SubTitle 2 - for Testing" & vbCrLf)
         sb.Append("<:NEWPAGE>" & vbCrLf)

        
' create some more data
         total = 5
        
For i As Integer = 1 To 40
            sb.Append(("Col" & i.ToString & "Data").PadRight(15) & _
                      ("Field 2 Data for Line " & i.ToString).PadRight(28) & _
                      ("Data Field 3 for Line " & i.ToString).PadRight(25) & _
                      total.ToString.PadLeft(12) & vbCrLf)
            total += 5
        
Next
         sb.Append(vbCrLf & Space(63) & "Total" & total.ToString.PadLeft(12) & _
            vbCrLf)



        
' finally, set up & print the report
         ' instantiate the object
         cprs = New CPrintReportString

        
' set the title font points size and style
         cprs.TitleFontSize = 14
         cprs.TitleFontStyle = CPrintReportString.TitleStyle.BoldItalic

        
' box the report if requested
         If Me.chkBoxed.Checked Then
            cprs.DrawBox = True
         End If

         ' get margin extenders if any
         cprs.LeftMarginExtender = GetMarginExtenders(MelmExtCB.Text)
         cprs.RightMarginExtender = GetMarginExtenders(
MermExtCB.Text)
         cprs.TopMarginExtender = GetMarginExtenders(
MetmExtCB.Text)
         cprs.BottomMarginExtender = GetMarginExtenders(
MebmExtCB.Text)

        
' add extra subtitles
         cprs.SubTitle2 = "This is SubTitle Number 2 (Can have up to four)"
         cprs.SubTitle3 = "This is SubTitle Number 3 (Can have up to four)"
         cprs.SubTitle4 = "This is SubTitle Number 4 (Can have up to four)"

        
' call the print or preview method
         cprs.PrintOrPreview(CPrintReportString.CharsPerLine.CPL80, _
            sb.ToString, "Demo Report", "SubTitle1 - Test Data Only", _
            IIf(Preview, CPrintReportString.PrintPreview.Preview, _
            CPrintReportString.PrintPreview.Print), _
            IIf(
Me.optPortrait.Checked, _
               CPrintReportString.PrintOrientation.Portrait, _
               CPrintReportString.PrintOrientation.Landscape), ch1, ch2)

      
Catch ex As System.Exception
         StructuredErrorHandler(ex)
      
End Try  
   End Sub

Figure 2 shows the Demo Form that is used to create the report and Figure 3 shows the Preview of the Demo Report in the Preview Dialog.

Figure 2 - Demo Form.

Demo Form


Figure 3 - Report Preview.

Preview Report


You can download the code for the CPrintString Class by clicking here.



If you find CPrintReportString Class useful and would like to make a donation to
allow KnowDotNet to continue to provide this type of tool click the button below.





Top of Page