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

来源:互联网 发布:jade2016 软件 编辑:程序博客网 时间:2024/05/01 06:17
 
  前面我们说了打印页面设置、打印机设置、打印预览对话框的实现,这个通用的类大家可以自己修改一下用于自己的项目中。这个类也将用于我们即将讲解并已实现的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的方式,一步一步的结合具体的程序实现打印,等你看完之后,你会觉得:打印,管理信息系统永恒的话题,而我,可以自己实现了。