推荐一款DataGridView的打印解决方案

简介: 本文转载:http://www.cnblogs.com/heekui/archive/2007/05/29/764531.html 今天有朋友请教在CS的WinForm中如何打印DataGridView中的内容。

本文转载:http://www.cnblogs.com/heekui/archive/2007/05/29/764531.html

 


今天有朋友请教在CS的WinForm中如何打印DataGridView中的内容。
网上搜索一番之后,还是在藏宝库CodeProject中找到一篇好文章《DataGridView
Printing by Selecting Columns and Rows》(http://www.codeproject.com/KB/grid/PrintDataGrid_CS.aspx

效果图
【打印设置画面】




【打印预览画面】


解决方案构成
这个打印解决方案由一个打印设置的窗体,及一个打印类组成。
可用于以下场景:
1、显示的数据量较大,但又没有必要打印全部数据的时候
2、希望打印出的列宽能自动适应页面宽度

打印类主要方法
Print_DataGridView(共有):
被外部类调用的主方法.
PrintDoc_BeginPrint(私有): 初始化一些打印变量

PrintDoc_PrintPage(私有): 执行打印工作

DrawFooter(私有): 页脚的处理部分


打印类代码


/**//* ***************************************************
* DataGridView打印类
* 原作者:Afrasiab Cheraghi.
* 修改者:何奎
*
* *************************************************
*/


using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Collections;
using System.Data;
using System.Text;

namespace testPrint
{
   
class PrintDGV
   
{
       
private static StringFormat StrFormat;  // Holds content of a TextBox Cell to write by DrawString
        private static StringFormat StrFormatComboBox; // Holds content of a Boolean Cell to write by DrawImage
        private static Button CellButton;       // Holds the Contents of Button Cell
        private static CheckBox CellCheckBox;   // Holds the Contents of CheckBox Cell
        private static ComboBox CellComboBox;   // Holds the Contents of ComboBox Cell

       
private static int TotalWidth;          // Summation of Columns widths
        private static int RowPos;              // Position of currently printing row
        private static bool NewPage;            // Indicates if a new page reached
        private static int PageNo;              // Number of pages to print
        private static ArrayList ColumnLefts = new ArrayList();  // Left Coordinate of Columns
        private static ArrayList ColumnWidths = new ArrayList(); // Width of Columns
        private static ArrayList ColumnTypes = new ArrayList();  // DataType of Columns
        private static int CellHeight;          // Height of DataGrid Cell
        private static int RowsPerPage;         // Number of Rows per Page
        private static System.Drawing.Printing.PrintDocument printDoc =
                      
new System.Drawing.Printing.PrintDocument();  // PrintDocumnet Object used for printing

       
private static string PrintTitle = ""// Header of pages
        private static DataGridView dgv;        // Holds DataGridView Object to print its contents
        private static List<string> SelectedColumns = new List<string>();   // The Columns Selected by user to print.
        private static List<string> AvailableColumns = new List<string>();  // All Columns avaiable in DataGrid
        private static bool PrintAllRows = true;   // True = print all rows,  False = print selected rows   
        private static bool FitToPageWidth = true; // True = Fits selected columns to page width ,  False = Print columns as showed   
        private static int HeaderHeight = 0;

       
public static void Print_DataGridView(DataGridView dgv1)
       
{
            PrintPreviewDialog ppvw;
           
try
           
{   
               
// Getting DataGridView object to print
                dgv = dgv1;

               
// Getting all Coulmns Names in the DataGridView
                AvailableColumns.Clear();
               
foreach (DataGridViewColumn c in dgv.Columns)
               
{
                   
if (!c.Visible) continue;
                    AvailableColumns.Add(c.HeaderText);
                }


               
// Showing the PrintOption Form
                PrintOptions dlg = new PrintOptions(AvailableColumns);
               
if (dlg.ShowDialog() != DialogResult.OK) return;

                PrintTitle
= dlg.PrintTitle;
                PrintAllRows
= dlg.PrintAllRows;
                FitToPageWidth
= dlg.FitToPageWidth;
                SelectedColumns
= dlg.GetSelectedColumns();

                RowsPerPage
= 0;

                ppvw
= new PrintPreviewDialog();
                ppvw.Document
= printDoc;

               
// Showing the Print Preview Page
                printDoc.BeginPrint +=new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
                printDoc.PrintPage
+=new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
               
if (ppvw.ShowDialog() != DialogResult.OK)
               
{
                    printDoc.BeginPrint
-= new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
                    printDoc.PrintPage
-= new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
                   
return;
                }


               
// Printing the Documnet
                printDoc.Print();
                printDoc.BeginPrint
-= new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
                printDoc.PrintPage
-= new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
            }

           
catch (Exception ex)
           
{
                MessageBox.Show(ex.Message,
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);               
            }

           
finally
           
{

            }

        }


       
private static void PrintDoc_BeginPrint(object sender,
                    System.Drawing.Printing.PrintEventArgs e)
       
{
           
try
           
{
               
// Formatting the Content of Text Cell to print
                StrFormat = new StringFormat();
                StrFormat.Alignment
= StringAlignment.Near;
                StrFormat.LineAlignment
= StringAlignment.Center;
                StrFormat.Trimming
= StringTrimming.EllipsisCharacter;

               
// Formatting the Content of Combo Cells to print
                StrFormatComboBox = new StringFormat();
                StrFormatComboBox.LineAlignment
= StringAlignment.Center;
                StrFormatComboBox.FormatFlags
= StringFormatFlags.NoWrap;
                StrFormatComboBox.Trimming
= StringTrimming.EllipsisCharacter;

                ColumnLefts.Clear();
                ColumnWidths.Clear();
                ColumnTypes.Clear();
                CellHeight
= 0;
                RowsPerPage
= 0;

               
// For various column types
                CellButton = new Button();
                CellCheckBox
= new CheckBox();
                CellComboBox
= new ComboBox();

               
// Calculating Total Widths
                TotalWidth = 0;
               
foreach (DataGridViewColumn GridCol in dgv.Columns)
               
{
                   
if (!GridCol.Visible) continue;
                   
if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;
                    TotalWidth
+= GridCol.Width;
                }

                PageNo
= 1;
                NewPage
= true;
                RowPos
= 0;               
            }

           
catch (Exception ex)
           
{
                MessageBox.Show(ex.Message,
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);               
            }

        }


       
private static void PrintDoc_PrintPage(object sender,
                    System.Drawing.Printing.PrintPageEventArgs e)
       
{
           
int tmpWidth, i;
           
int tmpTop = e.MarginBounds.Top;
           
int tmpLeft = e.MarginBounds.Left;

           
try
           
{           
               
// Before starting first page, it saves Width & Height of Headers and CoulmnType
                if (PageNo == 1)
               
{
                   
foreach (DataGridViewColumn GridCol in dgv.Columns)
                   
{
                       
if (!GridCol.Visible) continue;
                       
// Skip if the current column not selected
                        if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;

                       
// Detemining whether the columns are fitted to page or not.
                        if (FitToPageWidth)
                            tmpWidth
= (int)(Math.Floor((double)((double)GridCol.Width /
                                       (
double)TotalWidth * (double)TotalWidth *
                                       ((
double)e.MarginBounds.Width / (double)TotalWidth))));
                       
else
                            tmpWidth
= GridCol.Width;

                        HeaderHeight
= (int)(e.Graphics.MeasureString(GridCol.HeaderText,
                                    GridCol.InheritedStyle.Font, tmpWidth).Height)
+ 11;
                       
                       
// Save width & height of headres and ColumnType
                        ColumnLefts.Add(tmpLeft);
                        ColumnWidths.Add(tmpWidth);
                        ColumnTypes.Add(GridCol.GetType());
                        tmpLeft
+= tmpWidth;
                    }

                }


               
// Printing Current Page, Row by Row
                while (RowPos <= dgv.Rows.Count - 1)
               
{
                    DataGridViewRow GridRow
= dgv.Rows[RowPos];
                   
if (GridRow.IsNewRow || (!PrintAllRows && !GridRow.Selected))
                   
{
                        RowPos
++;
                       
continue;
                    }


                    CellHeight
= GridRow.Height;

                   
if (tmpTop + CellHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
                   
{
                        DrawFooter(e, RowsPerPage);
                        NewPage
= true;
                        PageNo
++;
                        e.HasMorePages
= true;
                       
return;
                    }

                   
else
                   
{
                       
if (NewPage)
                       
{
                           
// Draw Header
                            e.Graphics.DrawString(PrintTitle, new Font(dgv.Font, FontStyle.Bold),
                                    Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top
-
                            e.Graphics.MeasureString(PrintTitle,
new Font(dgv.Font,
                                    FontStyle.Bold), e.MarginBounds.Width).Height
- 13);

                            String s
= DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString();

                            e.Graphics.DrawString(s,
new Font(dgv.Font, FontStyle.Bold),
                                    Brushes.Black, e.MarginBounds.Left
+ (e.MarginBounds.Width -
                                    e.Graphics.MeasureString(s,
new Font(dgv.Font,
                                    FontStyle.Bold), e.MarginBounds.Width).Width), e.MarginBounds.Top
-
                                    e.Graphics.MeasureString(PrintTitle,
new Font(new Font(dgv.Font,
                                    FontStyle.Bold), FontStyle.Bold), e.MarginBounds.Width).Height
- 13);

                           
// Draw Columns
                            tmpTop = e.MarginBounds.Top;
                            i
= 0;
                           
foreach (DataGridViewColumn GridCol in dgv.Columns)
                           
{
                               
if (!GridCol.Visible) continue;
                               
if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText))
                                   
continue;

                                e.Graphics.FillRectangle(
new SolidBrush(Color.LightGray),
                                   
new Rectangle((int) ColumnLefts[i], tmpTop,
                                    (
int)ColumnWidths[i], HeaderHeight));

                                e.Graphics.DrawRectangle(Pens.Black,
                                   
new Rectangle((int) ColumnLefts[i], tmpTop,
                                    (
int)ColumnWidths[i], HeaderHeight));

e.Graphics.DrawString(GridCol.HeaderText, GridCol.InheritedStyle.Font,
                                   
new SolidBrush(GridCol.InheritedStyle.ForeColor),
                                   
new RectangleF((int)ColumnLefts[i], tmpTop,
                                    (
int)ColumnWidths[i], HeaderHeight), StrFormat);
                                i
++;
                            }

                            NewPage
= false;
                            tmpTop
+= HeaderHeight;
                        }


                       
// Draw Columns Contents
                        i = 0;
                       
foreach (DataGridViewCell Cel in GridRow.Cells)
                       
{
                           
if (!Cel.OwningColumn.Visible) continue;
                           
if (!SelectedColumns.Contains(Cel.OwningColumn.HeaderText))
                               
continue;

                           
// For the TextBox Column
                            if (((Type) ColumnTypes[i]).Name == "DataGridViewTextBoxColumn" ||
                                ((Type) ColumnTypes[i]).Name
== "DataGridViewLinkColumn")
                           
{
                                e.Graphics.DrawString(Cel.Value.ToString(), Cel.InheritedStyle.Font,
                                       
new SolidBrush(Cel.InheritedStyle.ForeColor),
                                       
new RectangleF((int)ColumnLefts[i], (float)tmpTop,
                                        (
int)ColumnWidths[i], (float)CellHeight), StrFormat);
                            }

                           
// For the Button Column
                            else if (((Type) ColumnTypes[i]).Name == "DataGridViewButtonColumn")
                           
{
                                CellButton.Text
= Cel.Value.ToString();
                                CellButton.Size
= new Size((int)ColumnWidths[i], CellHeight);
                                Bitmap bmp
=new Bitmap(CellButton.Width, CellButton.Height);
                                CellButton.DrawToBitmap(bmp,
new Rectangle(0, 0,
                                        bmp.Width, bmp.Height));
                                e.Graphics.DrawImage(bmp,
new Point((int)ColumnLefts[i], tmpTop));
                            }

                           
// For the CheckBox Column
                            else if (((Type) ColumnTypes[i]).Name == "DataGridViewCheckBoxColumn")
                           
{
                                CellCheckBox.Size
= new Size(14, 14);
                                CellCheckBox.Checked
= (bool)Cel.Value;
                                Bitmap bmp
= new Bitmap((int)ColumnWidths[i], CellHeight);
                                Graphics tmpGraphics
= Graphics.FromImage(bmp);
                                tmpGraphics.FillRectangle(Brushes.White,
new Rectangle(0, 0,
                                        bmp.Width, bmp.Height));
                                CellCheckBox.DrawToBitmap(bmp,
                                       
new Rectangle((int)((bmp.Width - CellCheckBox.Width) / 2),
                                        (
int)((bmp.Height - CellCheckBox.Height) / 2),
                                        CellCheckBox.Width, CellCheckBox.Height));
                                e.Graphics.DrawImage(bmp,
new Point((int)ColumnLefts[i], tmpTop));
                            }

                           
// For the ComboBox Column
                            else if (((Type) ColumnTypes[i]).Name == "DataGridViewComboBoxColumn")
                           
{
                                CellComboBox.Size
= new Size((int)ColumnWidths[i], CellHeight);
                                Bitmap bmp
= new Bitmap(CellComboBox.Width, CellComboBox.Height);
                                CellComboBox.DrawToBitmap(bmp,
new Rectangle(0, 0,
                                        bmp.Width, bmp.Height));
                                e.Graphics.DrawImage(bmp,
new Point((int)ColumnLefts[i], tmpTop));
                                e.Graphics.DrawString(Cel.Value.ToString(), Cel.InheritedStyle.Font,
                                       
new SolidBrush(Cel.InheritedStyle.ForeColor),
                                       
new RectangleF((int)ColumnLefts[i] + 1, tmpTop, (int)ColumnWidths[i]
                                       
- 16, CellHeight), StrFormatComboBox);
                            }

                           
// For the Image Column
                            else if (((Type) ColumnTypes[i]).Name == "DataGridViewImageColumn")
                           
{
                                Rectangle CelSize
= new Rectangle((int)ColumnLefts[i],
                                        tmpTop, (
int)ColumnWidths[i], CellHeight);
                                Size ImgSize
= ((Image)(Cel.FormattedValue)).Size;
                                e.Graphics.DrawImage((Image)Cel.FormattedValue,
                                       
new Rectangle((int)ColumnLefts[i] + (int)((CelSize.Width - ImgSize.Width) / 2),
                                        tmpTop
+ (int)((CelSize.Height - ImgSize.Height) / 2),
                                        ((Image)(Cel.FormattedValue)).Width, ((Image)(Cel.FormattedValue)).Height));

                            }


                           
// Drawing Cells Borders
                            e.Graphics.DrawRectangle(Pens.Black, new Rectangle((int)ColumnLefts[i],
                                    tmpTop, (
int)ColumnWidths[i], CellHeight));

                            i
++;

                        }

                        tmpTop
+= CellHeight;
                    }


                    RowPos
++;
                   
// For the first page it calculates Rows per Page
                    if (PageNo == 1) RowsPerPage++;
                }


               
if (RowsPerPage == 0) return;

               
// Write Footer (Page Number)
                DrawFooter(e, RowsPerPage);

                e.HasMorePages
= false;
            }

           
catch (Exception ex)
           
{
                MessageBox.Show(ex.Message,
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);               
            }

        }


       
private static void DrawFooter(System.Drawing.Printing.PrintPageEventArgs e,
                   
int RowsPerPage)
       
{
           
double cnt = 0;

           
// Detemining rows number to print
            if (PrintAllRows)
           
{
               
if (dgv.Rows[dgv.Rows.Count - 1].IsNewRow)
                    cnt
= dgv.Rows.Count - 2; // When the DataGridView doesn't allow adding rows
                else
                    cnt
= dgv.Rows.Count - 1; // When the DataGridView allows adding rows
            }

           
else
                cnt
= dgv.SelectedRows.Count;

           
// Writing the Page Number on the Bottom of Page
            string PageNum = "" + PageNo.ToString()
                          
+ " 页,共 " + Math.Ceiling((double)(cnt / RowsPerPage)).ToString()
                          
+ "";

            e.Graphics.DrawString(PageNum, dgv.Font, Brushes.Black,
                e.MarginBounds.Left
+ (e.MarginBounds.Width -
                e.Graphics.MeasureString(PageNum, dgv.Font,
                e.MarginBounds.Width).Width)
/ 2, e.MarginBounds.Top +
                e.MarginBounds.Height
+ 31);
        }

    }

}



