开源:MIS金质打印通原理及实现 Step by step (1)

本文介绍了MIS金质打印通的原理及实现方法。核心是实现二维数据打印和绘制线,通过组合网格可实现复杂报表、单据打印。提供多个默认常用对象,由MisGoldPrinter类管理。还给出C#和VB.Net代码示例,展示如何实现网格打印,后续将逐步结合程序实现打印。

开源:MIS金质打印通原理及实现 Step by step  (1)

原理篇


  前面我们说了打印页面设置、打印机设置、打印预览对话框的实现,这个通用的类大家可以自己修改一下用于自己的项目中。这个类也将用于我们即将讲解并已实现的MIS金质打印通中,让我们一起动手来实现自己的MIS打印程序吧!

  从现在开始,我们来一步一步的实现怎样打印管理信息系统(MIS)的报表、单据(如采购订单、订货单等)、合同(如工矿企业合同,格式非常复杂的合并网格,文本等)等等。

  很多打印程序,都是针对特定的网格控件如DataGrid打印,但是,为了通用,我们想想怎么办呢?

  实现的它们的核心,也就是实现二维数据的打印,加上绘制线,就组成了网格,多个网格就组成了报表、单据等。那么打印文本呢?哈哈,还是网格,只是一行一列,不用绘制网格线。也许有人要问,我的报表或单据合同之类的太复杂了,能实现吗?回答是肯定的,我们可以通过组合多个网格,合并网格的单元格进行实现。

  经过上面的分析,那我们就只要实现一个二维数据的打印和绘制直线或矩形线的两个类就可以实现任意的打印了。在以后的实现中,我们会看到一个IDraw接口,它至少包含一个void Draw()方法,我们要做的这两个核心类继承并实现Draw()。因此我有几个网格就实例化几个这样的对象,调用Draw()就OK了。

  在MIS金质打印通中提供了几个默认且常用的对象即Title、Caption、Top、Header、MultiHeader、Body、Footer、Bottom和MisGoldPrinter。大家一看就知道我为什么提供这几个对象,因为在打印报表或单据的时候基本都打印标题、子标题、网格头说明、网格的列标题我叫多层表头(一般中国人为了把表格搞的清晰,网格列标题好复杂,用几行多列并且有些合并单元来说明)、数据网格主体、主体网格注脚说明,Top与Bottom是在它们之上与之下的两个一行三列的对象。而将这些对象组织起来的就是MisGoldPrinter类,灵活的将这些对象管理起来,实现任意复杂的报表及票据等的打印。

  以上几个默认常用对象中,Top、Header、MultiHeader、Body、Footer、Bottom都是直接或间接继承于我们的核心类即绘制网格,Title、Caption虽然也可以用一行一列的网格来实现,但是我还是把它另外的实现了。Caption可以设置文本与字体,Title继承于Caption,因为Title还要画两个下划线。

  如果要套打(例如网格只打印单元格的文本,网格线不要绘制),在MisGoldPrinter中添加是否套打属性,也可以将套打属性分设在各个对象中,经过判断是否打印标题、多层表头、网格线等,或者用Excel作格式、分析、统计,我们只需将需要打印的数Excel就可以了。

  我们设计的思想是:简单快捷,易用实用

  例如,我们在窗口上拖一个命令按钮,取名btnPrintEasy,双击后写下如下代码即可以实现网格的打印:

C#:
private void btnPrintEasy_Click(object sender, System.EventArgs e)
{
 MisGoldPrinter webmis = new MisGoldPrinter();   //打印组件
 webmis.Title = "MIS金质打印通/nWWW.WebMIS.COM.CN";  //网格标题   
 webmis.DataSource = this.dataGrid1;    //DataGrid作为数据源,或者是任意二维的数组   
 webmis.Preview();      //打印预览
}

