Click here to Skip to main content
15,885,757 members
Articles / Desktop Programming / Windows Forms

Printing a datagridview in C# .NET 2.0

Rate me:
Please Sign up or sign in to vote.
4.09/5 (13 votes)
6 Nov 2009CPOL3 min read 132.1K   18.6K   41   12
This article demonstrates the printing of a datagridview

Introduction

This article demonstrates printing of a simple datagridview using the PrintPrintDocument and PrintPreivew classes.

datagridview.JPG

Background

Graphics class in C# .NET 2.0.

Using the Code

The best part of .NET is the organization of classes like the PrintDocument class which is derived from the Printing Class and Printing class is in turn derived from System.Drawing class which has methods for drawing Shapes, Bitmaps and Text so the same methods can be used by the PrintDocument Class.

To print a datagridview, we require a table with rows and columns. A table is nothing but a collection of rectangles as mentioned above. PrintDocument class supports drawing of shapes, so we can easily draw a rectangle given the parameters. The rectangle method is overloaded. The one in which we are more interested is:

C#
DrawRectangle(Pens p,int x,int y, int width,int height) 

where x and y are the co-ordinates on the print page in pixel units, the other two parameters specify the width and height of the rectangle.

We can specify the co-ordinates, say draw the first rectangle at location 20,20 but how do we get the exact width and height of the rectangle? Not to worry! We can get the width parameter from:

C#
int width=dataGridView1.Columns[0].Width; //Gives the width of first column

and height parameter from:

C#
int height=dataGridView1.Rows[0].Height; //Gives the height of the first Row

At this point, we have gathered all the required information to draw a rectangle but when and where to Draw? PrintDocument supports an event called PrintPage which has 2 parameters; the one which we are interested is of type PrintPageEventArgs which supports drawing of rectangle.

Here's a small snippet:

C#
private void printDocument1_PrintPage
	(object sender, System.Drawing.Printing.PrintPageEventArgs e) 
{ 
//Draws a rectangle with same width and height of first column of datagridview. 
e.Graphics.DrawRectangle(Pens.Black, 100, 100, 
	dataGridView1.Columns[0].Width, dataGridView1.Rows[0].Height); 

//Fills the above drawn rectangle with a light gray colour just to distinguish the header 
e.Graphics.FillRectangle(Brushes.LightGray, new Rectangle
	(100, 100, dataGridView1.Columns[0].Width, dataGridView1.Rows[0].Height)); 

//Draws a text inside the above drawn rectangle whose value is same of the first column. 

e.Graphics.DrawString(dataGridView1.Columns[0].HeaderText, 
	dataGridView1.Font, Brushes.Black, new RectangleF(100, 100, 
	dataGridView1.Columns[0].Width, dataGridView1.Rows[0].Height), str); 
}

Now we are able to draw or say replicate the first column of the datagridview on the page at location 100,100.

Now let's draw the second column which adjoins the first column horizontally. The position of y co-ordinate remains the same as columns span horizontally but the x position of the second column will change. It will now become 100 + dataGridView1.Columns[0].Width.

So repeat the above code in the snippet by just changing the x position of the DrawRectangle and DrawRectangleF method respectively. Here's the first one:

C#
e.Graphics.DrawRectangle(Pens.Black, 100 + dataGridView1.Columns[0].Width, 100, 
	dataGridView1.Columns[1].Width, dataGridView1.Rows[0].Height); 

To keep things simple, we will restrict our datagridview to only 2 columns. Now quickly let us draw the rows one by one by using the same trick as discussed above.

Store the origins(x and y) in variables, say x=100 and y=100.

Also:

C#
width= x + dataGridView1.Columns[0].Width; 
height=y; 

