Вы находитесь на странице: 1из 10

Printing of DataGridView

Life with .NET, 31 Jul 2008 CPOL


4.75 (70 votes)

Rate this:
vote 1vote 2vote 3vote 4vote 5
This article will print all the records in a datagridview in tabular form
Download test application - 25.85 KB
Download pictures - 138.9 KB

Introduction
Few days ago, I had been working on an application, called Fee Management
System, which used to take the fee details from students and display the records
on the basis of certain search criteria in a grid. Then the fee collector could print
the entire details in the form of a report. Although, it was not a tedious task, the
integration of printing with the application took most of the time. So, I thought of
sharing my code with all the other developers who are working on the printing
of datagridview.

Using the Code


To simplify things, I made a sample application and used the Customers table of
Northwind database. In this application, we will have a simple form that will have
two button controls, one datagridview control and a print<code>document
control. The form will look as under (Figure 1):

On the click of Get Customer Details button, we will load the Company Name,
Contact Name, Address, Postal Code and Phone from the Customers table on to
the grid and with the help of the Print button, we will print all the records in the
grid. The following code snippet will make a call to Customers table and load the
data on to the grid:
Hide Shrink

Copy Code

>//Start Code Snippet


----------------------------------------------------------------------#region Get Customer Details Button Click Event
/// <span class="code-SummaryComment"><summary></span>
/// Handles the customer details button click
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name=""sender""></param></span>
/// <span class="code-SummaryComment"><param name=""e""></param></span>
private void btnCustomerDetails_Click(object sender, EventArgs e)
{
Cursor.Current = Cursors.WaitCursor;
SqlConnection sqlConnection = null;
SqlCommand sqlCommand = null;
SqlDataReader sqlReader = null;
try
{
string strQuery = "SELECT CompanyName, ContactName, Address, PostalCode,
Phone FROM Customers";
sqlConnection = new SqlConnection(strConnectionString);
sqlConnection.Open();

sqlCommand = new SqlCommand(strQuery, sqlConnection);


sqlReader = sqlCommand.ExecuteReader();
while (sqlReader.Read())
{
object[] row = { sqlReader[0], sqlReader[1], sqlReader[2], sqlReader[3],
sqlReader[4] };
dataGridView1.Rows.Add(row);
}
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
finally
{
Cursor.Current = Cursors.Default;
sqlConnection.Close();
if (sqlReader != null)
{
sqlReader.Dispose();
sqlReader = null;
}
if (sqlCommand != null)
{
sqlCommand.Dispose();
sqlCommand = null;
}
}
}
#endregion
----------------------------------------------------------------------//End Code Snippet

After executing the above code sample, we will have the grid with more than 90
records as shown in Figure 2:

Figure 2

And finally on click of Print button, we will print all the records in a tabular form as
shown in Figure 3:

The printdocument control plays a major role in this printing process. This control
has a PrintPage event that will have all the logic of printing. The spacing between
the cells, width of the cells, page margins are all handled in this event. Our print
click button event handler will invoke the PrintDialog control and there we can set
the printer, page and other settings. The following code sample will be used in the
Print button click event:
Hide Shrink

Copy Code

//Start Code Snippet


----------------------------------------------------------------------#region Print Button Click Event
/// <span class="code-SummaryComment"><summary></span>
/// Handles the print button click event
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name=""sender""></param></span>
/// <span class="code-SummaryComment"><param name=""e""></param></span>
private void btnPrint_Click(object sender, EventArgs e)
{
//Open the print dialog
PrintDialog printDialog = new PrintDialog();
printDialog.Document = printDocument1;
printDialog.UseEXDialog = true;

//Get the document


if (DialogResult.OK == printDialog.ShowDialog())
{
printDocument1.DocumentName = "Test Page Print";
printDocument1.Print();
}
/*
Note: In case you want to show the Print Preview Dialog instead of
Print Dialog then comment the above code and uncomment the following code
*/
//Open the print preview dialog
//PrintPreviewDialog objPPdialog = new PrintPreviewDialog();
//objPPdialog.Document = printDocument1;
//objPPdialog.ShowDialog();
}
#endregion
----------------------------------------------------------------------//End Code Snippet

So, the print button click will show the Print Dialog as shown in Figure 4:

This is a standard print dialog and you can change the settings here. Now, on the
click of Print button in Print Dialog control, the PrintPage event
of printdocument gets invoked and prints all the records in the grid in tabular form

as show in figure 4. The PrintDialogs Document property is set to


the printdocument control and to print the document, invoke the Print method
of printDocument control. This will invoke the PrintPage event of printDocument.
We have also handled the BeginPrint event of printDocument, where we
formatted the string to be printed. The following code sample will be called from
the BeginPrint event:
Hide Shrink

Copy Code

//Start Code Snippet


----------------------------------------------------------------------#region Begin Print Event Handler
/// <span class="code-SummaryComment"><summary></span>
/// Handles the begin print event of print document
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name=""sender""></param></span>
/// <span class="code-SummaryComment"><param name=""e""></param></span>
private void printDocument1_BeginPrint(object sender,
System.Drawing.Printing.PrintEventArgs e)
{
try
{
strFormat = new StringFormat();
strFormat.Alignment = StringAlignment.Near;
strFormat.LineAlignment = StringAlignment.Center;
strFormat.Trimming = StringTrimming.EllipsisCharacter;
arrColumnLefts.Clear();
arrColumnWidths.Clear();
iCellHeight = 0;
iCount = 0;
bFirstPage = true;
bNewPage = true;
// Calculating Total Widths
iTotalWidth = 0;
foreach (DataGridViewColumn dgvGridCol in dataGridView1.Columns)
{
iTotalWidth += dgvGridCol.Width;
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion
----------------------------------------------------------------------//End Code Snippet

And finally, we will call the PrintPage event which plays the crucial role in this
printing process. The following code sample is used within the PrintPage event:
Hide Shrink

Copy Code

//Start Code Snippet


----------------------------------------------------------------------#region Print Page Event
/// <span class="code-SummaryComment"><summary></span>
/// Handles the print page event of print document
/// <span class="code-SummaryComment"></summary></span>
/// <span class="code-SummaryComment"><param name=""sender""></param></span>
/// <span class="code-SummaryComment"><param name=""e""></param></span>
private void printDocument1_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
{
try
{
//Set the left margin
int iLeftMargin = e.MarginBounds.Left;
//Set the top margin
int iTopMargin = e.MarginBounds.Top;
//Whether more pages have to print or not
bool bMorePagesToPrint = false;
int iTmpWidth = 0;
//For the first page to print set the cell width and header height
if (bFirstPage)
{
foreach (DataGridViewColumn GridCol in dataGridView1.Columns)
{
iTmpWidth = (int)(Math.Floor((double)((double)GridCol.Width /
(double)iTotalWidth * (double)iTotalWidth *
((double)e.MarginBounds.Width / (double)iTotalWidth))));
iHeaderHeight = (int)(e.Graphics.MeasureString(GridCol.HeaderText,
GridCol.InheritedStyle.Font, iTmpWidth).Height) + 11;
// Save width and height of headers
arrColumnLefts.Add(iLeftMargin);
arrColumnWidths.Add(iTmpWidth);
iLeftMargin += iTmpWidth;
}
}
//Loop till all the grid rows not get printed
while (iRow <= dataGridView1.Rows.Count - 1)
{
DataGridViewRow GridRow = dataGridView1.Rows[iRow];
//Set the cell height
iCellHeight = GridRow.Height + 5;
int iCount = 0;
//Check whether the current page settings allows more rows to print
if (iTopMargin + iCellHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
{
bNewPage = true;
bFirstPage = false;
bMorePagesToPrint = true;
break;
}
else
{
if (bNewPage)
{
//Draw Header
e.Graphics.DrawString("Customer Summary",

new Font(dataGridView1.Font, FontStyle.Bold),


Brushes.Black, e.MarginBounds.Left,
e.MarginBounds.Top - e.Graphics.MeasureString("Customer Summary",
new Font(dataGridView1.Font,FontStyle.Bold),
e.MarginBounds.Width).Height - 13);
String strDate = DateTime.Now.ToLongDateString() + " " +
DateTime.Now.ToShortTimeString();
//Draw Date
e.Graphics.DrawString(strDate,
new Font(dataGridView1.Font, FontStyle.Bold), Brushes.Black,
e.MarginBounds.Left +
(e.MarginBounds.Width - e.Graphics.MeasureString (strDate,
new Font(dataGridView1.Font, FontStyle.Bold),
e.MarginBounds.Width).Width),
e.MarginBounds.Top - e.Graphics.MeasureString("Customer Summary",
new Font(new Font(dataGridView1.Font, FontStyle.Bold),
FontStyle.Bold), e.MarginBounds.Width).Height - 13);
//Draw Columns
iTopMargin = e.MarginBounds.Top;
foreach (DataGridViewColumn GridCol in dataGridView1.Columns)
{
e.Graphics.FillRectangle(new SolidBrush(Color.LightGray),
new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
(int)arrColumnWidths[iCount], iHeaderHeight));
e.Graphics.DrawRectangle(Pens.Black,
new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
(int)arrColumnWidths[iCount], iHeaderHeight));
e.Graphics.DrawString(GridCol.HeaderText,
GridCol.InheritedStyle.Font,
new SolidBrush(GridCol.InheritedStyle.ForeColor),
new RectangleF((int)arrColumnLefts[iCount], iTopMargin,
(int)arrColumnWidths[iCount], iHeaderHeight), strFormat);
iCount++;
}
bNewPage = false;
iTopMargin += iHeaderHeight;
}
iCount = 0;
//Draw Columns Contents
foreach (DataGridViewCell Cel in GridRow.Cells)
{
if (Cel.Value != null)
{
e.Graphics.DrawString(Cel.Value.ToString(),
Cel.InheritedStyle.Font,
new SolidBrush(Cel.InheritedStyle.ForeColor),
new RectangleF((int)arrColumnLefts[iCount],
(float)iTopMargin,
(int)arrColumnWidths[iCount], (float)iCellHeight),
strFormat);
}
//Drawing Cells Borders
e.Graphics.DrawRectangle(Pens.Black,
new Rectangle((int)arrColumnLefts[iCount], iTopMargin,
(int)arrColumnWidths[iCount], iCellHeight));
iCount++;

}
}
iRow++;
iTopMargin += iCellHeight;
}
//If more lines exist, print another page.
if (bMorePagesToPrint)
e.HasMorePages = true;
else
e.HasMorePages = false;
}
catch (Exception exc)
{
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
#endregion
----------------------------------------------------------------------//End Code Snippet

Here it is. You can see how easy the printing of datagridview records is. The
sample application is also attached for your reference. Let me know in case you
have any queries/issue

Вам также может понравиться