VB.Net:
Private Sub btnPrintEasy_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintEasy.Click
        Dim webmis As MisGoldPrinter      '打印组件
        webmis = New MisGoldPrinter
        webmis.Title = "MIS金质打印通"+vbCrLf+"WWW.WebMIS.COM.CN"  '网格标题
        webmis.DataSource = Me.DataGrid1              'DataGrid作为数据源
        webmis.Preview()                             '打印预览
End Sub

  当然,不要忘记了下面的代码,我们要为DataGrid写些测试数据哟。做法是双击窗口空白处,为窗口Form1_Load事件调用,如下:
C#:

private void Form1_Load(object sender, System.EventArgs e)
{
 this.dataGrid1.DataSource = this.GetDataSource();
}

private DataTable GetDataSource()
{
 DataTable dt=new DataTable();

 int rows = 50;
 int cols = 6;

 //增加行
 for (int intRowIndex=0;intRowIndex<rows;intRowIndex++)
 {
  dt.Rows.Add(dt.NewRow());    
 }
 //增加新列
 for (int intColIndex=0;intColIndex<cols;intColIndex++)
 {
  //dt.Columns.Add(intColIndex.ToString());
  dt.Columns.Add();
  //填写默认值为空串(.NET  TextColumn默认为"空")
  dt.Columns[intColIndex].DefaultValue="";
 }

 int i,j;
 for(i=0 ;i< rows ; i++)
 {
  for(j=0 ;j< cols-3 ; j++)
  {
   dt.Rows[i][j] = (i + 1).ToString() + "行" + (j + 1).ToString() + "列";     
   dt.Rows[i][cols-3] = (j + 1).ToString() + "." + (i + 1).ToString();
   dt.Rows[i][cols-2] = (i + 1).ToString();
  }       
  dt.Rows[i][cols-1] = (double.Parse(dt.Rows[i][cols-2].ToString()) * double.Parse(dt.Rows[i][cols-3].ToString())).ToString();
 } 

 return dt;
}

VB.Net:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.DataGrid1.DataSource = Me.GetDataSource()
    End Sub

    Private Function GetDataSource() As System.Data.DataTable
        Dim dt As New System.Data.DataTable
        Dim rows, cols As Int32
        rows = 50
        cols = 6

        Dim i, j As Int32
        i = 0
        While (i < rows)
            dt.Rows.Add(dt.NewRow())
            i += 1
        End While

        i = 0
        While (i < cols)
            dt.Columns.Add()
            i += 1
        End While

        For i = 0 To rows - 1
            For j = 0 To cols - 1
                dt.Rows(i)(j) = (i + 1).ToString() + "行" + (j + 1).ToString() + "列"
                dt.Rows(i)(cols - 3) = (j + 1).ToString() + "." + (i + 1).ToString()
                dt.Rows(i)(cols - 2) = (i + 1).ToString()
            Next
            dt.Rows(i)(cols - 1) = (Double.Parse(dt.Rows(i)(cols - 2).ToString()) * Double.Parse(dt.Rows(i)(cols - 3).ToString())).ToString()
        Next

        Return dt
    End Function


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.DataGrid1.DataSource = Me.GetDataSource()
    End Sub

  怎么样?确实不复杂吧?如果我们还想改变标题 Title的字体等,我们都可以很轻松的做到。我们还可以设置子(副)标题、网格的标题、页眉、页脚、网格附加的表头表底的说明。总之,无需您做很多的事情,都可以轻松搞定打印。

  我们将在后续的文章中以Step by step的方式,一步一步的结合具体的程序实现打印,等你看完之后,你会觉得:打印,管理信息系统永恒的话题,而我,可以自己实现了。


声明:本文版权为周方勇[长江支流]所有,如需转载,请保留完整的内容及出处。
flygoldfish@sina.com

