c#winform打印类

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Printing;
using System.Drawing;

namespace Common
{
    
/// <summary>
    
/// 
    
/// </summary>
    public class Printer
    {
        
private DataGridView dataview;
        
private PrintDocument printDoc;
        
//打印有效区域的宽度
        int width;
        
int height;
        
int columns;
        
double Rate;
        
bool hasMorePage = false;
        
int currRow = 0;
        
int rowHeight = 20;
        
//打印页数
        int PageNumber;
        
//当前打印页的行数
        int pageSize = 20;
        
//当前打印的页码
        int PageIndex;

        
private int PageWidth; //打印纸的宽度
        private int PageHeight; //打印纸的高度
        private int LeftMargin; //有效打印区距离打印纸的左边大小
        private int TopMargin;//有效打印区距离打印纸的上面大小
        private int RightMargin;//有效打印区距离打印纸的右边大小
        private int BottomMargin;//有效打印区距离打印纸的下边大小

        
int rows;

        
/// <summary>
        
/// 构造函数
        
/// </summary>
        
/// <param name="dataview">要打印的DateGridView</param>
        
/// <param name="printDoc">PrintDocument用于获取打印机的设置</param>
        public Printer(DataGridView dataview, PrintDocument printDoc)
        {
            
this.dataview = dataview;
            
this.printDoc = printDoc;
            PageIndex 
= 0;
            
//获取打印数据的具体行数
            this.rows = dataview.RowCount;

            
this.columns = dataview.ColumnCount;
            
//判断打印设置是否是横向打印
            if (!printDoc.DefaultPageSettings.Landscape)
            {

                PageWidth 
= printDoc.DefaultPageSettings.PaperSize.Width;
                PageHeight 
= printDoc.DefaultPageSettings.PaperSize.Height;

            }
            
else
            {

                PageHeight 
= printDoc.DefaultPageSettings.PaperSize.Width;
                PageWidth 
= printDoc.DefaultPageSettings.PaperSize.Height;

            }
            LeftMargin 
= printDoc.DefaultPageSettings.Margins.Left;
            TopMargin 
= printDoc.DefaultPageSettings.Margins.Top;
            RightMargin 
= printDoc.DefaultPageSettings.Margins.Right;
            BottomMargin 
= printDoc.DefaultPageSettings.Margins.Bottom;


            height 
= PageHeight - TopMargin - BottomMargin - 2;
            width 
= PageWidth - LeftMargin - RightMargin - 2;

            
double tempheight = height;
            
double temprowHeight = rowHeight;
            
while (true)
            {
                
string temp = Convert.ToString(tempheight / Math.Round(temprowHeight, 3));
                
int i = temp.IndexOf('.');
                
double tt = 100;
                
if (i != -1)
                {
                    tt 
= Math.Round(Convert.ToDouble(temp.Substring(temp.IndexOf('.'))), 3);
                }
                
if (tt <= 0.01)
                {
                    rowHeight 
= Convert.ToInt32(temprowHeight);
                    
break;
                }
                
else
                {
                    temprowHeight 
= temprowHeight + 0.01;

                }
            }
            pageSize 
= height / rowHeight;
            
if ((rows + 1<= pageSize)
            {
                pageSize 
= rows + 1;
                PageNumber 
= 1;
            }
            
else
            {
                PageNumber 
= rows / (pageSize - 1);
                
if (rows % (pageSize - 1!= 0)
                {
                    PageNumber 
= PageNumber + 1;
                }

            }


        }


        
/// <summary>
        
/// 初始化打印
        
/// </summary>
        private void InitPrint()
        {
            PageIndex 
= PageIndex + 1;
            
if (PageIndex == PageNumber)
            {
                hasMorePage 
= false;
                
if (PageIndex != 1)
                {
                    pageSize 
= rows % (pageSize - 1+ 1;
                }
            }
            
else
            {
                hasMorePage 
= true;
            }


        }
        
//打印头
        private void DrawHeader(Graphics g)
        {

            Font font 
= new Font("宋体"12, FontStyle.Bold);
            
int temptop = (rowHeight / 2+ TopMargin + 1;
            
int templeft = LeftMargin + 1;

            
for (int i = 0; i < this.columns; i++)
            {
                
string headString = this.dataview.Columns[i].HeaderText;
                
float fontHeight = g.MeasureString(headString, font).Height;
                
float fontwidth = g.MeasureString(headString, font).Width;
                
float temp = temptop - (fontHeight) / 3;
                g.DrawString(headString, font, Brushes.Black, 
new PointF(templeft, temp));
                templeft 
= templeft + (int)(this.dataview.Columns[i].Width / Rate) + 1;
            }

        }
        
//画表格
        private void DrawTable(Graphics g)
        {

            Rectangle border 
= new Rectangle(LeftMargin, TopMargin, width, (pageSize) * rowHeight);
            g.DrawRectangle(
new Pen(Brushes.Black, 2), border);
            
for (int i = 1; i < pageSize; i++)
            {
                
if (i != 1)
                {
                    g.DrawLine(
new Pen(Brushes.Black, 1), new Point(LeftMargin + 1, (rowHeight * i) + TopMargin + 1), new Point(width + LeftMargin, (rowHeight * i) + TopMargin + 1));
                }
                
else
                {
                    g.DrawLine(
new Pen(Brushes.Black, 2), new Point(LeftMargin + 1, (rowHeight * i) + TopMargin + 1), new Point(width + LeftMargin, (rowHeight * i) + TopMargin + 1));
                }
            }

            
//计算出列的总宽度和打印纸比率
            Rate = Convert.ToDouble(GetDateViewWidth()) / Convert.ToDouble(width);
            
int tempLeft = LeftMargin + 1;
            
int endY = (pageSize) * rowHeight + TopMargin;
            
for (int i = 1; i < columns; i++)
            {
                tempLeft 
= tempLeft + 1 + (int)(this.dataview.Columns[i - 1].Width / Rate);
                g.DrawLine(
new Pen(Brushes.Black, 1), new Point(tempLeft, TopMargin), new Point(tempLeft, endY));
            }

        }
        
/**/
        
/// <summary>
        
/// 获取打印的列的总宽度
        
/// </summary>
        
/// <returns></returns>
        private int GetDateViewWidth()
        {
            
int total = 0;
            
for (int i = 0; i < this.columns; i++)
            {
                total 
= total + this.dataview.Columns[i].Width;
            }
            
return total;
        }

        
//打印行数据
        private void DrawRows(Graphics g)
        {

            Font font 
= new Font("宋体"12, FontStyle.Regular);
            
int temptop = (rowHeight / 2+ TopMargin + 1 + rowHeight;


            
for (int i = currRow; i < pageSize + currRow - 1; i++)
            {
                
int templeft = LeftMargin + 1;
                
for (int j = 0; j < columns; j++)
                {
                    
string headString = this.dataview.Rows[i].Cells[j].Value.ToString();
                    
float fontHeight = g.MeasureString(headString, font).Height;
                    
float fontwidth = g.MeasureString(headString, font).Width;
                    
float temp = temptop - (fontHeight) / 3;
                    
while (true)
                    {
                        
if (fontwidth <= (int)(this.dataview.Columns[j].Width / Rate))
                        {
                            
break;
                        }
                        
else
                        {
                            headString 
= headString.Substring(0, headString.Length - 1);
                            fontwidth 
= g.MeasureString(headString, font).Width;
                        }
                    }
                    g.DrawString(headString, font, Brushes.Black, 
new PointF(templeft, temp));

                    templeft 
= templeft + (int)(this.dataview.Columns[j].Width / Rate) + 1;
                }

                temptop 
= temptop + rowHeight;


            }
            currRow 
= pageSize + currRow - 1;

        }

        
/// <summary>
        
/// 在PrintDocument中的PrintPage方法中调用
        
/// </summary>
        
/// <param name="g">传入PrintPage中PrintPageEventArgs中的Graphics</param>
        
/// <returns>是否还有打印页 有返回true,无则返回false</returns>
        public bool Print(Graphics g)
        {
            InitPrint();
            DrawTable(g);
            DrawHeader(g);
            DrawRows(g);

            
//打印页码
            string pagestr = PageIndex + " / " + PageNumber;
            Font font 
= new Font("宋体"12, FontStyle.Regular);
            g.DrawString(pagestr, font, Brushes.Black, 
new PointF((PageWidth / 2- g.MeasureString(pagestr, font).Width, PageHeight - (BottomMargin / 2- g.MeasureString(pagestr, font).Height));
            
//打印查询的功能项名称
            string temp = dataview.Tag.ToString() + " " + DateTime.Now.ToString("yyyy-MM-dd HH:mm");
            g.DrawString(temp, font, Brushes.Black, 
new PointF(PageWidth - 5 - g.MeasureString(temp, font).Width, PageHeight - 5 - g.MeasureString(temp, font).Height));
            
return hasMorePage;
        }

    }
}

 

posted @ 2010-12-15 09:31  自由精灵  阅读(612)  评论(0编辑  收藏  举报