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

简介: 今天有朋友请教在CS的WinForm中如何打印DataGridView中的内容。 网上搜索一番之后,还是在藏宝库CodeProject中找到一篇好文章《DataGridView Printing by Selecting Columns and Rows》(http://www.codeproject.com/KB/grid/PrintDataGrid_CS.aspx)效果图 【打印设置画面】 【打印预览画面】解决方案构成 这个打印解决方案由一个打印设置的窗体,及一个打印类组成。

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

目录
相关文章
|
人工智能 vr&ar
AIGC领域又有大动作了!AI视频“黑马”Morph Studio 来袭,1080P高清画质视频免费生成!
AIGC领域又有大动作了!AI视频“黑马”Morph Studio 来袭,1080P高清画质视频免费生成!
824 2
|
缓存 监控 Java
手把手教你在服务器如何免费搭建一套GPS定位系统平台
GPS定位系统一般是指部署在服务器端可以监控各类GPS北斗卫星定位硬件设备的系统软件,比如实时的位置和行驶轨迹等等。
6159 0
手把手教你在服务器如何免费搭建一套GPS定位系统平台
|
Java Maven
Gradle下载安装教程
gradle和maven一样都是用来构建java程序的,maven2004年开始兴起,gradle2012年开始诞生,既然已经有了maven这么成熟的构建工具为什么还有gradle的诞生呢,因为gradle有很多地方比maven做的更好,例如gradle采用groovy语言开发,语法更加简单,例如maven一个配置需要三行,而gradle只需要一行即可
3842 0
Gradle下载安装教程
|
7月前
|
云安全 运维 监控
阿里云CDN应急响应服务方案(转载)
阿里云推出CDN应急响应服务,提供7×24小时故障与安全双重保障:故障方面分级响应、专家快速定位修复;安全方面支持远程/现场处置,涵盖攻击遏制、恶意程序清理、溯源分析及加固指导,全面提升CDN稳定性与安全性。(239字)
487 1
阿里云CDN应急响应服务方案(转载)
|
6月前
|
人工智能 自然语言处理 Java
Java团队必看:为何转型AI应用开发已刻不容缓?
本文解析Java团队转型AI的必要性,从技术趋势、业务需求、开发效率三维度展开,并重点介绍JBoltAI框架如何通过统一API、事件驱动、开箱即用等功能,助力Java开发者低门槛构建智能问答、RAG、知识图谱等AI应用。(239字)
241 0
|
10月前
|
数据采集 监控 数据管理
如何评估数据质量?数据质量管理该如何进行?
本文探讨企业数据质量管理的核心挑战与解决方案,通过真实案例揭示数据不一致、重复、延迟等问题对业务决策的严重影响。提出从完整性、准确性、一致性等六大维度评估数据质量,并构建“定义-测量-分析-改进”的闭环管理体系。强调以关键数据资产为起点,推动业务与技术协同,实现数据质量的可持续管控,最终建立组织内对数据的信任与共识。
鸿蒙开发:自定义一个Toast
如果整个项目的toast样式都一样,直接在初始化中设置统一的属性即可,针对单独不一样的效果,可以单独设置。
425 2
鸿蒙开发:自定义一个Toast
|
机器学习/深度学习 存储 人工智能
《深度剖析:Q-learning与策略梯度方法的本质区别》
在强化学习领域,Q-learning和策略梯度方法是两种重要的算法。Q-learning通过迭代更新状态-动作值(Q值),评估动作价值,适用于离散动作空间;策略梯度方法则直接优化参数化策略,适合连续动作空间。前者收敛稳定但速度较慢,后者收敛快但稳定性差。两者各有优劣,适用于不同场景。
839 27
|
机器学习/深度学习 人工智能 安全
AI与旅游业:旅行规划的智能助手
在数字化浪潮中,人工智能(AI)正重塑旅游业。本文探讨了AI如何通过个性化推荐、智能预测与预警、语音交互与虚拟助手、增强现实体验及可持续发展,提升旅行规划的效率、安全性和趣味性,推动旅游业创新与变革。
1240 1
|
前端开发 JavaScript 安全
前端JS实现密码校验键盘横竖、26字母、相同字母、相同数字、密码包含用户名、数字 字母不能连续 不能相同三个、不能横向 竖向 连续三个 包含字符、不能有中文符号
该 JavaScript 代码实现了一个严格的密码校验功能,确保密码满足多种安全要求,包括长度、字符类型、不包含中文及特殊字符、不与用户名相似等。通过多个辅助函数,如 `validateFormat` 检查密码格式,`isHasChinaCharFun` 检测中文符号,`getCharAll` 生成键盘组合,以及 `checkPasswordFun` 综合验证密码的有效性和安全性。此工具对于提高用户账户的安全性非常有用。
1066 0