示例工程下载:
testPrint



目录
相关文章
|
8月前
|
人工智能 自然语言处理 机器人
Function Calling
Function Calling是大语言模型从“知”到“行”的关键突破,让AI不仅能回答问题,更能调用外部工具执行查天气、订机票、生成报表等实际任务。它使LLM从聊天机器人进化为智能体,实现意图理解、决策与行动闭环,推动AI迈向自动化与智能化新纪元。
|
9月前
|
运维 Linux 开发者
Linux系统中使用Python的ping3库进行网络连通性测试
以上步骤展示了如何利用 Python 的 `ping3` 库来检测网络连通性,并且提供了基本错误处理方法以确保程序能够优雅地处理各种意外情形。通过简洁明快、易读易懂、实操性强等特点使得该方法非常适合开发者或系统管理员快速集成至自动化工具链之内进行日常运维任务之需求满足。
618 18
|
存储 Web App开发 搜索推荐
macOS Sonoma 14.7.5 (23H527) Boot ISO 原版可引导镜像下载
macOS Sonoma 14.7.5 (23H527) Boot ISO 原版可引导镜像下载
523 1
macOS Sonoma 14.7.5 (23H527) Boot ISO 原版可引导镜像下载
|
算法 Java JavaScript
规则引擎
我是阿里巴巴做规则引擎相关工作多年的java工程师一枚,本职工作就是通过规则引擎、规则管理平台等技术输出,来应对阿里巴巴复杂多变的上层规则相关业务的支持。限于技术保密、安全等因素,本文只讲一些个人对“规则引擎”的看法,欢迎大家一起探讨。
27108 1
|
tengine 应用服务中间件 nginx
Tengine命令安装教程
该内容提供了一套详细的步骤指南,用于通过 FinalShell 远程连接并安装 Tengine 服务器。从下载与配置 Tengine,到使用 yum 安装必要的组件,再到编译、安装及配置 Nginx,以及如何处理 HTTPS 部署和证书设置,最后涵盖了基本的站点程序控制命令。此外,还提供了隐藏版本号的方法及文本编辑技巧。
|
Java Android开发
Android 导航方式切换
Android 导航方式切换
750 1
|
5G 网络架构
带你读《5G 系统技术原理与实现》精品文章合集
带你读《5G 系统技术原理与实现》精品文章合集
|
Kubernetes Linux 网络安全
K8S 离线安装版 1.23.1
在准备Kubernetes (k8s) 集群部署时,执行了以下步骤: 1. 关闭防火墙和服务:`systemctl stop firewalld && systemctl disable firewalld`,并禁用SELinux和swap。 2. 添加主机条目到`/etc/hosts`,同步时间使用`ntpdate time.windows.com`。 3. 设置k8s仓库源,安装必要的工具,如`yum install yum-utils -y`。 4. 安装Docker,并下载k8s相关软件包。 5. 制作离线包,使用`docker save`保存镜像,然后在目标机器上用`docker
1776 0
|
程序员 图形学

热门文章

最新文章