Afrasiab Cheraghi著于codeproject.com
原代碼地址:http://www.codeproject.com/KB/grid/PrintDataGridView.aspx
简介
有的时候使用者需要打印特定的列或行(或者全部)在一个DataGridView。有些例子可以是作为如下:
1)在DataGridView中有很多行并且这里不需要全部打印。
2)列的宽度和可能比纸的要大,当打印的时候最好是去掉一列或更多。
因此一个名叫PrintDGV的类被执行,并且可以在任何.NET2.0的应用程序中使用。我已经做好了DataGrid 和DataGridView,用C#和VB.NET
描述
代码主要的部分是PrintDGV 类和PrintOptions组成。
在PrintDGV,我们有:
1)SelectedColumns 和 AvailableColumns保存列名
2)PrintDocument对象指定PrintDoc(BeginPrint 和 PrintPage事件操作者 )
3)四个函数
Print_DataGridView: 主函数可以在类的外面使用。
PrintDoc_BeginPrint: 初始化变量来开始打印。
PrintDoc_PrintPage: 执行打印工作
DrawFooter: 打出纸的号码。
代码有以下特点
1)支持TextBox, Link, Button, ComboBox, CheckBox, and Image 列.
2)绘制合适的列宽来符合纸的宽度,或者绘制他们指定的大小。
3)如果单元格宽度小于文本那么它将隐藏单元格文本。
4)在纸上显示页脚,日期,时间和标题。
使用代码
在应用程序中使用代码。PrintDGV 类和PrintOptions必须被添加,并且Print_DataGridView函数被调用。在我们的例子中,有一个MainForm.
在MainForm中,DataGridView填充了'Persongs.mdb'的‘Persons’表。
在PrintOption中DataGridView列,合适的页,和使用者可以选择标题。
PrintDoc_PrintPage 事件处理者做如下工作:
1)计算列宽度
2)打印单前页。
3)在'Print Selected Rows' 模式中,如果当前的排没有选择,那么就不打印那排。
4)如果它到达结尾的页,则写页数并且去下页。 如果它不到达结尾的页然后:
5)如果它在新的页,则绘制标题、日期-时间、页眉和列(检查是佛没一列都被选中如果没有就丢弃它)
6)绘制边界
7)第一页的每一排数据
8)打出页脚和页数
System.Drawing.Printing.PrintPageEventArgs e)
... {
int tmpWidth, i;
int tmpTop = e.MarginBounds.Top;
int tmpLeft = e.MarginBounds.Left;
int HeaderHeight=0;
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 the 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 Print Title
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();
// Draw Time and Date
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 Headers
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);
}
}