KnowDotNet Visual Organizer

.NET Printing is different, but much more powerful and flexible.

CPrintReportString - A Complete C# Class for Printing a Report.

by Les Smith
Print this Article Discuss in Forums

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.

In this article the Class is written in C#.  If you want to use it in VB.NET click
here.to see the VB.NET article and code.

Figure 1 - Calling the Print Method.

    private void GenerateReport(bool preview)
    {
      StringBuilder sb =
new StringBuilder();
      
// create two column headers, can have max of 4
      string ch1 =  "Field1".PadRight(15) +
        "Longer Field2".PadRight(28) +
        "Field3 Heading".PadRight(25) +
        "Counter".PadRight(12);
      
string ch2  =
        "Header".PadRight(15) +
        "Line2 of Heading".PadRight(28) +
        "Heading Line 2".PadRight(25) +
        "Of Lines".PadRight(12);
      
int total = 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(int i = 1; i<=100; i++)<BR>       {
        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) + Environment.NewLine);
        total += 5;
      }

      
// now we will pretend to have had a total break and change the
      // subtitle, after forcing a page change
      sb.Append(Environment.NewLine + " ".PadLeft(63) +
        "Total" + total.ToString().PadLeft(12) + Environment.NewLine);

      sb.Append("<:SUBTITLE1>My New SubTitle Heading Line" + Environment.NewLine);
      sb.Append("<:SUBTITLE2>New SubTitle 2 - for Testing" + Environment.NewLine);
      sb.Append("<:NEWPAGE>" + Environment.NewLine);

      
// create some more data
      total = 5;
      
for(int i=1; i<=40; i++)<BR>       {
        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) + Environment.NewLine);
        total += 5;
      }
      sb.Append(Environment.NewLine + " ".PadLeft(63) +
         "Total" + total.ToString().PadLeft(12) + Environment.NewLine);

      
// finally, set up & print the report
      // instantiate the object
      cprs = new CPrintReportStringDemo.CPrintReportString();

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

      
// box the report if requested
      if( this.chkBoxed.Checked)
        cprs.DrawBox =
true;

      
// get margin extenders if any
      cprs.LeftMarginExtender = GetMarginExtenders(thislmExtCB.Text);
      cprs.RightMarginExtender = GetMarginExtenders(
thisrmExtCB.Text);
      cprs.TopMarginExtender = GetMarginExtenders(
thistmExtCB.Text);
      cprs.BottomMarginExtender = GetMarginExtenders(
thisbmExtCB.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
      string title = "Demo Report";
      
string subTitle = "SubTitle1 - Test Data Only";

      
if(preview)
      {
        
if(this.optPortrait.Checked)
          cprs.PrintOrPreview(CharsPerLine.CPL80,
            sb.ToString(),title,subTitle,PrintPreview.Preview,
            PrintOrientation.Portrait,ch1,ch2);
        
else
          cprs.PrintOrPreview(CharsPerLine.CPL80,
            sb.ToString(),title,subTitle,PrintPreview.Preview,
            PrintOrientation.Landscape,ch1,ch2);
      }
      
else
      {
        
if(!this.optPortrait.Checked)
          cprs.PrintOrPreview(CharsPerLine.CPL80,
            sb.ToString(),title,subTitle,PrintPreview.Print,
            PrintOrientation.Portrait,ch1,ch2);
        
else
          cprs.PrintOrPreview(CharsPerLine.CPL80,
            sb.ToString(),title,subTitle,PrintPreview.Print,
            PrintOrientation.Landscape,ch1,ch2);
      }
    }

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

Writing Add-Ins for Visual Studio .NET
Writing Add-ins for Visual Studio .NET
by Les Smith
Apress Publishing