本文转载: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

转载于:https://www.cnblogs.com/51net/archive/2012/06/14/2479830.html

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

  1. 推荐一款文件文档在线预览解决方案

    真正的大师,永远都怀着一颗学徒的心! 今天给大家推荐一款文件文档在线预览解决方案.同学们,我们在开发的过程中,对于一些管理系统肯定有文档在线预览的需求.对于简单的文档,用谷歌的在线文档可以直接处理.但 ...

  2. 推荐一款基于Vue的开源智慧物业解决方案项目源码

    项目介绍 「e家宜业」是一整套基于AGPL开源协议开源的智慧物业解决方案.实现了微信公众号.小程序.PC.H5.智能硬件多端打通,旨在提升物业公司效率.规范物业服务流程.提升物业服务满意度.加强小区智 ...

  3. 一款Excel导入导出解决方案组成的轻量级开源组件

    Excel-Boot GitHub地址:gitee.com/nw1992/easy- 码云地址:github.com/programmere- Excel-Boot是一款Excel导入导出解决方案组成 ...

  4. easypoi导入校验跳过空行_Easy-POI是一款Excel导入导出解决方案组成的轻量级开源组件...

    Excel-Boot是一款Excel导入导出解决方案组成的轻量级开源组件. 如果喜欢或愿意使用, 请star本项目或者点击donate图标捐赠我们 如果是企业使用, 为了产品推广, 请通过评论.Iss ...

  5. easypoi 多sheet导入_easy-poi: Easy-POI是一款Excel导入导出解决方案组成的轻量级开源组件。...

    Easy-POI Easy-POI是一款Excel导入导出解决方案组成的轻量级开源组件. 如果喜欢或愿意使用, 请star并且Watch本项目或者移步码云捐赠我们 https://gitee.com/ ...

  6. 推荐14款强大的Mac修图利器,简约创意,让你随心所欲的创作

    如何让您的照片看起来更棒,并让人们喜欢的珍贵的纪念品,推荐14款强大的Mac修图利器,简约创意,让你随心所欲的创作,原来修图从未如此简单. 1.Luminar 4 Luminar 4 for mac( ...

  7. 向 Web 开发人员推荐35款 JavaScript 图形图表库

    图表是数据图形化的表示,通过形象的图表来展示数据,比如条形图,折线图,饼图等等.可视化图表可以帮助开发者更容易理解复杂的数据,提高生产的效率和 Web 应用和项目的可靠性. 在这篇文章中,我们收集了3 ...

  8. 推荐一款最好用Mysql数据库客户端

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 二师兄 来源 | 公众号「程序新视界」 今天给 ...

  9. 推荐3款 Docker 认证的实用免费插件,帮助您快速构建云原生应用程序!

    出品丨Docker公司(ID:docker-cn) 编译丨小东 每周一.三.五,与您不见不散! Docker 认证技术项目(Docker Certified Technology Program)是为 ...

  10. 解放双手!推荐一款阿里开源的低代码工具,YYDS!

    之前分享过一些低代码相关的文章,发现大家还是比较感兴趣的.之前在我印象中低代码就是通过图形化界面来生成代码而已,其实真正的低代码不仅要负责生成代码,还要负责代码的维护,把它当做一站式开发平台也不为过! ...

最新文章

  1. Java 客户端界面功能:停止当前操作
  2. [学习笔记]matlab
  3. 英语期末复习unit 3-4课后习题第一题及背诵段落
  4. Docker-compose 安装Minio 最新版本
  5. 剑指 Offer II 070. 排序数组中只出现一次的数字
  6. Python使用tkinter打造自定义对话框完整代码
  7. SpringBoot系列: Eclipse+Maven环境准备
  8. 深度学习简单线性训练
  9. ATA/SATA/SCSI/SAS/FC总线简介
  10. R语言中与矩阵相关的所有操作 (下)
  11. synchronized()_synchronized 和 ReentrantLock 有什么区别?
  12. [转载] Linux进程状态解析之R、S、D、T、Z、X
  13. poj 2567 code thr tree
  14. 织梦dedecms 内容管理系统模板标签代码参考
  15. 004 鸿蒙应用开发-通知栏
  16. 获取微信小程序右上角胶囊的位置
  17. 黑客 骚扰欺诈 呼死你之外还假冒给好友打电话
  18. 优化扩展live555支持MP2T(mpeg2ts)RTSP拉流附源代码
  19. 和平精英封十年修改服务器,和平精英反开挂系统升级,观战作弊最低封号十年,网友:大快人心...
  20. 有计算机学的大学,Brandeis有计算机专业排名经验揭秘精简篇

热门文章

  1. 【286页干货】一天搞懂深度学习(台湾资料科学年会课程)李宏毅
  2. Gensim进阶教程
  3. 简单尝试windows多线程程序
  4. win7+vs2015+pcl1.8.0配置
  5. uchar与char
  6. python3扫描_Python3实现TCP端口扫描器
  7. Docker教程小白实操入门(14)--如何使用CMD和ENTRYPOINT指令指定容器启动时要运行的命令
  8. 微信小程序云开发教程-产品原型的意义
  9. Hyperledger Fabric 或 Composer 获取指定Tx_id(transactionId)的信息
  10. php输入一个字符串 输出所有组合,C++_C语言实现输入一个字符串后打印出该字符串中字符的所有排列,本文实例讲述了C语言实现输入 - phpStudy...