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

  1. /**//* ***************************************************
  2.  * DataGridView打印类
  3.  * 原作者:Afrasiab Cheraghi. 
  4.  * 修改者:何奎
  5.  * 
  6.  * **************************************************/
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Windows.Forms;
  10. using System.Drawing;
  11. using System.Collections;
  12. using System.Data;
  13. using System.Text;
  14. namespace testPrint
  15. {
  16.     class PrintDGV
  17.     {
  18.         private static StringFormat StrFormat;  // Holds content of a TextBox Cell to write by DrawString
  19.         private static StringFormat StrFormatComboBox; // Holds content of a Boolean Cell to write by DrawImage
  20.         private static Button CellButton;       // Holds the Contents of Button Cell
  21.         private static CheckBox CellCheckBox;   // Holds the Contents of CheckBox Cell 
  22.         private static ComboBox CellComboBox;   // Holds the Contents of ComboBox Cell
  23.         private static int TotalWidth;          // Summation of Columns widths
  24.         private static int RowPos;              // Position of currently printing row 
  25.         private static bool NewPage;            // Indicates if a new page reached
  26.         private static int PageNo;              // Number of pages to print
  27.         private static ArrayList ColumnLefts = new ArrayList();  // Left Coordinate of Columns
  28.         private static ArrayList ColumnWidths = new ArrayList(); // Width of Columns
  29.         private static ArrayList ColumnTypes = new ArrayList();  // DataType of Columns
  30.         private static int CellHeight;          // Height of DataGrid Cell
  31.         private static int RowsPerPage;         // Number of Rows per Page
  32.         private static System.Drawing.Printing.PrintDocument printDoc =
  33.                        new System.Drawing.Printing.PrintDocument();  // PrintDocumnet Object used for printing
  34.         private static string PrintTitle = "";  // Header of pages
  35.         private static DataGridView dgv;        // Holds DataGridView Object to print its contents
  36.         private static List<string> SelectedColumns = new List<string>();   // The Columns Selected by user to print.
  37.         private static List<string> AvailableColumns = new List<string>();  // All Columns avaiable in DataGrid 
  38.         private static bool PrintAllRows = true;   // True = print all rows,  False = print selected rows    
  39.         private static bool FitToPageWidth = true// True = Fits selected columns to page width ,  False = Print columns as showed    
  40.         private static int HeaderHeight = 0;
  41.         public static void Print_DataGridView(DataGridView dgv1)
  42.         {
  43.             PrintPreviewDialog ppvw;
  44.             try 
  45.             {    
  46.                 // Getting DataGridView object to print
  47.                 dgv = dgv1;
  48.                 // Getting all Coulmns Names in the DataGridView
  49.                 AvailableColumns.Clear();
  50.                 foreach (DataGridViewColumn c in dgv.Columns)
  51.                 {
  52.                     if (!c.Visible) continue;
  53.                     AvailableColumns.Add(c.HeaderText);
  54.                 }
  55.                 // Showing the PrintOption Form
  56.                 PrintOptions dlg = new PrintOptions(AvailableColumns);
  57.                 if (dlg.ShowDialog() != DialogResult.OK) return;
  58.                 PrintTitle = dlg.PrintTitle;
  59.                 PrintAllRows = dlg.PrintAllRows;
  60.                 FitToPageWidth = dlg.FitToPageWidth;
  61.                 SelectedColumns = dlg.GetSelectedColumns();
  62.                 RowsPerPage = 0;
  63.                 ppvw = new PrintPreviewDialog();
  64.                 ppvw.Document = printDoc;
  65.                 // Showing the Print Preview Page
  66.                 printDoc.BeginPrint +=new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
  67.                 printDoc.PrintPage +=new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
  68.                 if (ppvw.ShowDialog() != DialogResult.OK)
  69.                 {
  70.                     printDoc.BeginPrint -= new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
  71.                     printDoc.PrintPage -= new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
  72.                     return;
  73.                 }
  74.                 // Printing the Documnet
  75.                 printDoc.Print();
  76.                 printDoc.BeginPrint -= new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
  77.                 printDoc.PrintPage -= new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
  78.             }
  79.             catch (Exception ex)
  80.             {
  81.                 MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);                
  82.             }
  83.             finally
  84.             {
  85.             }
  86.         }
  87.         private static void PrintDoc_BeginPrint(object sender, 
  88.                     System.Drawing.Printing.PrintEventArgs e) 
  89.         {
  90.             try
  91.             {
  92.                 // Formatting the Content of Text Cell to print
  93.                 StrFormat = new StringFormat();
  94.                 StrFormat.Alignment = StringAlignment.Near;
  95.                 StrFormat.LineAlignment = StringAlignment.Center;
  96.                 StrFormat.Trimming = StringTrimming.EllipsisCharacter;
  97.                 // Formatting the Content of Combo Cells to print
  98.                 StrFormatComboBox = new StringFormat();
  99.                 StrFormatComboBox.LineAlignment = StringAlignment.Center;
  100.                 StrFormatComboBox.FormatFlags = StringFormatFlags.NoWrap;
  101.                 StrFormatComboBox.Trimming = StringTrimming.EllipsisCharacter;
  102.                 ColumnLefts.Clear();
  103.                 ColumnWidths.Clear();
  104.                 ColumnTypes.Clear();
  105.                 CellHeight = 0;
  106.                 RowsPerPage = 0;
  107.                 // For various column types
  108.                 CellButton = new Button();
  109.                 CellCheckBox = new CheckBox();
  110.                 CellComboBox = new ComboBox();
  111.                 // Calculating Total Widths
  112.                 TotalWidth = 0;
  113.                 foreach (DataGridViewColumn GridCol in dgv.Columns)
  114.                 {
  115.                     if (!GridCol.Visible) continue;
  116.                     if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;
  117.                     TotalWidth += GridCol.Width;
  118.                 }
  119.                 PageNo = 1;
  120.                 NewPage = true;
  121.                 RowPos = 0;                
  122.             }
  123.             catch (Exception ex)
  124.             {
  125.                 MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);                
  126.             }
  127.         }
  128.         private static void PrintDoc_PrintPage(object sender, 
  129.                     System.Drawing.Printing.PrintPageEventArgs e) 
  130.         {
  131.             int tmpWidth, i;
  132.             int tmpTop = e.MarginBounds.Top;
  133.             int tmpLeft = e.MarginBounds.Left;
  134.             try 
  135.             {            
  136.                 // Before starting first page, it saves Width & Height of Headers and CoulmnType
  137.                 if (PageNo == 1) 
  138.                 {
  139.                     foreach (DataGridViewColumn GridCol in dgv.Columns)
  140.                     {
  141.                         if (!GridCol.Visible) continue;
  142.                         // Skip if the current column not selected
  143.                         if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;
  144.                         // Detemining whether the columns are fitted to page or not.
  145.                         if (FitToPageWidth) 
  146.                             tmpWidth = (int)(Math.Floor((double)((double)GridCol.Width / 
  147.                                        (double)TotalWidth * (double)TotalWidth * 
  148.                                        ((double)e.MarginBounds.Width / (double)TotalWidth))));
  149.                         else
  150.                             tmpWidth = GridCol.Width;
  151.                         HeaderHeight = (int)(e.Graphics.MeasureString(GridCol.HeaderText,
  152.                                     GridCol.InheritedStyle.Font, tmpWidth).Height) + 11;
  153.                         
  154.                         // Save width & height of headres and ColumnType
  155.                         ColumnLefts.Add(tmpLeft);
  156.                         ColumnWidths.Add(tmpWidth);
  157.                         ColumnTypes.Add(GridCol.GetType());
  158.                         tmpLeft += tmpWidth;
  159.                     }
  160.                 }
  161.                 // Printing Current Page, Row by Row
  162.                 while (RowPos <= dgv.Rows.Count - 1)
  163.                 {
  164.                     DataGridViewRow GridRow = dgv.Rows[RowPos];
  165.                     if (GridRow.IsNewRow || (!PrintAllRows && !GridRow.Selected))
  166.                     {
  167.                         RowPos++;
  168.                         continue;
  169.                     }
  170.                     CellHeight = GridRow.Height;
  171.                     if (tmpTop + CellHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
  172.                     {
  173.                         DrawFooter(e, RowsPerPage);
  174.                         NewPage = true;
  175.                         PageNo++;
  176.                         e.HasMorePages = true;
  177.                         return;
  178.                     }
  179.                     else
  180.                     {
  181.                         if (NewPage)
  182.                         {
  183.                             // Draw Header
  184.                             e.Graphics.DrawString(PrintTitle, new Font(dgv.Font, FontStyle.Bold), 
  185.                                     Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top -
  186.                             e.Graphics.MeasureString(PrintTitle, new Font(dgv.Font, 
  187.                                     FontStyle.Bold), e.MarginBounds.Width).Height - 13);
  188.                             String s = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString();
  189.                             e.Graphics.DrawString(s, new Font(dgv.Font, FontStyle.Bold), 
  190.                                     Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - 
  191.                                     e.Graphics.MeasureString(s, new Font(dgv.Font, 
  192.                                     FontStyle.Bold), e.MarginBounds.Width).Width), e.MarginBounds.Top - 
  193.                                     e.Graphics.MeasureString(PrintTitle, new Font(new Font(dgv.Font, 
  194.                                     FontStyle.Bold), FontStyle.Bold), e.MarginBounds.Width).Height - 13);
  195.                             // Draw Columns
  196.                             tmpTop = e.MarginBounds.Top;
  197.                             i = 0;
  198.                             foreach (DataGridViewColumn GridCol in dgv.Columns)
  199.                             {
  200.                                 if (!GridCol.Visible) continue;
  201.                                 if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) 
  202.                                     continue;
  203.                                 e.Graphics.FillRectangle(new SolidBrush(Color.LightGray), 
  204.                                     new Rectangle((int) ColumnLefts[i], tmpTop,
  205.                                     (int)ColumnWidths[i], HeaderHeight));
  206.                                 e.Graphics.DrawRectangle(Pens.Black, 
  207.                                     new Rectangle((int) ColumnLefts[i], tmpTop,
  208.                                     (int)ColumnWidths[i], HeaderHeight));
  209.                                 e.Graphics.DrawString(GridCol.HeaderText, GridCol.InheritedStyle.Font, 
  210.                                     new SolidBrush(GridCol.InheritedStyle.ForeColor),
  211.                                     new RectangleF((int)ColumnLefts[i], tmpTop, 
  212.                                     (int)ColumnWidths[i], HeaderHeight), StrFormat);
  213.                                 i++;
  214.                             }
  215.                             NewPage = false;
  216.                             tmpTop += HeaderHeight;
  217.                         }
  218.                         // Draw Columns Contents
  219.                         i = 0;
  220.                         foreach (DataGridViewCell Cel in GridRow.Cells)
  221.                         {
  222.                             if (!Cel.OwningColumn.Visible) continue;
  223.                             if (!SelectedColumns.Contains(Cel.OwningColumn.HeaderText))
  224.                                 continue;
  225.                             // For the TextBox Column
  226.                             if (((Type) ColumnTypes[i]).Name == "DataGridViewTextBoxColumn" || 
  227.                                 ((Type) ColumnTypes[i]).Name == "DataGridViewLinkColumn")
  228.                             {
  229.                                 e.Graphics.DrawString(Cel.Value.ToString(), Cel.InheritedStyle.Font, 
  230.                                         new SolidBrush(Cel.InheritedStyle.ForeColor),
  231.                                         new RectangleF((int)ColumnLefts[i], (float)tmpTop,
  232.                                         (int)ColumnWidths[i], (float)CellHeight), StrFormat);
  233.                             }
  234.                             // For the Button Column
  235.                             else if (((Type) ColumnTypes[i]).Name == "DataGridViewButtonColumn")
  236.                             {
  237.                                 CellButton.Text = Cel.Value.ToString();
  238.                                 CellButton.Size = new Size((int)ColumnWidths[i], CellHeight);
  239.                                 Bitmap bmp =new Bitmap(CellButton.Width, CellButton.Height);
  240.                                 CellButton.DrawToBitmap(bmp, new Rectangle(0, 0, 
  241.                                         bmp.Width, bmp.Height));
  242.                                 e.Graphics.DrawImage(bmp, new Point((int)ColumnLefts[i], tmpTop));
  243.                             }
  244.                             // For the CheckBox Column
  245.                             else if (((Type) ColumnTypes[i]).Name == "DataGridViewCheckBoxColumn")
  246.                             {
  247.                                 CellCheckBox.Size = new Size(14, 14);
  248.                                 CellCheckBox.Checked = (bool)Cel.Value;
  249.                                 Bitmap bmp = new Bitmap((int)ColumnWidths[i], CellHeight);
  250.                                 Graphics tmpGraphics = Graphics.FromImage(bmp);
  251.                                 tmpGraphics.FillRectangle(Brushes.White, new Rectangle(0, 0, 
  252.                                         bmp.Width, bmp.Height));
  253.                                 CellCheckBox.DrawToBitmap(bmp, 
  254.                                         new Rectangle((int)((bmp.Width - CellCheckBox.Width) / 2), 
  255.                                         (int)((bmp.Height - CellCheckBox.Height) / 2), 
  256.                                         CellCheckBox.Width, CellCheckBox.Height));
  257.                                 e.Graphics.DrawImage(bmp, new Point((int)ColumnLefts[i], tmpTop));
  258.                             }
  259.                             // For the ComboBox Column
  260.                             else if (((Type) ColumnTypes[i]).Name == "DataGridViewComboBoxColumn")
  261.                             {
  262.                                 CellComboBox.Size = new Size((int)ColumnWidths[i], CellHeight);
  263.                                 Bitmap bmp = new Bitmap(CellComboBox.Width, CellComboBox.Height);
  264.                                 CellComboBox.DrawToBitmap(bmp, new Rectangle(0, 0, 
  265.                                         bmp.Width, bmp.Height));
  266.                                 e.Graphics.DrawImage(bmp, new Point((int)ColumnLefts[i], tmpTop));
  267.                                 e.Graphics.DrawString(Cel.Value.ToString(), Cel.InheritedStyle.Font, 
  268.                                         new SolidBrush(Cel.InheritedStyle.ForeColor), 
  269.                                         new RectangleF((int)ColumnLefts[i] + 1, tmpTop, (int)ColumnWidths[i]
  270.                                         - 16, CellHeight), StrFormatComboBox);
  271.                             }
  272.                             // For the Image Column
  273.                             else if (((Type) ColumnTypes[i]).Name == "DataGridViewImageColumn")
  274.                             {
  275.                                 Rectangle CelSize = new Rectangle((int)ColumnLefts[i], 
  276.                                         tmpTop, (int)ColumnWidths[i], CellHeight);
  277.                                 Size ImgSize = ((Image)(Cel.FormattedValue)).Size;
  278.                                 e.Graphics.DrawImage((Image)Cel.FormattedValue, 
  279.                                         new Rectangle((int)ColumnLefts[i] + (int)((CelSize.Width - ImgSize.Width) / 2), 
  280.                                         tmpTop + (int)((CelSize.Height - ImgSize.Height) / 2), 
  281.                                         ((Image)(Cel.FormattedValue)).Width, ((Image)(Cel.FormattedValue)).Height));
  282.                             }
  283.                             // Drawing Cells Borders 
  284.                             e.Graphics.DrawRectangle(Pens.Black, new Rectangle((int)ColumnLefts[i], 
  285.                                     tmpTop, (int)ColumnWidths[i], CellHeight));
  286.                             i++;
  287.                         }
  288.                         tmpTop += CellHeight;
  289.                     }
  290.                     RowPos++;
  291.                     // For the first page it calculates Rows per Page
  292.                     if (PageNo == 1) RowsPerPage++;
  293.                 }
  294.                 if (RowsPerPage == 0) return;
  295.                 // Write Footer (Page Number)
  296.                 DrawFooter(e, RowsPerPage);
  297.                 e.HasMorePages = false;
  298.             }
  299.             catch (Exception ex)
  300.             {
  301.                 MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);                
  302.             }
  303.         }
  304.         private static void DrawFooter(System.Drawing.Printing.PrintPageEventArgs e, 
  305.                     int RowsPerPage)
  306.         {
  307.             double cnt = 0; 
  308.             // Detemining rows number to print
  309.             if (PrintAllRows)
  310.             {
  311.                 if (dgv.Rows[dgv.Rows.Count - 1].IsNewRow) 
  312.                     cnt = dgv.Rows.Count - 2; // When the DataGridView doesn't allow adding rows
  313.                 else
  314.                     cnt = dgv.Rows.Count - 1; // When the DataGridView allows adding rows
  315.             }
  316.             else
  317.                 cnt = dgv.SelectedRows.Count;
  318.             // Writing the Page Number on the Bottom of Page
  319.             string PageNum = " 第 " + PageNo.ToString()
  320.                            + " 页,共 " + Math.Ceiling((double)(cnt / RowsPerPage)).ToString()
  321.                            + " 页";
  322.             e.Graphics.DrawString(PageNum, dgv.Font, Brushes.Black, 
  323.                 e.MarginBounds.Left + (e.MarginBounds.Width - 
  324.                 e.Graphics.MeasureString(PageNum, dgv.Font, 
  325.                 e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + 
  326.                 e.MarginBounds.Height + 31);
  327.         }
  328.     }
  329. }
