Click here to Skip to main content
15,797,823 members
Articles / Programming Languages / C#

Printing Multiple Pages and Tabular Printing

Rate me:
Please Sign up or sign in to vote.
4.91/5 (17 votes)
23 Nov 2009CPOL3 min read 85.1K   8.7K   90   16
In this article, I will discuss printing of tabular data in multiple pages.



When I was learning .NET programming, I found printing difficult and tedious to learn. I grasped the fundamentals of printing quickly, but when it came to printing multiple pages and tabular printing, I often felt frustrated trying to understand and program through it. However, when I finally prepared my mind to master it, I realized that there is a little mathematical and logical trick that is involved in printing.

In this article, I will discuss the printing of tabular data in multiple pages. For this purpose, I am using my data source datagrid from database records in Microsoft SQL Server. However, my target is to be able to print any data source in tabular form. This can be done for data sources such as ListViews. So keep in mind that our intention is to print in tabular form, not program databases in this article. In addition, I will also include the code for printing individual records from a database.

When I wrote the article, I kept in my mind that we can also make reports and do printing using the Report Manager of Visual Studio and/or third party applications such as Crystal Reports. However, when we try to print and make a report for an application that does not involve databases, it will be better if we know the printing paradigm. So in this article, I will mainly concentrate on the mathematical geometry of the page.

Page Geometry

During printing, the first thing to consider is the geometry of the page. Since printing is similar to graphics drawing, we have to consider the page as our canvas. We notice that all the printing functions are done using similar functions of printing.

Image 2

A single page has height, width as well as the left, right, top, and bottom margins. First, we calculate the actual area of the page on which data can be printed.

int top, bottom, left, right; 
left = psp.PageSettings.Margins.Top; 
right = psp.PageSettings.Margins.Bottom;
top = psp.PageSettings.Margins.Left; 
bottom = psp.PageSettings.Margins.Right; 
pagewidth = printDocument2.DefaultPageSettings.PaperSize.Width
        -printDocument1.DefaultPageSettings.Margins.Left -
pageheight = printDocument2.DefaultPageSettings.PaperSize.Height -
    printDocument1.DefaultPageSettings.Margins.Top -

In this, we calculate the boundaries area of the page.

Calculate the number of maximum rows to be printed in a single page. This is used for locating the number of pages for the data in the records (datagrid).

//calculate approximate number of rows per page
rpp = (int)( 0.98 * ((pagewidth -
      (int)(e.Graphics.MeasureString(grv.Columns[1].HeaderText, fh).Height) )/
      (int)(sm.Height +10)));

Actual Printing

Column Heading

The first thing to be printed is the data heading from the data grid.

int i;
//iterates through data in the array columns of the datagrid
for (i = 0; i < grv.Columns.Count; i++) {
e.Graphics.DrawString(grv.Columns[i].HeaderText, fh, Brushes.Black, new
PointF(left + sf.Width * i + 50, top + 50)); }
int j; 

Next, the records or the rows are printed.

Data Rows

Image 3

The data in the rows are printed sequentially through iteration.

//prints rows in the datagrid in a single pages using rpp control
for (j = currentrow; j < Math.Min (rpp+currentrow , grv.Rows.Count )-1; j++)
{ int k;
for (k = 0; k < grv.Rows[j].Cells.Count; k++)
{ e.Graphics.DrawString(grv.Rows[j].Cells[k].Value.ToString().ToUpper(), ff,
Brushes.Black, new PointF(left + sf.Width * k + 50, top + 50 + (j +
1-currentrow) * (sm.Height + 10))); }
//sum is used for holding the total amount from datagrid which is later printed for total
sum += Convert.ToDouble(grv.Rows[j].Cells[grv.Rows[j].Cells.Count - 2].Value);
//draw the rectangle for each data row which together forms the table
e.Graphics.DrawRectangle(Pens.Black, new Rectangle((int)(left + 50),
    (int)(top + 50 + (j-currentrow ) * (10 + sm.Height)),
    (int)(left + sf.Width * (i - 1)), (int)(sm.Height + 10))); }

Printing Multiple Pages

