/// <summary>
/// Purpose:继承PrintDocument,实现DataGrid的打印
/// Author: Dangmy
/// Date: 2007-03-09
/// Version: 1.0
/// </summary>
public class DataGridPrintDocument:System.Drawing.Printing.PrintDocument
{
private Font fontCaption = new Font("宋体",12,FontStyle.Bold); //表名字体
private Font fontText = new Font("宋体",9); //表内容字体
private int CellSpace = 2; //单元格与内容空隙
private SolidBrush brushText = new SolidBrush(Color.Black); //表格字体笔刷,指定为黑色
private SolidBrush brushLine = new SolidBrush(Color.Gray); //表格线条笔刷,指定为灰色
private SolidBrush brushHead = new SolidBrush(Color.LightGray); //表头背景笔刷,指定为浅灰色
private SolidBrush brushCell = new SolidBrush(Color.White); //表格背景笔刷,指定为白色
private DataGrid dataGrid; //打印DataGrid
private DataTable dataTable; //打印DataGrid数据表
private int PageIndex; //当前打印的页号
private int LineCount; //每页总共打印行数
private int ColCount; //总共打印的列数
private int ColIndex; //当前打印的列下标
private int ColLastIndex; //上一页打印的列下标
private int HeaderIndex; //当前打印的表头下标
private int RecordCount; //总共打印的记录数
private int RecordIndex; //当前打印记录下标
private int RecordLastIndex; //上一页打印的记录下标
private float x; //打印X坐标
private float y; //打印Y坐标
private bool IsPrintColHeader = false; //是否每页打印表头
private bool IsNewPageByCol = false; //是否换页打印剩余列
private bool IsNewPageByRow = false; //是否换页打印剩余行
private bool IsPreviewed = false; //是否已生成预览,如果已生成预览,再预览窗口点击打印时,弹出打印机对话框
private void InitializeComponent()
{
}
//构造函数
public DataGridPrintDocument(DataGrid printDataGrid)
{
dataGrid = printDataGrid;
dataTable = (DataTable)printDataGrid.DataSource;
}
//初始化全局变量
private void InitVar()
{
if(dataTable == null)
return;
RecordCount = dataTable.Rows.Count;
ColCount = dataTable.Columns.Count;
PageIndex = 1;
ColIndex = 0;
ColLastIndex = 0;
HeaderIndex = 0;
RecordIndex = 0;
RecordLastIndex = 0;
}
protected override void OnBeginPrint(PrintEventArgs e)
{
base.OnBeginPrint (e);
if(IsPreviewed)
{
PrintDialog dlgPrint = new PrintDialog();
dlgPrint.Document = this;
if(dlgPrint.ShowDialog() != DialogResult.OK)
e.Cancel = true;
}
InitVar();
}
//PrintDocumen事件重写
protected override void OnPrintPage(PrintPageEventArgs e)
{
base.OnPrintPage (e);
if(dataTable == null)
return;
//计算每页打印行数
if(DefaultPageSettings.Landscape)
{
LineCount = (DefaultPageSettings.PaperSize.Width -
DefaultPageSettings.Margins.Left -
DefaultPageSettings.Margins.Right -
(int)fontCaption.GetHeight(e.Graphics))/
((int)fontText.GetHeight(e.Graphics) + CellSpace + CellSpace);
}
else
{
LineCount = (DefaultPageSettings.PaperSize.Height -
DefaultPageSettings.Margins.Top -
DefaultPageSettings.Margins.Bottom -
(int)fontCaption.GetHeight(e.Graphics))/
((int)fontText.GetHeight(e.Graphics) + CellSpace + CellSpace);
}
//如果是第一行,则打印表名
if(PageIndex == 1 && ColIndex == 0)
DrawCaption(e.Graphics);
//重置行下标、列下标
if(IsNewPageByCol)
{
RecordIndex = RecordLastIndex;
ColIndex = ColLastIndex;
}
if(IsNewPageByRow)
{
RecordLastIndex = RecordIndex;
ColLastIndex = 0;
}
y = this.DefaultPageSettings.Margins.Top;
//如果是第一页或者每页都打印表头,则打印表头
if(RecordIndex == 0 || IsPrintColHeader)
DrawColHeader(e.Graphics);
//循环打印数据行
int cnt = 0;
for( ; RecordIndex<RecordCount; RecordIndex++)
{
if( cnt++ == LineCount)
{
if(!IsNewPageByCol)
IsNewPageByRow = true;
break;
}
if( RecordIndex == RecordCount-1)
{
IsNewPageByRow = false;
}
DrawRow(e.Graphics,RecordIndex);
}
ColLastIndex = ColIndex;
//换页
if(IsNewPageByRow || IsNewPageByCol)
{
PageIndex++;
e.HasMorePages = true;
}
IsPreviewed = true;
}
//打印报表名称
private void DrawCaption(Graphics g)
{
x = this.DefaultPageSettings.Margins.Left;
y = this.DefaultPageSettings.Margins.Top + fontCaption.GetHeight(g);
g.DrawString(dataGrid.CaptionText,fontCaption,brushText,x,y);
}
//打印表头
private void DrawColHeader(Graphics g)
{
x = this.DefaultPageSettings.Margins.Left + CellSpace;
y += fontCaption.GetHeight(g) + fontText.GetHeight(g) + CellSpace*3;
Pen penLine = new Pen(brushLine);
if(!IsNewPageByCol)
HeaderIndex = 0;
for( ; HeaderIndex<ColCount; HeaderIndex++ )
{
//超出页宽,停止打印
if(DefaultPageSettings.Landscape)//横向打印
{
if(x > DefaultPageSettings.PaperSize.Height - DefaultPageSettings.Margins.Top - DefaultPageSettings.Margins.Bottom)
break;
}
else//纵向打印
{
if(x > DefaultPageSettings.PaperSize.Width - DefaultPageSettings.Margins.Left - DefaultPageSettings.Margins.Right)
break;
}
g.FillRectangle(brushHead,x,y,dataGrid.TableStyles[0].GridColumnStyles[HeaderIndex].Width + CellSpace*2,fontText.GetHeight(g) + CellSpace*2);
g.DrawRectangle(penLine,x,y,dataGrid.TableStyles[0].GridColumnStyles[HeaderIndex].Width + CellSpace*2,fontText.GetHeight(g) + CellSpace*2);
g.DrawString(dataTable.Columns[HeaderIndex].ToString(), fontText, brushText, x+CellSpace,y+CellSpace);
x += dataGrid.TableStyles[0].GridColumnStyles[HeaderIndex].Width + CellSpace;
}
}
//打印一行
private void DrawRow(Graphics g,int index)
{
x = this.DefaultPageSettings.Margins.Left + CellSpace;
y += fontText.GetHeight(g) + CellSpace;
Pen penLine = new Pen(brushLine);
for(ColIndex = ColLastIndex; ColIndex<ColCount; ColIndex++ )
{
//超出页宽,停止打印
if(DefaultPageSettings.Landscape)//横向打印
{
if(x > DefaultPageSettings.PaperSize.Height - DefaultPageSettings.Margins.Top - DefaultPageSettings.Margins.Bottom)
{
IsNewPageByCol = true;
IsNewPageByRow = false;
break;
}
}
else//纵向打印
{
if( x > DefaultPageSettings.PaperSize.Width - DefaultPageSettings.Margins.Left - DefaultPageSettings.Margins.Right)
{
IsNewPageByCol = true;
IsNewPageByRow = false;
break;
}
}
g.FillRectangle(brushCell,x,y,dataGrid.TableStyles[0].GridColumnStyles[ColIndex].Width + CellSpace*2,fontText.GetHeight(g) + CellSpace*2);
g.DrawRectangle(penLine,x,y,dataGrid.TableStyles[0].GridColumnStyles[ColIndex].Width + CellSpace*2,fontText.GetHeight(g) + CellSpace*2);
g.DrawString(dataTable.Rows[index][ColIndex].ToString(), fontText, brushText, x + CellSpace,y + CellSpace);
x += dataGrid.TableStyles[0].GridColumnStyles[ColIndex].Width + CellSpace;
}
if(ColIndex == ColCount)
IsNewPageByCol = false;
}
}
//打印预览调用
private void btnPrint_Click(object sender, System.EventArgs e)
{
DataGridPrintDocument printDocument = new DataGridPrintDocument(dataGrid1);
//页面设置
PageSetupDialog dlgPage = new PageSetupDialog();
dlgPage.Document = printDocument;
dlgPage.ShowDialog();
//预览
PrintPreviewDialog dlgPreview = new PrintPreviewDialog();
dlgPreview.Document = printDocument;
dlgPreview.ShowDialog();
}