printing reports in
TRANSCRIPT
-
7/26/2019 Printing Reports in
1/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 1/13
Articles Desktop Development Printing General
Mike Mayer, 27 Aug 2008 CPOL 315.9K 12K 256
Printing Reports in .NET
Using the library presented, you can print reports from C# and other .NET languages
Download source ver 0.7 282.6 KB
4.84 66 votes
http://www.codeproject.com/KB/printing/ReportPrinting/ReportPrinting_ver_0_7.ziphttp://www.codeproject.com/KB/printing/ReportPrinting/ReportPrinting_ver_0_7.ziphttp://www.codeproject.com/KB/printing/ReportPrinting/ReportPrinting_ver_0_7.ziphttp://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://www.codeproject.com/script/Content/SiteMap.aspxhttp://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://www.codeproject.com/info/cpol10.aspxhttp://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://www.codeproject.com/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://www.codeproject.com/KB/printing/ReportPrinting/ReportPrinting_ver_0_7.ziphttp://void%280%29/http://www.codeproject.com/Chapters/1/Desktop-Development.aspxhttp://void%280%29/http://void%280%29/http://void%280%29/http://www.codeproject.com/KB/printing/#Generalhttp://www.codeproject.com/KB/printing/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://void%280%29/http://www.codeproject.com/script/Membership/View.aspx?mid=230488 -
7/26/2019 Printing Reports in
2/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 2/13
Introduction
Printing a document programmatically can be quite involved. Using the ReportPrintinglibrary presented here, you'll be able to print reports with multiple sections with verylittle code.
The reports are comprised of plain text sections such as the title "Birthdays", and the other paragraphs and grids of data from a database more specifically, from a DataViewobject. Lines and images using the .NET Imageclass and boxes like the CSS box model are also supported. The framework presented can easily be extended to handle many
other primitives.
I do not plan to keep this page uptodate with the latest code and documentation. This will just be a quick presentation of what you can do and the classes involved. For the latest
version, see here. However, this project is not actively being developed, so use at your own risk. This was all written for the .NET 1.1 Framework, and I know a lot of new namespaces
were added in .NET 2.0 that may make a lot of this obsolete. It solved a problem I had at the time.
Step-by-Step
This section will take you through the process of using the ReportPrinting library, step by step.
Create a DataView
The first step is to create a DataTableand DataViewthat serves as the source of data. The following code will create a table of some famous birthdays:
publicstatic DataView GetDataView()
{
DataTable dt = new DataTable("People");
dt.Columns.Add("FirstName", typeof(string));
dt.Columns.Add("LastName", typeof(string));
dt.Columns.Add("Birthdate", typeof(DateTime));
dt.Rows.Add(newObject[] {"Theodore", "Roosevelt", new DateTime(1858, 11, 27)}); dt.Rows.Add(newObject[] {"Winston", "Churchill",
new DateTime(1874, 11, 30)});
dt.Rows.Add(newObject[] {"Pablo", "Picasso",
new DateTime(1881, 10, 25)});
dt.Rows.Add(newObject[] {"Charlie", "Chaplin",
new DateTime(1889, 4, 16)});
dt.Rows.Add(newObject[] {"Steven", "Spielberg",
new DateTime(1946, 12, 18)});
dt.Rows.Add(newObject[] {"Bart", "Simpson",
http://sourceforge.net/projects/net-rep-printer/ -
7/26/2019 Printing Reports in
3/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 3/13
new DateTime(1987, 4, 19)});
dt.Rows.Add(newObject[] {"Louis", "Armstrong",
new DateTime(1901, 8, 4)});
dt.Rows.Add(newObject[] {"Igor", "Stravinski",
new DateTime(1882, 6, 17)});
dt.Rows.Add(newObject[] {"Bill", "Gates",
new DateTime(1955, 10, 28)});
dt.Rows.Add(newObject[] {"Albert", "Einstein",
new DateTime(1879, 3, 14)});
dt.Rows.Add(newObject[] {"Marilyn", "Monroe",
new DateTime(1927, 6, 1)}); dt.Rows.Add(newObject[] {"Mother", "Teresa",
new DateTime(1910, 8, 27)});
DataView dv = dt.DefaultView;
return dv;
}
This function will return a DataViewfor a table of a dozen famous individuals and their birthdays.
Create a ReportMaker
The ReportPrinting.IReportMakerinterface is used to create objects that setup a ReportDocument . That is, an object that implements IReportMaker will containall the code necessary to make a report. For this example, it is a class called SampleReportMaker1 . It has one method to implement:
publicvoid MakeDocument(ReportDocument reportDocument)
{
Let's take a look at the implementation of this method stepbystep. First, it is a good idea to reset the TextStyleclass. TextStyleprovides global styles for the formatting oftext such as heading, normal paragraphs, headers, footers, etc. Since the scope of this class is application wide, it should be reset to a known state at the beginning of report
generation.
TextStyle.ResetStyles();
Next, setup the default margins for the document, if desired.
// Setup default margins for the document (units of 1/100 inch)
reportDocument.DefaultPageSettings.Margins.Top = 50;reportDocument.DefaultPageSettings.Margins.Bottom = 50;
reportDocument.DefaultPageSettings.Margins.Left = 75;
reportDocument.DefaultPageSettings.Margins.Right = 75;
-
7/26/2019 Printing Reports in
4/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 4/13
As mentioned, the TextStyleclass has several static, global styles that can be applied to different text blocks. These styles can each be customized. We'll change some fonts andcolors just to show what's possible.
// Setup the global TextStyles
TextStyle.Heading1.FontFamily = new FontFamily("Comic Sans MS");
TextStyle.Heading1.Brush = Brushes.DarkBlue;
TextStyle.Heading1.SizeDelta = 5.0f;
TextStyle.TableHeader.Brush = Brushes.White;
TextStyle.TableHeader.BackgroundBrush = Brushes.DarkBlue;
TextStyle.TableRow.BackgroundBrush = Brushes.AntiqueWhite;
TextStyle.Normal.Size = 12.0f;
// Add some whitespace to the page. By adding a 1/10 inch margin
// to the bottom of every line, quite a bit of white space will be added
TextStyle.Normal.MarginBottom = 0.1f;
Using our method defined earlier, we'll get a dataviewand set the default sort based on the values setup in a GUI. Note, this is a hack. Better encapsulation should be used toisolate the dialog, defined later, from this class.
// create a data table and a default view from it.
DataView dv = GetDataView();
// set the sort on the data view
if (myPrintDialog.cmbOrderBy.SelectedItem != null)
{
string str = myPrintDialog.cmbOrderBy.SelectedItem.ToString();
if (myPrintDialog.chkReverse.Checked)
{
str += " DESC"; }
dv.Sort = str;
}
The next step is creating an instance of the ReportPrinting.ReportBuilderclass. This object is used to simplify the task of piecing together text, data, and the container
sections that they go into these classes for text, data and sections are described in more detail later in this article.
// create a builder to help with putting the table together.
ReportBuilder builder = new ReportBuilder(reportDocument);
Creating a header and footer are quite easy with the builder class's five overloaded functions. The one below creates a simple header with text on the left side Birthdays Report and
on the right side page #. The footer has the date centered.
// Add a simple page header and footer that is the same on all pages.
builder.AddPageHeader( "Birthdays Report", String.Empty, "page %p");
-
7/26/2019 Printing Reports in
5/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 5/13
builder.AddPageFooter( String.Empty, DateTime.Now.ToLongDateString(),
String.Empty);
Now the real fun begins: we start a vertical, linear layout because every section from here should be added below the preceding section.
builder.StartLinearLayout(Direction.Vertical);
Now add two text sections. The first section added will be a heading as defined by TextStyle.Heading1
. The second section is just normal text as defined by the
TextStyle.Normal.
// Add text sectionsbuilder.AddTextSection( "Birthdays", TextStyle.Heading1);
builder.AddTextSection( "The following are various birthdays of people " +
"who are considered important in history.");
Next, we add a section of a data table. The first line adds a data section with a visible header row. Then three column descriptors are added. These are added in the order that the
columns are displayed. That is, LastNamewill be the first column, followed by FirstName, followed by Birthdate.
The first parameter passed to AddColumnis the name of the column in the underlying DataTable. The second parameter is the stringas printed in the header row. The lastthree parameters describe the widths used. A maxwidth can be specified in inches. Optionally, the width can be autosized based on the header row and/or the data rows. In this
case, with falsebeing passed, no autosizing is performed.
// Add a data section, then add columns
builder.AddDataSection(dv, true);builder.AddColumn ("LastName", "Last Name", 1.5f, false, false);
builder.AddColumn ("FirstName", "First Name", 1.5f, false, false);
builder.AddColumn ("Birthdate", "Birthdate", 3.0f, false, false);
We set a format expression for the last column added the date column
. These format expressions are identical to those used by String.Format. This makes the date show up inlong format.
// Set the format expression to this string.builder.CurrentColumn.FormatExpression = "{0:D}";
And the very last thing is to finish the LinearLayout that was started earlier.
builder.FinishLinearLayout();}
-
7/26/2019 Printing Reports in
6/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 6/13
Create a Form for Printing
There are only a handful of controls on the following form: a label, a combo box, a check box, and a usercontrol from ReportPrinting namespace called PrintControl. Thiscontrol has the four buttons you see at the bottom of the form.
This form also has an instance of the ReportPrinting.ReportDocumentclass. This is a subclass of System.Drawing.Printing.PrintDocument. If you create theabove form in a designer, here is the constructor required to create a new ReportDocumentobject.
private ReportDocument reportDocument;
public ReportPrinting.PrintControl PrintControls;
public System.Windows.Forms.ComboBox cmbOrderBy;
public System.Windows.Forms.CheckBox chkReverse;
public SamplePrintDialog1()
{
InitializeComponent();
this.reportDocument = new ReportDocument();
this.PrintControls.Document = reportDocument;
SampleReportMaker1 reportMaker = new SampleReportMaker1(this);
this.reportDocument.ReportMaker = reportMaker;
this.cmbOrderBy.Items.Clear();
this.cmbOrderBy.Items.Add("FirstName");
this.cmbOrderBy.Items.Add("LastName");
-
7/26/2019 Printing Reports in
7/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 7/13
this.cmbOrderBy.Items.Add("Birthdate");
}
In this constructor, an instance of ReportDocumentis created. This instance is assigned to the PrintControls.Documentproperty. A SampleReportMaker1objectdefined above is then instantiated and assigned to the ReportDocument 's ReportMakerproperty. The final bit of the constructor simply sets up the ComboBox.
You're Finished
The above code prints a fairly simple document. Just to note, you can use the standard PrintDialog, PrintPreview, and PageSettings dialogs without using thePrintControlsusercontrol
.
This entire sample can be found in the download of the ReportPrinting library, along with many other tests that I have created most are boring to look at, but test variousrandom settings
.
Report Document Classes
There are several classes introduced into the ReportPrinting namespace. They work together for the printing of the above report in addition to all the .NET Framework baseclasses that are used. Here is a quasiUML diagram that shows the relationship between these classes. An open triangle is generalization i.e. it points to the superclass in the
inheritance chain. The black diamonds are composite i.e. show that one class instantiates members of another class. The dashedlines are dependency i.e. it uses the class.
-
7/26/2019 Printing Reports in
8/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 8/13
ReportDocument
ReportDocumentextends from PrintDocumentand is customized for printing reports from one or more tables of data. A ReportDocument object is the toplevelcontainer for all the sections that make up the report. This consists of a header, body, and footer.
The ReportDocument's main job is printing, which occurs when the Print()method is called of the base class. The Print()method iterates through all theReportSectionsmaking up the document, printing each one.
-
7/26/2019 Printing Reports in
9/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 9/13
The strategy design pattern is employed for formatting the report. An object implementing IReportMaker may be associated with the ReportDocument. ThisIReportMakerobject is application specific and knows how to create a report based on application state and user settings. This object would be responsible for creating sections,associating DataViews, and applying any required styles through use of the TextStyleclass. It will generally use the ReportBuilderclass to assist with the complexity ofbuilding a report.
ReportSection
ReportSectionis an abstract class that represents a printable section of a report. There are several subclasses of ReportSection, including ReportSectionText which
represents a string of text and ReportSectionData which represents a printable DataView. There are also container sections which derive from SectionContainerclass, which in turn derives from ReportSection
. These containers hold child ReportSectionobjects also known as subsections
to be printed. Lets take a quick look at
how this might work with an example.
In the sample report shown at the top of this article, there is a paragraph of text followed by a table of data. There are actually two paragraphs of text, one of which is a heading. Plus
there is a page header, but we'll ignore all that for now.
We would create a ReportSectionTextobject to print the paragraph of text and a ReportSectionDataobject toprint the table of data. To add both of these ReportSectionsto the ReportDocument, we must create a container. We would create a LinearSectionscontainer to holdthese two sections. This container is then made the body of the ReportDocument. When the document is printed, the section container will first print theReportSectionText, and then below that, it will print the ReportSectionData. Simply printing each section below the preceding one will result in the finished report. Butthere are many other ways to set up these classes.
SectionContainer
This abstract class defines a container of sections. There are two types provided with the framework: LinearSectionsand LayeredSections.
LinearSections
The LinearSectionsclass is a subclass of SectionContainer, which is a subclass of ReportSection. Therefore, the LinearSections can be thought of as "aprintable section of a report." However, it is also a container of one or more sections.
As its name implies, it lays sections out linearly that is, in a row or in a column. A property named Directionspecifies if this container will layout sections going down the page
typical or across the page not as typical.
LayeredSections
The LayeredSectionsclass is also a subclass of SectionContainer, which is a subclass of ReportSection. Therefore, the LayeredSectionscan be thought of as"a printable section of a report." It is also a container of one or more sections.
The child sections of a LayeredSectionsobject are all painted on top of one another creating layers
. The first section added to a LayeredSectionsobject is the bottom
-
7/26/2019 Printing Reports in
10/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 10/13
layer. Subsequent ReportSectionobjects added to the LayeredSectionsobject will be shown on top of each other.
ReportSectionText
The ReportSectionTextprints a stringto the page. Two publicproperties are used to setup this section. Text is used to specify the stringto print. TextStyle,described later, sets the font, color, alignment and other properties for how the text is printed.
It is interesting to note that the stringspecified for this section can be just one word, or many paragraphs of text.
ReportSectionData
The ReportSectionDataprints a table of data. It uses a DataViewobject from the .NET System.Datanamespace as the source of data. It then uses a series ofReportDataColumnsto provide the formatting details. These ReportDataColumnsare similar to the DataGridColumnStyleclass.
ReportDataColumn
The ReportDataColumnprovides the necessary information for formatting data for a column of a report. For every column to be presented within a section of data, a new
ReportDataColumnobject is instantiated and added to the ReportSection. At a minimum, each column describes a source field from the DataSource that is, a columnname from the DataView and a maximum width on the page.
The ReportDataColumncan be setup with its own unique TextStylefor both header and normal rows. Therefore, each column's data can be formatted differently e.g. animportant column could be bold and red. The TextStyleis also used to set the horizontal alignment justification.
TextStyle
The TextStyleclass allows styles and fonts to be added to text selectively, allowing default styles to be used when not explicitly set. All styles except for the staticTextStyle.Normal
have another style as their "default" style. Until a property is set like bold, underline, size, font family, etc, a TextStyleobject always uses thecorresponding value from its default or parent
style.
For example, a new style can be defined using Normalas its default, but setting bold.
TextStyle paragraphStyle = new TextStyle(TextStyle.Normal);
paragraphStyle.Bold = true;
It will have all the same properties as TextStyle.Normal, except it will be bold. A later change to Normal such as below will have the effect of increasing the size of bothstyles Normaland paragraphStyle
.
-
7/26/2019 Printing Reports in
11/13
-
7/26/2019 Printing Reports in
12/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 12/13
Removed two dead links
Updated code to the latest known good code from Sourceforge
Added a little bit of text that this is no longer being actively worked on
Ran through Visual Studio's reformat document to clean up some HTML
License
This article, along with any associated source code and files, is licensed under The Code Project Open License CPOL
Share
About the Author
You may also be interested in...
Easily turn a ListView into a nicely printed report,
complete with print preview
Common Cassandra Data Modeling Traps
No Biography provided
Mike MayerUnited States
9/17/2015 P i ti R t i NET C d P j t
http://www.codeproject.com/Members/Mike-Mayerhttp://www.codeproject.com/Articles/21395/Easily-turn-a-ListView-into-a-nicely-printed-reporhttp://www.codeproject.com/ResearchLibrary/155/Common-Cassandra-Data-Modeling-Trapshttp://www.codeproject.com/info/cpol10.aspx -
7/26/2019 Printing Reports in
13/13
9/17/2015 Printing Reports in .NET - CodeProject
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Print 13/13
Permalink| Advertise | Privacy| Terms of Use| Mobile
Web03 | 2.8.1509010.1 | Last Updated 27 Aug 2008Select Language
Article Copyright 2003 by Mike Mayer
Everything else Copyright CodeProject, 19992015
Printing support functions Red Hat JBoss BPM Suite 6 Compared to Pegasystems
Pega 7 BPM
Printing a Form in a report fashion (release 2.2) Red Hat JBoss BPM Suite 6 compared to Appian 7
BPM Suite
Comments and Discussions
91 messageshave been posted for this article Visit http://www.codeproject.com/Articles/4934/PrintingReportsinNETto post and view comments on this article, or click
hereto get a print view with messages.
http://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=Mobilemailto:[email protected]://www.codeproject.com/ResearchLibrary/164/Red-Hat-JBoss-BPM-Suite-compared-to-Appian-BPM-Suihttp://developermedia.com/http://www.codeproject.com/ResearchLibrary/164/Red-Hat-JBoss-BPM-Suite-compared-to-Appian-BPM-Suihttp://www.codeproject.com/ResearchLibrary/166/Red-Hat-JBoss-BPM-Suite-Compared-to-Pegasystems-Pehttp://www.codeproject.com/Articles/293/Printing-support-functionshttp://www.codeproject.com/Articles/293/Printing-support-functionshttp://www.codeproject.com/Articles/21395/Easily-turn-a-ListView-into-a-nicely-printed-reporhttp://www.codeproject.com/Articles/5738/Printing-a-Form-in-a-report-fashion-releasehttp://www.codeproject.com/ResearchLibrary/166/Red-Hat-JBoss-BPM-Suite-Compared-to-Pegasystems-Pehttp://www.codeproject.com/Articles/5738/Printing-a-Form-in-a-report-fashion-releasehttp://void%280%29/http://www.codeproject.com/ResearchLibrary/155/Common-Cassandra-Data-Modeling-Trapshttp://www.codeproject.com/Articles/4934/Printing-Reports-in-NET?display=PrintAllhttp://www.codeproject.com/info/TermsOfUse.aspxhttp://www.codeproject.com/Articles/4934/Printing-Reports-in-NEThttp://www.codeproject.com/Articles/4934/Printing-Reports-in-NEThttp://www.codeproject.com/info/privacy.aspx