datagrid的一个简单的通用打印程序

来源:互联网 发布:windows ad域的搭建 编辑:程序博客网 时间:2024/06/05 16:27

经过两天的学习,终于写出来了,通用的datagrid打印程序,但是有一个要求,必须要有datagrid的格式设置,源代码如下:

Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
Public Class DataGridPrint
    Inherits System.Drawing.Printing.PrintDocument

#Region " 组件设计器生成的代码 "

    Public Sub New()
        MyBase.New()

        ' 该调用是组件设计器所必需的。
        InitializeComponent()

        '在 InitializeComponent() 调用之后添加任何初始化

    End Sub

    'Control 重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    '控件设计器所必需的
    Private components As System.ComponentModel.IContainer

    '注意: 以下过程是组件设计器所必需的
    ' 可以使用组件设计器修改此过程。不要使用
    ' 代码编辑器修改它。
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        components = New System.ComponentModel.Container
    End Sub

#End Region
    Dim _table As DataTable
    <Description("传入的表变量")> Public WriteOnly Property Table() As DataTable
        Set(ByVal Value As DataTable)
            _table = Value
        End Set
    End Property
    Dim _ds As DataGridTableStyle
    <Description("传入的表风格的变量")> Public WriteOnly Property DataGridTableStyle() As DataGridTableStyle
        Set(ByVal Value As DataGridTableStyle)
            _ds = Value
        End Set
    End Property
    Dim _htext As String = ""
    <Description("表头文件")> Public WriteOnly Property HeaderText() As String
        Set(ByVal Value As String)
            _htext = Value
        End Set
    End Property
    Dim _hfont As New Font("Arial", 11)
    <Description("表头字体")> Public WriteOnly Property HeaderFont() As Font
        Set(ByVal Value As Font)
            _hfont = Value
        End Set
    End Property
    Dim _rfont As New Font("Arial", 9)
    <Description("行字体")> Public WriteOnly Property RowFont() As Font
        Set(ByVal Value As Font)
            _rfont = Value
        End Set
    End Property
    Dim _isLine As Boolean = False
    <Description("是否需要打印线条")> Public WriteOnly Property IsPaintLine() As Boolean
        Set(ByVal Value As Boolean)
            IsPaintLine = False
        End Set
    End Property
    <Description("是否具有可以打印的页")> Public ReadOnly Property PagesCount() As Int16  '这个函数可以不用
        Get
            Return GetTotalPage()
        End Get
    End Property
    Dim _totalColumns As Int16 = 0
    Dim _totalPage As Int16 = 0 '总页数
    Dim _curPage As Int16 = 1 '当前页数
    Dim _curRow As Int32 = 0 '当前行数
    Dim _curColumn As Int32 = 0 '当前列数
    Function GetTotalPage() As Int16
        Dim dcs As DataGridColumnStyle
        For Each dcs In _ds.GridColumnStyles
            _totalColumns += 1
        Next
        '先计算列占页,因为这个计算有点小问题
        '有可能造成的问题是单列会超出页宽,这种情况下将不进行打印,_totalPage=0
        Dim _width As Int16 = 0 '用来保存每一次计算的总宽度
        Dim i As Int16 = 0 '进行循环计算的条件
        If _table.Columns.Count = 0 Then '没有列
            Return 0
        End If
        If _table.Rows.Count = 0 Then '没有行
            Return 0
        End If
        While i < _totalColumns
            If _ds.GridColumnStyles(i).Width > Me.DefaultPageSettings.Bounds.Width Then  '假如单列的宽度大于页面设置的宽度,则不打印
                Return 0
            End If
            _width += _ds.GridColumnStyles(i).Width
            If _width > Me.DefaultPageSettings.Bounds.Width Then
                i -= 1 '退回一列,将此列计算到下一页中
                _totalPage += 1  '页数增加
                _width = 0 '宽度和置0
            End If
            i += 1
        End While
        _totalPage += 1  '全部通过了还有最后一页

        i = 0 '用来计算行所占页
        Dim j As Int16 = 0 '每页行数
        j = (Me.DefaultPageSettings.Bounds.Height - _hfont.Height - 2 - (_rfont.Height - 2) * 2) / (_rfont.Height + 2)      '每行保留2的间距,页尾也必须得加上
        i = _table.Rows.Count / j
        _totalPage *= i
        Return (_totalPage) '是返回,顺便也解决了_totalPage
    End Function
    Function GetTotalPage(ByVal width As Int16, ByVal height As Int16)
        Dim dcs As DataGridColumnStyle
        _totalColumns = 0
        _totalPage = 0
        For Each dcs In _ds.GridColumnStyles
            _totalColumns += 1
        Next
        '先计算列占页,因为这个计算有点小问题
        '有可能造成的问题是单列会超出页宽,这种情况下将不进行打印,_totalPage=0
        Dim _width As Int16 = 0 '用来保存每一次计算的总宽度
        Dim i As Int16 = 0 '进行循环计算的条件
        If _table.Columns.Count = 0 Then '没有列
            Return 0
        End If
        If _table.Rows.Count = 0 Then '没有行
            Return 0
        End If
        While i < _totalColumns
            If _ds.GridColumnStyles(i).Width > width Then  '假如单列的宽度大于页面设置的宽度,则不打印
                Return 0
            End If
            _width += _ds.GridColumnStyles(i).Width
            If _width > width Then
                i -= 1 '退回一列,将此列计算到下一页中
                _totalPage += 1  '页数增加
                _width = 0 '宽度和置0
            End If
            i += 1
        End While
        _totalPage += 1  '全部通过了还有最后一页

        i = 0 '用来计算行所占页
        Dim j As Int16 = 0 '每页行数
        j = Math.Floor((height - _hfont.Height - 2 - (_rfont.Height - 2) * 2) / (_rfont.Height + 2))    '每行保留2的间距,页尾也必须得加上
        i = Math.Ceiling(_table.Rows.Count / j)
        _totalPage *= i
        Return (_totalPage) '是返回,顺便也解决了_totalPage
    End Function
    Protected Overrides Sub OnPrintPage(ByVal e As System.Drawing.Printing.PrintPageEventArgs)
        If _curPage = 1 Then   '第一次运行,先运行计算总页数的程序,以前的都是错的
            GetTotalPage(e.MarginBounds.Width, e.MarginBounds.Height)
        End If
        Dim rPerPage As Int16 = (e.MarginBounds.Height - _hfont.Height - 2 - (_rfont.Height - 2) * 2) / (_rfont.Height + 2)
        Dim cPerPage As Int16 = 0 '每页能打印的列数
        Dim i As Int16 = _curRow '计算行数 需要打印到第几行
        Dim j As Int16 = _curColumn '列数的计算 ‘需要本页需要打印到第几列
        Dim xPos As Int16 = 0 '纵横点的坐标
        Dim yPos As Int16 = e.MarginBounds.Top
        Dim _width As Int16 = 0 '用来计算能用多少列的玩意,同时用于计算当前的宽度
        While _curColumn + cPerPage < _totalColumns
            cPerPage += 1
            _width += _ds.GridColumnStyles(j + cPerPage - 1).Width
            If _width > e.MarginBounds.Width Then
                cPerPage -= 1 '由于最大化后需要回退一列,所以每页打印的列数需要减1
                Exit While
            End If
        End While
        Dim o As Int16 = 1  '用于行数计数
        Dim p As Int16 = 1  '用于列数计数
        '''打印列头
        '''如何将文字居中:
        xPos = (e.MarginBounds.Width - _htext.Length * _hfont.Size) / 2
        e.Graphics.DrawString(_htext, _hfont, Brushes.Black, xPos, yPos)
        xPos = e.MarginBounds.Left
        yPos += _hfont.Height + 2
        ''打印表的列头
        While p <= cPerPage
            e.Graphics.DrawString(_ds.GridColumnStyles(p + _curColumn - 1).HeaderText, _rfont, Brushes.Black, xPos, yPos)
            xPos += _ds.GridColumnStyles(p + _curColumn - 1).Width
            p += 1
        End While

        xPos = e.MarginBounds.Left
        yPos += _rfont.Height + 1
        ''打完表头画根线,总比不画要强多了
        e.Graphics.DrawLine((New Pen(Color.Black)), xPos, yPos, xPos + e.MarginBounds.Width, yPos)
        xPos = e.MarginBounds.Left
        yPos += 2
        p = 1
        '进入表格内容打印阶断
        While o < rPerPage
            If _curRow + 1 > _table.Rows.Count Then
                Exit While
            End If
            While p <= cPerPage
                e.Graphics.DrawString(_table.Rows(i + o - 1)(_ds.GridColumnStyles(_curColumn + p - 1).MappingName) & "", _rfont, Brushes.Black, xPos, yPos)
                xPos += _ds.GridColumnStyles(_curColumn + p - 1).Width
                p += 1
            End While
            _curRow += 1
            p = 1  '列次减1
            yPos += _rfont.Height + 2
            xPos = e.MarginBounds.Left
            o += 1 '行次增加
        End While
        '打印主体后还得加一点后续
        e.Graphics.DrawString("打印日期:" & Date.Now.ToString("yyyy-MM-dd"), _rfont, Brushes.Black, xPos, yPos)
        '打印完后当前列需要增加
        If _curRow + 1 > _table.Rows.Count Then
            _curColumn += cPerPage
            _curRow = 0
        End If
        '打印完后当前页增加1
        _curPage += 1
        If _curPage > _totalPage Then
            _totalPage = 0   '由于预览完后需要打印的话就完了,因为变量已经超出了范围
            _totalColumns = 0
            _curPage = 1
            _curRow = 0
            _curColumn = 0
            e.HasMorePages = False
        Else
            e.HasMorePages = True
        End If
    End Sub
End Class

调用实例之一:

dim pd as new datagridprint

pd.table=ptable

pd.datagridtablestyle=datagrid1.tablestyles(0)

...

pd.print

原创粉丝点击