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

namespace WinAppPrint
{
    /// <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;
        }
    }
}

C#打印类的更多相关文章

  1. [asp.net]c# winform打印类

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

  2. -XX:-PrintClassHistogram 按下Ctrl+Break后,打印类的信息

    -XX:+PrintClassHistogram –按下Ctrl+Break后,打印类的信息: num     #instances         #bytes  class name ------ ...

  3. python 以单例模式封装logging相关api实现日志打印类

    python 以单例模式封装logging相关api实现日志打印类   by:授客QQ:1033553122 测试环境: Python版本:Python 2.7   实现功能: 支持自由配置,如下lo ...

  4. __str__被print函数调用,目的是打印类的内容到屏幕上

    # -*- coding: utf-8 -*- #python 27 #xiaodeng #__str__被print函数调用,目的是打印类的内容到屏幕上 class APIError(): def ...

  5. C#Lpt端口打印类的操作浅析

    C#LPT端口打印类的操作是什么呢?首先让我们看看什么是LPT端口(打印机专用)?LPT端口是一种增强了的双向并行传输接口,在USB接口出现以前是扫描仪,打印机最常用的接口.最高传输速度为1.5Mbp ...

  6. Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的行数并保存日志文件

    Android日志打印类LogUtils,能够定位到类名,方法名以及出现错误的行数并保存日志文件 在开发中,我们常常用打印log的方式来调试我们的应用.在Java中我们常常使用方法System.out ...

  7. JAVA打印类(带预览)

    package tool; import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; ...

  8. python 打印类的属性、方法

    打印变量db的类(class):[root@fuel ~]# pythonPython 2.6.6 (r266:84292, Jan 22 2014, 09:42:36)[GCC 4.4.7 2012 ...

  9. ZPL条码打印类

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.I ...

随机推荐

  1. Laravel5.1 表单验证

    当我们提交表单时 通常会对提交过来的数据进行一些验证.Laravel在Controller类中使用了一个traint:ValidatesRequest.方便我们在控制器中使用验证器. 下面我们就来看一 ...

  2. javascript new Date()函数在不同浏览器上返回不同的值

    今天是2015年3月16日,在IE 6 上new Date()返回给后台server的字符串格式为 "Mon Mar 16  00:00:00 UTC 0800 2015",而在f ...

  3. DM8168 OpenCV尝试与评估(编译ARM版OpenCV)

     交叉编译opencv2.3.1,并在DM8168 cortex A8中执行图像处理. 开发环境: PC:ubuntu12.04LTS.Intel Core 2 Duo CPU  E7200@2. ...

  4. OOXML,XLSX分析

    07以上的xlsx是使用了OOXML和zip,将后缀修改为.zip,就可以看到文件,主要分析xl目录下的文件,如图: 主要数据文件在xl目录下面 styles.xml里面存放着excel的样式数据 很 ...

  5. sql语法:从一个表update到另外一个表

    sql语法:从一个表update到另外一个表 一. update a set a.name=b.name1 from a,b where a.id=b.id 二. update table1 set ...

  6. Android实现“退出确认”对话框

    @Override public void onBackPressed() { new AlertDialog.Builder(this).setTitle("确认退出吗?") . ...

  7. jpa单向多对一关联映射

    表结构 student class Class package auth.model; import javax.persistence.Column; import javax.persistenc ...

  8. Thymeleaf模板如何获取springMVC返回的model值

    Thymeleaf模板如何获取springMVC返回的model值 后台的实现: @RequestMapping("/hello") public String hello(Mod ...

  9. IDEA整合日志框架Log4j2+Slf4j详细配置过程

    日志框架这么多,他们之间到底是什么关系呢?笼统的讲就是slf4j是一系列的日志接口,而log4j2.logback是具体实现了接口功能的日志框架.现在的主流日志接口都使用slf4j,而日志的实现就见仁 ...

  10. JS中的call、apply、bind 用法解疑

    JS中的caller  arguments.callee  call  apply  bind方法 一.call()和apply()方法 1.方法定义 call方法: 语法:call([thisObj ...