摘至: 推荐一款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(私有): 页脚的处理部分

打印类代码


 

与6.0版相比,控件6.01版的主要更改如下: 1、解决6.0版在XP及Windows Server 2008等操作系统下打印预览及打印不正确的问题(第1页正常,其他各页全部是空白)。 控件主要功能: 1、强大的DataGridView打印功能,不仅可以以多种形式(普通打印、分栏打印、跨页打印、工资条打印打印DGV表格,基本上能完全按DGV控件本身设置的格式如字体、字号、背景颜色、前景颜色、单元格对齐方式等打印出来,文字图像都可以打印,而且是完全根据表格当前的显示顺序进行打印的,基本上做到了所见即所得的打印。 2、报表设计功能。报表模板设计组件EasyReport可以设计普通报表、分组报表、套打模板等,以DataGridView为数据源。控件的位置以毫米为计量单位,定位准确,很适合套打单据设计。 3、图表打印功能。5.2版控件新增了一个Chartlet的组件,使用非常方便,可以生成柱形图、饼图、折线图等多种图形,而且可以设置2D或3D效果,既可以在打印控件中打印出来,也可以在Graphics对象中显示。 4、文本打印输出功能,控件提供多个文本打印重载函数,打印文本时,如果需要,控件会自动换行和换页打印输出。还增加了以指定行间距及字符间距打印文本的功能,可以用固定行距,也可以用单倍或多倍行距打印文本。 5、绘图功能,基本上.NET的GDI+的绘图函数(如直线、矩形、路径、多边形、曲线等)都有,只有个别函数的名称有点区别。 6、支持同一文档多种版面格式打印(类似于Word中的节的功能):对同一份文档,不同的页面可以设置不同的格式(纸张大小、纸张方向、页边距),只需要在新增一页时在NewPage方法中指定要使用的页面格式即可,使用非常简单。 7、报表文件保存功能。本控件允许将当前打印预览的内容保存为报表文件,以后使用本控件重新打开该报表文件即可重现原来保存报表时的打印内容。 8、数据导出功能,可以将DataGridView导出为Excel\PDF\RTF\HTML文件,5.7版控件使用开源的NPOI导出Excel,速度非常快,效果非常好。 9、强大的容器控件打印功能(DrawPanel函数)。借助该函数,您只需要在您的容器控件中设计好要打印的内容及打印内容的相对位置,控件轻松帮你打印出来(如果超过一页,控件会自动换页续打)。 10、5.6版新增的SimpleReport组件允许您在一个方案文件中管理多个打印方案,在打印预览时能自由在各个打印方案之间切换。 11、RichTextBox控件的RTF文本打印功能。 12、页眉页脚中既可打印文字,也可打印图像,或者即打印图像又打印输出文字。 13、多表头(跨行跨列的复杂表头)打印功能,多表头组件支持多表头显示与打印、单元格内容的合并显示、打印与导出。 14、自定义纸张支持功能。 15、直接打印窗口中的TreeView控件功能。 16、打印窗口中的ListView功能。 17、斜线表头打印功能。 18、各种条形码(包括二维码)打印功能。 19、5.7版控件增加了使用开源的NPOI从Excel文件(支持2003与2007格式)中导入数据到DataGridView的功能,以及DataGridView的复制与粘贴功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值