您的位置:首页 > 其它

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

2011-12-20 11:04 218 查看
转自:/article/4881264.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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: