65.9K
CodeProject 正在变化。 阅读更多。
Home

打印DataGridView

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.69/5 (72投票s)

2008年7月23日

CPOL

3分钟阅读

viewsIcon

537290

downloadIcon

48021

本文将以表格形式打印datagridview中的所有记录

引言

几天前,我一直在开发一个名为“费用管理系统”的应用程序,该应用程序用于从学生那里获取费用详细信息,并根据网格中的某些搜索条件显示记录。然后,收费员可以以报告的形式打印出所有的详细信息。虽然这不是一项繁琐的任务,但将打印功能与应用程序集成却花费了大部分时间。因此,我想与其他所有正在进行 datagridview 打印工作的开发人员分享我的代码。

Using the Code

为了简化操作,我制作了一个示例应用程序,并使用了 Northwind 数据库的 Customers 表。 在此应用程序中,我们将有一个简单的窗体,该窗体将具有两个 button 控件、一个 datagridview 控件和一个 printdocument 控件。 窗体将如下所示(图 1)

图 1

单击“获取客户详细信息”按钮后,我们将从 Customers 表加载“公司名称”、“联系人姓名”、“地址”、“邮政编码”和“电话”到网格上,并在“打印”按钮的帮助下,我们将打印网格中的所有记录。 以下代码段将调用 Customers 表并将数据加载到网格上

>//Start Code Snippet
-----------------------------------------------------------------------
#region Get Customer Details Button Click Event
/// <summary>
/// Handles the customer details button click
/// </summary>
/// <param name=""sender""></param>
/// <param name=""e""></param>
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

执行以上代码示例后,我们将获得包含 90 多条记录的网格,如图 2 所示

图 2

最后,单击“打印”按钮,我们将以表格形式打印所有记录,如图 3 所示

图 3

printdocument 控件在此打印过程中起着重要作用。此控件具有一个 PrintPage 事件,其中包含所有打印逻辑。单元格之间的间距、单元格的宽度、页面边距都在此事件中处理。我们的打印单击按钮事件处理程序将调用 PrintDialog 控件,我们可以在其中设置打印机、页面和其他设置。 以下代码示例将在“打印”按钮单击事件中使用

//Start Code Snippet
-----------------------------------------------------------------------
#region Print Button Click Event
/// <summary>
/// Handles the print button click event
/// </summary>
/// <param name=""sender""></param>
/// <param name=""e""></param>
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

因此,打印按钮单击将显示“打印对话框”,如图 4 所示

图 4

这是一个标准的打印对话框,您可以在此处更改设置。 现在,在“打印对话框”控件中单击“打印”按钮时,将调用 printdocumentPrintPage 事件,并以表格形式打印网格中的所有记录,如图 4 所示。 PrintDialogDocument 属性设置为 printdocument 控件,要打印文档,请调用 printDocument 控件的 Print 方法。 这将调用 printDocumentPrintPage 事件。 我们还处理了 printDocumentBeginPrint 事件,我们在其中格式化了要打印的 string。 以下代码示例将从 BeginPrint 事件中调用

//Start Code Snippet
-----------------------------------------------------------------------
#region Begin Print Event Handler
/// <summary>
/// Handles the begin print event of print document
/// </summary>
/// <param name=""sender""></param>
/// <param name=""e""></param>
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

最后,我们将调用 PrintPage 事件,该事件在此打印过程中起着至关重要的作用。 以下代码示例在 PrintPage 事件中使用

//Start Code Snippet
-----------------------------------------------------------------------
#region Print Page Event
/// <summary>
/// Handles the print page event of print document
/// </summary>
/// <param name=""sender""></param>
/// <param name=""e""></param>
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

就在这里。您可以看到打印 datagridview 记录有多么容易。 示例应用程序也已附上供您参考。 如果您有任何疑问/问题,请告诉我。

编程愉快!

© . All rights reserved.