姓 名: 周方勇 网 名: 长江支流/咏方舟 Email: flygoldfish@sina.com.cn Blog: http://blog.csdn.net/flygoldfish 2004年04月18日 1、在网友的热心支持下免费提供空间域名 www.webmis.com.cn 2004年04月07日 发布不带.dll的源码供交流 2005年01月24日 1、提供VB.NET及C#的使用示例工程 2、发布V2.2测试版 2005年01月22日 将打印示例程序按功能(简单打印、完整示例、Excel打印)分在不同的窗口 2005年0114日 发布《MIS金质打印》 V2.1测试版 2004年0113日 1、将MisPrinter类改为MisGoldPrinter,以促进品牌效应。 2、在MisGoldPrinter类中再增加一个带参构造函数,以便直接默认横向打印/预览 3、增加DocumentName属性,以便在打印/预览时在窗口标题栏中显示指定的名称 2004年01月07日 调整打印程序内部结构,为使发出去的后期源程序版本一致,待近期调整完结构之后公布源码! 这就是继V1.1之后没有发源代码的原因。 ____________________________________________________ 2004年7月 完成了整体的框架、涉及打印的几个对话框、核心打印程序及几个基本打印对象并由BillPrinter类将其组织起来,程序基本定型。 本程序为打印程序,单据、会计凭证、发票清单、报表、任意复杂表格、合并表格如工矿企业合同都可以由系统提供的几个默 认打印对象组合打印DataGrid、DataTable、MSHFlexGrid等二维形式全部可以打印。 部分对象如PrinterMargins、Sewing、GridLineFlag、GridMergeFlag等提供图例,以促进理解。 后期版本将提供XML描述、SQL数据源的打印,并用管理器管理任意多个网格、文本对象、图象等,用户可以随意定义。 2004年8月初 为一些类或程序写上注释,如下: /// 程序提供:周方勇;Email:flygoldfish@sina.com。 /// 请 关 注:WebMIS.Net快速开发工具,不写一行程序开发B/S架构下MIS、OA、CRM、人事管理、档案管理等数据库网页系统。简单、实用、稳定、可靠。 /// 下 载: /// 上海奥联:WWW.AlinkSoft.COM /// 用友华表:WWW.CellSoft.CC ///★★★★★您可以免费使用此程序,但是请您保留此说明,以维护知识产权★★★★★ 2004年08月07日 1、将框架作了部分调整,并且将打印基本对象的基类Printer作了调整。 由于打印对象的定位及打印区域受PrintDocument、Sewing影响,为了方便Printer的子类不必在每次实例化后设置这 两个对象,故将PrintDocument、Sewing放在一个类中作为全局静态变量,现删除这两个全局静态变量, 改在Printer 的构造函数中,为每个子类提供一个默认的PrintDocument、Sewing实例对象。 2、为GridBase扩充了几个属性与方法,由于字段太多,每次增加或修改字段后要去构造函数中去修改他们的初始化, 太麻烦了,所以将它们的初始化直接放在定义处,并把相应的属性及相关方法直接放在字段后,并用#region指令将 它们折叠起来,便于维护。 3、增加了ReDimArrString(string[,] arrStr,int rows,int cols),即重定义二维字符数组,因为网格的行列数可能要改 变,但不能因为它们改变了而丢失原有的数据,因此写此程序保留新定义的行列,但保留原有行列数相交的部分数据。 4、应用设计模式原理重新组织IPrinterPageSetting、PrinterPageSetting、WinPrinterPageSetting、WebPrinterPageSetting。 WebPrinterPageSetting待进一步完善。 2004年08月08日 1、将以往程序优化 2、将DrawGrid类中DrawGridLine(...)、DrawGridText(...)、DrawGridBorder(...)参数最全的核心函数改为protected,提供public的 无参方法供实例化对象调用; 由于在指定的区域内可能绘制不完网格,因此上面的几个函数可能会将返回类型void改为一个描述绘制结果的对象; SetText(int row,int col,string text)、SetText(int row,int col)将在后期版本中提供.Row[index].Text的属性; TransGrid()、ResetTransGrid()是在设计时为了能做任意的缩放的变换提供的,待进一步完善。 3、对Printer类中的ReSetVariableVal()、GetPrinterMargins()进行修改,以适应对纸张进行调整特别是横向、竖向打印的支持。 2004年08月09日 1、解决分页问题,主要是有些对象每页都重复打印,使得条件复杂。 2004年08月10日 113:42将源程序传给资深程序员李峰; 2、计划增加每页小计。 2004年08月111、为网格增加画对角线的功能,以满足中国人表格的特点; 2、将Graphics、PrintDocument、Sewing、RectangleF、Height、Draw()重新组织在IDraw里,并在 BillPrinter中增加private void OutObject(IDraw outer),使每个对象输出时调用此方法,提高代码重用率; 2004年08月14日 1、忘了,反正又把程序看了看,修修补补做了些调整。 2004年08月15日 1、将分页又重新简化了一下,主要是打印Body上用了数据行指针; 2004年08月16日 1、发布V1.0源码版,程序名称为MIS金质打印王。 2、在优快云上发布贴子: .^^.开源:C#.NET开发的MIS打印程序,各种网格DataGrid打印、DataTable、HtmlTable等二维形式全搞定,源码免费下载 http://community.csdn.net/Expert/topic/3278/3278050.xml?temp=.5012934 2004年08月17日 1、在优快云上发布文章: 开源:.NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现 http://blog.csdn.net/flygoldfish/archive/2004/08/17/77208.aspx 2、应广大网友来信要求,计划将PrinterPageSetting目录开源到演示程序,以后逐一以文章的形式全部开放。 2004年08月18日 1、中国共享软件网收录 MIS金质打印王 V1.0源码版 http://www.shareware.cn/pub/2319.html 2、将PrinterPageSetting目录即(页面设置、打印机设置、打印预览)源码加入演示程序。 3、在MisGoldPrinter中添加属性,DataSource,这样,仅需几句话就可以打印了,如: MisGoldPrinter webmis = new MisGoldPrinter(); //申明并实例化打印组件 webmis.Title = "WebMIS.Net快速开发工具\nWWW.AlinkSoft.COM"; //网格标题 webmis.DataSource = this.dataGrid1; //DataGrid作为数据源 webmis.Preview(); //打印预览 注意:将将MisGoldPrinter中的Draw(Graphics g)打印各个对象时加一下 printerobject != null的判断,如 if (mCurrentPageIndex == 1 || _caption.IsDrawAllPage)... 改为 if (_caption != null && (mCurrentPageIndex == 1 || _caption.IsDrawAllPage))... 否则可能会出错。 4、将3的应用加到了frmPrint.cs ,做一个简单的打印。 2004年08月19日 1、将PrinterPageSetting目录即(页面设置、打印机设置、打印预览)源码加入演示程序。 2、发布V1.1源码版,程序名称为MIS金质打印王。 2004年09月03日 1、由于在优快云上发表文档".NET环境下有关打印页面设置、打印机设置、打印预览对话框的实现", 因此将PrinterPageSetting封装成一个.dll,分别用C#与VB.net写了使用示例工程程序 2、在IPrinterPageSetting.cs增加event PrintPageDelegate PrintPage,并将原PrintPage改为PrintPageValue /// C#调用: /// PrinterPageSetting1.PrintPageValue = new PrintPageDelegate(this.PrintPageEventHandler); ///或 PrinterPageSetting1.PrintPage += new PrintPageDelegate(this.PrintPageEventHandler); /// VB调用: /// Me.printerPageSetting.PrintPageValue = New GoldPrinter.PrintPageDelegate(AddressOf printDocument_PrintPage) 3、增加了DrawText类,用以打印文档(其实可以用一行一列的DrawGrid打印) 4、PrinterPageSetting的readme.txt如下: ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 声明: 1、版权归周方勇所有,如需传播,请保留完整的内容及此声明,以维护知识产权! 2、您可以使用本程序中的任何部分作为学习或商业用途,但是需要保留相关程序的注释。 3、最新版本下载:http://www.alinksoft.com 4、免费源码 5、本人不承担任何责任。 周方勇;Email:flygoldfish@sina.com。 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ 本程序带C#与VB.net版本使用方式,用VS.net打开PrinterPageSetting.sln, 在您喜欢的语言项目上单击鼠标右键,在弹出的菜单中选择"设为启动项目",然后运行。 5、准备独立发布PrinterPageSetting 2004年09月04日 重大喜讯:收到中国共享软件注册中心2004年09月03日的邮件。部分内容如下: 软件名称:MISGoldPrinter免费C#.NET源码版(5块钱给softreg吧) 注册价格:5元/套 您的软件在本站的编号是: /535AC7A1-9985-4314-A52C-978BB9C0BB29/ 软件注册页绝对链接: http://www.softreg.com.cn/shareware_view.asp?id=/535AC7A1-9985-4314-A52C-978BB9C0BB29/ 快捷链接: http://www.softreg.com.cn/shareware.asp?id=17260 2004年10月...日 改变PrintDocument的DefaultPageSettings就会改变PrinterMargins。由于是打印基类,继承者博多,因此 每次实例化时都会计算PrinterMargins会影响效率,这就是前些版本速度慢的原因。改为手动调用CalculatePageInfo()或改变 PrintDocument后在调用处重新计算一个PrinterMargins保存起来,因此增加PrinterSingleton, 使系统只有同一个PrintDocument及PrinterMargins,这样速度大大改观。 开发Excel打印功能 2004年11月20日 开发Excel打印功能完成,能够生成Excel文件、Excel打印预览Excel操作。 自定制模板打印,非常灵活。完成各种打印、套打、报表、图表分析。 2004年11月23日 发布MIS金质打印王 V2.0测试版。如需要源码,下载V1.1即可。 V2.0源码版在预计在12月上旬推出。 2004年11月27日 改正预览时显示正确,在预览窗口单击打印打印不出Body的错误。 其实只要在PrintPageEventHandler()中打印预览重置当前页及当前行 this.mCurrentPageIndex = 1; this.mCurrentRowIndex = 0; 2004年12月...1、调整打印程序内部结构,公开部分程序基本没动,只作相应的错误更正及加几个属性。 2、PrinterBase不再包含装订线Sewing,打印对象的定位及打印区域只受PrintDocument的影响, 3、由于使用PrinterSingleton使系统只有同一个PrintDocument及PrinterMargins,因此在同一系统 两个地方使用时出现了打印一样的效果,如A处有header而B处没有,先打A再打B,结果B中也有header了, 于是在PrinterSingleton增加Reset()方法以使PrintDocument及PrinterMargins为null,在MisPrinter 构造函数中首先调用Reset()
更多商业源程序:www.bzcode.net 本程序为打印程序,单据、会计凭证、发票清单、报表、任意复杂表格、合并表格如工矿企业合同都可以由系统提供的几个默认打印对象组合打印DataGrid、DataTable、ListView、MSHFlexGrid等二维形式或二维数组全部可以打印。源码二次开发,打天下报表。 后期版本将陆续提供XML描述、SQL数据源的打印,并用管理器管理任意多个网格、文本对象、图象等,用户可以随意定义。 主要功能: 打印预览,可以调整打印页面设置、打印机设置、显示打印预览对话框 主标题、副标题、页顶、网格头、多层表头(网格标题)、网格主体(明细)、网格底、页底等打印对象 可以指定每个对象是否每页重复打印 超宽自动压缩,可以调整列宽、行高、合并方式 分组合并报表,合并方式还可以选择任意合并、按行、按列合并等 可以调整套打 可以每页都显示当前页小计 可以为每页指定打印行数,默认自适应 可以打印装订线,分左装订上装订,随意选择 打印有效区域矩阵,以在开发中参照 可以指定打印边框,分单边框,加粗单边框、双边框、加粗双边框等等 分页处理、可编程分栏处理 背景颜色、图片 能够生成Excel文件、Excel打印预览Excel操作。 自定制模板打印,非常灵活。完成各种打印、套打、报表、图表分析。
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值