The important code snippet in printing multiple pages, if needed, starts from the form declaration of the static variable:

//used for counting the number of pages required to print the rows.
static int currentrow = 0;

It is important to declare it as static, since every time the printing procedure is incremented, it is incremented by the total number of rows to print in a single page calculated previously (rpp).

//the current row is incremented by rrp
// (total number of rows to be printed in single page)
currentrow += rpp-1;

//used for checking if it reaches final page of the printing pages

//if true it prints total amount from the guest
//again the sum is also static variable
if (currentrow >= (grv.Rows.Count))
    e.Graphics.DrawString("Total: ", ff,
    Brushes.Blue, new PointF(left + 50 + 3 * (sm.Width + 10), top + 50 + rt.Height
    + 10)); e.Graphics.DrawString(sum.ToString("##,##.00 NKF"), ff,
    Brushes.Red, new PointF(left + 50 + 4 * (sm.Width + 10), top + 50 + rt.Height +
    e.Graphics.DrawLine(Pens.Blue, left + 50 + 4 *
    (sm.Width + 10), top + 50 + rt.Height + 10 + sm.Height, left + 50 + 4 *
    (sm.Width + 10) + e.Graphics.MeasureString(sum.ToString("##,##.0
    NKF"), ff).Width, top + 50 + rt.Height + 10 + sm.Height);

Image 4

Final Code

//test if currentrow reaches bottom of the page, if true add additional page
if (currentrow >= grv.Rows.Count)
    e.HasMorePages = false;
     currentrow = 0; 
    e.HasMorePages = true; 

During printing, when an additional page is added, the print page event handler is called automatically. This continues recursively until the whole data is printed.

Point of Interest

Finally, I found out that printing is also a lot of fun. In this article, I was mainly concerned about the printing capabilities, although the application involves simple database manipulation.


  • 7th October, 2009: Initial version.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Written By
Software Developer
Eritrea Eritrea
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

QuestionZIP File Pin
gggustafson15-Apr-17 7:21
professionalgggustafson15-Apr-17 7:21 
There appears to be a corruption of your ZIP file. "Form1" does not exist. Please advise.
Gus Gustafson

QuestionSupport how to print many pages in c# using webform Pin
Jason Ngo4-Apr-14 18:25
Jason Ngo4-Apr-14 18:25 
GeneralMy vote of 5 Pin
Member 933785517-Aug-12 3:08
Member 933785517-Aug-12 3:08 
GeneralMy vote of 4 Pin
Jashobanta27-Dec-11 4:10
Jashobanta27-Dec-11 4:10 
GeneralMy vote of 5 Pin
User 774426226-Nov-11 8:37
User 774426226-Nov-11 8:37 
Questionnot extracting file Pin
carPrince26-Oct-11 8:57
carPrince26-Oct-11 8:57 
GeneralNice Pin
varaprasadreddy27-Jun-11 20:05
varaprasadreddy27-Jun-11 20:05 
GeneralRe: Nice Pin
tadeze28-Jun-11 0:29
tadeze28-Jun-11 0:29 
GeneralExcellent! Pin
polczym14-Mar-10 0:48
polczym14-Mar-10 0:48 
GeneralRe: Excellent! Pin
tadeze28-Jun-11 0:09
tadeze28-Jun-11 0:09 
QuestionHow I can calculate how many pages will be printed Pin
dev_prog25-Jan-10 18:00
dev_prog25-Jan-10 18:00 
GeneralA Good Article Pin
infinitess30-Nov-09 16:32
infinitess30-Nov-09 16:32 
GeneralNice Article ....... Pin
PankajRai.Net25-Oct-09 20:44
PankajRai.Net25-Oct-09 20:44 
GeneralRe: Nice Article ....... Pin
tadeze27-Oct-09 4:13
tadeze27-Oct-09 4:13 
GeneralRe: Nice Article ....... Pin
chenqingwei121010-Nov-09 22:32
chenqingwei121010-Nov-09 22:32 
GeneralRe: Nice Article ....... Pin
AspDotNetDev23-Nov-09 18:38
protectorAspDotNetDev23-Nov-09 18:38 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.