Before coding, there are few more important points to be discussed.

  1. We can get the number of Rows in a datagridview view by using the RowCount property.
  2. We need to run a loop to draw all the rows as is in the datagridveiw one by one.
  3. We need to check if your table height is exceeding the page height. If it exceeds, then the printing should continue on a new page, before directly printing the row on the new page first it should draw the column headers and continue drawing the row.
  4. Every time we print a new row, we need to increase the table height (nothing but y co-ordinate) by rowheight and let the x co-ordinate be at the same position, in our case it's 100, i.e. height+=rowheight;
  5. When we are printing the cells of a row, we only need to increase the x co-ordinate by colwidth each time and let the y co-ordinate(height) remain stationary, i.e. width += colwidth;

Here's the code snippet

C#
while (i < dataGridView1.Rows.Count)

rowheight=dataGridView1.Rows[i].Height; 

colwidth= dataGridView1.Columns[0].Width ; /*the columns width is same for all columns 

in our case */ 

if (height > e.MarginBounds.Height) 
{ 
height = x; //maintains the y co-ordinate 
width = y; //maintains the x co-ordinate 
e.HasMorePages = true; /*start printing on a new page,setting this property to true 

fires PagePrint event */ 

return; 
} 
height += rowheight; //increment the y co-ordinate 
e.Graphics.DrawRectangle(Pens.Black, x, height,colwidth,rowheight); 

e.Graphics.DrawString(dataGridView1.Rows[i].Cells[0].FormattedValue.ToString(), 
dataGridView1.Font, Brushes.Black, new RectangleF(x, height, colwidth,rowheight), str); 

e.Graphics.DrawRectangle(Pens.Black, y+ colwidth, height, colwidth, rowheight); 

e.Graphics.DrawString(dataGridView1.Rows[i].Cells[1].Value.ToString(), 
	dataGridView1.Font, Brushes.Black, new RectangleF(x+ colwidth, 
	height, width, rowheight), str); 
width += colwidth; //increment the x co- ordinate 
i++; 
} 

Behind the print button, type:

C#
PrintPreviewDialog1.Document=PrintDocument1;

Note: Declare the variable i as static or a class level variable:

printpreview.JPG

Cheers!

History

  • 6th November, 2009: Initial post

License

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


Written By
Software Developer
India India
My first love is C ,was alomost about to marry java(loved it too) but life took a different turn and finally ended by marrying C#.Now got adjusted to .NET and happy with it.
but occasionally code in C

Comments and Discussions

 
Questionnot working Pin
vaibhav 330-Dec-16 7:13
vaibhav 330-Dec-16 7:13 
Questionprint gridview data Pin
Brijesh Patel Mukhi30-Jul-15 20:07
Brijesh Patel Mukhi30-Jul-15 20:07 
QuestionPrint Line And Columns As in Bill Pin
Member 1160112212-Apr-15 9:08
Member 1160112212-Apr-15 9:08 
QuestionNot Printing the records Pin
swapnildhotre8-Aug-14 16:50
swapnildhotre8-Aug-14 16:50 
Question3 columns? Pin
ian1233313-Jun-14 21:07
ian1233313-Jun-14 21:07 
QuestionNot printing Pin
medev_the293-Apr-13 3:17
professionalmedev_the293-Apr-13 3:17 
I test this program exe as well as code. It's only print header not complete row.

So check .
QuestionNeed help for page setup Pin
chawnu24-Oct-12 6:37
chawnu24-Oct-12 6:37 
Questionwhy it continu generating previews??? Pin
intell8728-May-12 0:20
intell8728-May-12 0:20 
Questionwhy it continu counts... Pin
intell8727-May-12 23:38
intell8727-May-12 23:38 
Questionhow to add more columns Pin
himanshuh312-Aug-11 3:43
himanshuh312-Aug-11 3:43 
GeneralMy vote of 4 [modified] Pin
kmlslm2-Sep-10 4:42
kmlslm2-Sep-10 4:42 
GeneralRe: My vote of 4 [modified] Pin
megasorongo28-Mar-12 10:37
megasorongo28-Mar-12 10:37 

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.