本文转载: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)
效果图
【打印设置画面】
![](https://images.cnblogs.com/cnblogs_com/heekui/PrintDataGridView1.jpg)
【打印预览画面】
![](https://images.cnblogs.com/cnblogs_com/heekui/PrintDataGridView2.jpg)
解决方案构成
这个打印解决方案由一个打印设置的窗体,及一个打印类组成。
可用于以下场景:
1、显示的数据量较大,但又没有必要打印全部数据的时候
2、希望打印出的列宽能自动适应页面宽度
打印类主要方法
Print_DataGridView(共有)
:
被外部类调用的主方法.
PrintDoc_BeginPrint(私有)
: 初始化一些打印变量
PrintDoc_PrintPage(私有)
: 执行打印工作
DrawFooter(私有)
: 页脚的处理部分
打印类代码
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//* ***************************************************
* DataGridView打印类
* 原作者:Afrasiab Cheraghi.
* 修改者:何奎
*
* **************************************************/
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Drawing;
using System.Collections;
using System.Data;
using System.Text;
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
namespace testPrint
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
class PrintDGV
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
public static void Print_DataGridView(DataGridView dgv1)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
PrintPreviewDialog ppvw;
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// Getting DataGridView object to print
dgv = dgv1;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Getting all Coulmns Names in the DataGridView
AvailableColumns.Clear();
foreach (DataGridViewColumn c in dgv.Columns)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!c.Visible) continue;
AvailableColumns.Add(c.HeaderText);
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Showing the PrintOption Form
PrintOptions dlg = new PrintOptions(AvailableColumns);
if (dlg.ShowDialog() != DialogResult.OK) return;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
PrintTitle = dlg.PrintTitle;
PrintAllRows = dlg.PrintAllRows;
FitToPageWidth = dlg.FitToPageWidth;
SelectedColumns = dlg.GetSelectedColumns();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RowsPerPage = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ppvw = new PrintPreviewDialog();
ppvw.Document = printDoc;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 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)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
printDoc.BeginPrint -= new System.Drawing.Printing.PrintEventHandler(PrintDoc_BeginPrint);
printDoc.PrintPage -= new System.Drawing.Printing.PrintPageEventHandler(PrintDoc_PrintPage);
return;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 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)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
finally
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private static void PrintDoc_BeginPrint(object sender,
System.Drawing.Printing.PrintEventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// Formatting the Content of Text Cell to print
StrFormat = new StringFormat();
StrFormat.Alignment = StringAlignment.Near;
StrFormat.LineAlignment = StringAlignment.Center;
StrFormat.Trimming = StringTrimming.EllipsisCharacter;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Formatting the Content of Combo Cells to print
StrFormatComboBox = new StringFormat();
StrFormatComboBox.LineAlignment = StringAlignment.Center;
StrFormatComboBox.FormatFlags = StringFormatFlags.NoWrap;
StrFormatComboBox.Trimming = StringTrimming.EllipsisCharacter;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
ColumnLefts.Clear();
ColumnWidths.Clear();
ColumnTypes.Clear();
CellHeight = 0;
RowsPerPage = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// For various column types
CellButton = new Button();
CellCheckBox = new CheckBox();
CellComboBox = new ComboBox();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Calculating Total Widths
TotalWidth = 0;
foreach (DataGridViewColumn GridCol in dgv.Columns)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!GridCol.Visible) continue;
if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;
TotalWidth += GridCol.Width;
}
PageNo = 1;
NewPage = true;
RowPos = 0;
}
catch (Exception ex)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private static void PrintDoc_PrintPage(object sender,
System.Drawing.Printing.PrintPageEventArgs e)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
int tmpWidth, i;
int tmpTop = e.MarginBounds.Top;
int tmpLeft = e.MarginBounds.Left;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
try
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// Before starting first page, it saves Width & Height of Headers and CoulmnType
if (PageNo == 1)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
foreach (DataGridViewColumn GridCol in dgv.Columns)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!GridCol.Visible) continue;
// Skip if the current column not selected
if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText)) continue;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// 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;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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;
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Printing Current Page, Row by Row
while (RowPos <= dgv.Rows.Count - 1)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DataGridViewRow GridRow = dgv.Rows[RowPos];
if (GridRow.IsNewRow || (!PrintAllRows && !GridRow.Selected))
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
RowPos++;
continue;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
CellHeight = GridRow.Height;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (tmpTop + CellHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
DrawFooter(e, RowsPerPage);
NewPage = true;
PageNo++;
e.HasMorePages = true;
return;
}
else
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (NewPage)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
// 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);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
String s = DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString();
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Draw Columns
tmpTop = e.MarginBounds.Top;
i = 0;
foreach (DataGridViewColumn GridCol in dgv.Columns)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!GridCol.Visible) continue;
if (!PrintDGV.SelectedColumns.Contains(GridCol.HeaderText))
continue;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e.Graphics.FillRectangle(new SolidBrush(Color.LightGray),
new Rectangle((int) ColumnLefts[i], tmpTop,
(int)ColumnWidths[i], HeaderHeight));
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e.Graphics.DrawRectangle(Pens.Black,
new Rectangle((int) ColumnLefts[i], tmpTop,
(int)ColumnWidths[i], HeaderHeight));
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Draw Columns Contents
i = 0;
foreach (DataGridViewCell Cel in GridRow.Cells)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
if (!Cel.OwningColumn.Visible) continue;
if (!SelectedColumns.Contains(Cel.OwningColumn.HeaderText))
continue;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// For the TextBox Column
if (((Type) ColumnTypes[i]).Name == "DataGridViewTextBoxColumn" ||
((Type) ColumnTypes[i]).Name == "DataGridViewLinkColumn")
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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")
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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")
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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")
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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")
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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));
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Drawing Cells Borders
e.Graphics.DrawRectangle(Pens.Black, new Rectangle((int)ColumnLefts[i],
tmpTop, (int)ColumnWidths[i], CellHeight));
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
i++;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
}
tmpTop += CellHeight;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
RowPos++;
// For the first page it calculates Rows per Page
if (PageNo == 1) RowsPerPage++;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
if (RowsPerPage == 0) return;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Write Footer (Page Number)
DrawFooter(e, RowsPerPage);
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
e.HasMorePages = false;
}
catch (Exception ex)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
private static void DrawFooter(System.Drawing.Printing.PrintPageEventArgs e,
int RowsPerPage)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
double cnt = 0;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Detemining rows number to print
if (PrintAllRows)
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
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;
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
// Writing the Page Number on the Bottom of Page
string PageNum = " 第 " + PageNo.ToString()
+ " 页,共 " + Math.Ceiling((double)(cnt / RowsPerPage)).ToString()
+ " 页";
![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
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);
}
}
}
![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
示例工程下载:
testPrint