专栏首页跟着阿笨一起玩NET推荐一款DataGridView的打印解决方案

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

今天有朋友请教在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 = ;



        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 = ;



                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 = ;

                RowsPerPage = ;



                // For various column types

                CellButton = new Button();

                CellCheckBox = new CheckBox();

                CellComboBox = new ComboBox();



                // Calculating Total Widths

                TotalWidth = ;

                foreach (DataGridViewColumn GridCol in dgv.Columns)

                {

                    if (!GridCol.Visible) continue;

                    if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;

                    TotalWidth += GridCol.Width;

                }

                PageNo = ;

                NewPage = true;

                RowPos = ;                

            }

            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 == ) 

                {

                    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) + ;

                        

                        // 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 - )

                {

                    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 - );



                            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 - );



                            // Draw Columns

                            tmpTop = e.MarginBounds.Top;

                            i = ;

                            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 = ;

                        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(, , 

                                        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(, );

                                CellCheckBox.Checked = (bool)Cel.Value;

                                Bitmap bmp = new Bitmap((int)ColumnWidths[i], CellHeight);

                                Graphics tmpGraphics = Graphics.FromImage(bmp);

                                tmpGraphics.FillRectangle(Brushes.White, new Rectangle(, , 

                                        bmp.Width, bmp.Height));

                                CellCheckBox.DrawToBitmap(bmp, 

                                        new Rectangle((int)((bmp.Width - CellCheckBox.Width) / ), 

                                        (int)((bmp.Height - CellCheckBox.Height) / ), 

                                        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(, , 

                                        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] + , tmpTop, (int)ColumnWidths[i]

                                        - , 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) / ), 

                                        tmpTop + (int)((CelSize.Height - ImgSize.Height) / ), 

                                        ((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 == ) RowsPerPage++;

                }



                if (RowsPerPage == ) 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 = ; 



            // Detemining rows number to print

            if (PrintAllRows)

            {

                if (dgv.Rows[dgv.Rows.Count - ].IsNewRow) 

                    cnt = dgv.Rows.Count - ; // When the DataGridView doesn't allow adding rows

                else

                    cnt = dgv.Rows.Count - ; // 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) / , e.MarginBounds.Top + 

                e.MarginBounds.Height + );

        }

    }

}

示例工程下载: testPrint

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Linq 分组(group by)求和(sum)并且按照分隔符(join)分割列数据

    转载:http://www.cnblogs.com/zq281660880/archive/2012/09/26/2704836.html

    跟着阿笨一起玩NET
  • Linux+Nginx+Supervisor部署ASP.NET Core实操手册

    3.3、通过supervisor守护进程设置dotnet core应用自动启动运行

    跟着阿笨一起玩NET
  • Unit Test单元测试时如何模拟HttpContext

    参考文章:http://blog.csdn.net/bclz_vs/article/details/6902638

    跟着阿笨一起玩NET
  • Android自定义View【实战教程】4⃣️----BitmapShader详解及圆形、圆角、多边形实现

    官方定义:Shader used to draw a bitmap as a texture BitmapShader的作用是使用特定的图片来作为纹理来使用...

    先知先觉
  • hbase源码系列(十三)缓存机制MemStore与Block Cache

    这一章讲hbase的缓存机制,这里面涉及的内容也是比较多,呵呵,我理解中的缓存是保存在内存中的特定的便于检索的数据结构就是缓存。 之前在讲put的时候,put是...

    岑玉海
  • CloudSim 的详解与调度扩展实现

    (1)云数据中心(Datacenter) (2)物理机(Host) (3)虚拟机(VM) (4)服务代理商(DatacenterBroker) (5)任...

    用户7625070
  • Android开发笔记(一百零三)地图与定位SDK

    国内常用的地图SDK就是百度和高德了,二者的用法大同小异,可按照官网上的开发指南一步步来。下面是我在集成地图SDK时遇到的问题说明: 1、点击基本地图功能...

    用户4464237
  • 史上最详细的Yolov3边框预测分析

    我们读yolov3论文时都知道边框预测的公式,然而难以准确理解为何作者要这么做,这里我就献丑来总结解释一下个人的见解,总结串联一下学习时容易遇到的疑惑,期待对大...

    BBuf
  • Hive在load data时注意事项

    create table if not exists bdp_log(         tableName string ,             dat...

    幽鸿
  • 用MyEclipse开发第一个JSP项目

     首先你得有一个破解版的MyEclipse,没有的话自行百度下载破解,我下载的是MyEclipse2017版本

    mathor

扫码关注云+社区

领取腾讯云代金券