zoukankan      html  css  js  c++  java
  • [VB.NET] 打印DataGridView类

    Imports System.Drawing.Printing

    Public Class PrintDataGridView
    Private WithEvents PrintDocument1 As New Printing.PrintDocument
    Private WithEvents PageSetupDialog1 As New System.Windows.Forms.PageSetupDialog
    Private WithEvents FontDialog1 As New System.Windows.Forms.FontDialog
    Private WithEvents PrintPreviewDialog1 As New System.Windows.Forms.PrintPreviewDialog
    Private DGV As DataGridView
    Private strTitle As String
    Private tsiDisplayStyle As ToolStripItemDisplayStyle = ToolStripItemDisplayStyle.Image
    Private tirTextImageRelation As TextImageRelation = Windows.Forms.TextImageRelation.ImageAboveText
    Private wInc As Single = 5 'wInc 为单元格宽增量
    Private hInc As Single = 5 'hInc 为单元格竖增量
    Private MainStartHeigth As Single 'MainStartHeigth 为主体表格起始的高度
    Shared pNo As Integer = 1 'pNo 为页码
    Private StartHeigth As Single
    Private StartPos As Single
    Shared hi As Integer = 0
    Public PrintFont As Font = New Font("Arial", 16)
    Private ColumnsWidth() As Single '数组 ColumnsWidth 为计算后的列宽
    Private orgColumnsWidth() As Single '数组 orgColumnsWidth 为原始的最大列宽
    Private RowHeigth As Single 'RowHeigth 为计算后的行高

    Sub New()
    AddHandler PrintDocument1.PrintPage, AddressOf Me.pd_PrintMain
    End Sub

    '按钮显示方式
    '遍历整个表格,得到每列的最大宽度
    Private Sub GetLargestWidthOfColumn(ByVal g As System.Drawing.Graphics)
    ReDim ColumnsWidth(DGV.Columns.Count - 1) '定义列宽数组的长度
    ReDim orgColumnsWidth(DGV.Columns.Count - 1)
    For i As Integer = 0 To DGV.Columns.Count - 1
    If DGV.Columns(i).Visible = False Then Continue For '如果列为隐藏,不打印
    ColumnsWidth(i) = DGV.Columns(i).Width
    Next

    Dim iC, iR As Integer
    For iC = 0 To DGV.Columns.Count - 1
    If DGV.Columns(iC).Visible = False Then Continue For '如果列为隐藏,不打印
    Dim dc As DataGridViewColumn = DGV.Columns(iC)
    '计算列头文字需要的宽
    Dim sizeFHeader As Drawing.SizeF
    sizeFHeader
    = g.MeasureString(dc.HeaderText, PrintFont)
    If sizeFHeader.Width > ColumnsWidth(iC) Then
    orgColumnsWidth(iC)
    = sizeFHeader.Width
    Else
    If orgColumnsWidth(iC) > ColumnsWidth(iC) * 3 Then
    orgColumnsWidth(iC)
    = ColumnsWidth(iC) * 3
    Else
    orgColumnsWidth(iC)
    = ColumnsWidth(iC)
    End If
    End If
    RowHeigth
    = sizeFHeader.Height

    dc.Dispose()
    '计算值的宽
    For iR = 0 To DGV.Rows.Count - 1
    Dim dr As DataGridViewRow = DGV.Rows(iR)
    If dr.Cells(iC).Value IsNot Nothing AndAlso Not IsDBNull(dr.Cells(iC).Value) Then
    sizeFHeader
    = g.MeasureString(dr.Cells(iC).Value.ToString, PrintFont)
    If orgColumnsWidth(iC) < sizeFHeader.Width Then
    orgColumnsWidth(iC)
    = sizeFHeader.Width
    End If

    End If
    dr.Dispose()
    Next
    Next
    End Sub

    '根据纸张宽度,计算出合适的列宽,返回缩小的比例
    Private Function GetFitWidthOfColumn(ByVal pWidth As Single) As Integer
    '每列按原始宽度的1%递减,直到适合纸张宽度(pWidth)
    Dim l, i, k As Integer
    l
    = orgColumnsWidth.Length
    For k = 100 To 1 Step -1
    Dim WidthSum As Single = 0
    '按比例求宽度
    For i = 0 To l - 1
    ColumnsWidth(i)
    = orgColumnsWidth(i) * k / 100
    WidthSum
    += orgColumnsWidth(i) * k / 100 + wInc
    Next
    If Not WidthSum > pWidth Then
    Exit For
    End If
    Next
    Return (k)
    End Function

    '根据合适的列宽和列宽缩小的比例,计算出合适的行高
    Private Sub GetFitHeightOfRow(ByVal pScale As Integer)
    RowHeigth
    = RowHeigth * Fix((100 / pScale) + 1) + hInc
    End Sub

    '打印主体
    Private Sub pd_PrintMain(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
    Dim g As Graphics = e.Graphics
    '如果是第一页,计算长宽
    If pNo = 1 Then
    GetLargestWidthOfColumn(g)
    GetFitHeightOfRow(GetFitWidthOfColumn(e.MarginBounds.Width))
    End If
    '添加DataGridView主体
    '计算标题的高度,预留空间
    Dim sizeFTitle As Drawing.SizeF
    sizeFTitle
    = e.Graphics.MeasureString(Title, New Font("宋体", 30, FontStyle.Bold))
    MainStartHeigth
    = sizeFTitle.Height + e.MarginBounds.Top
    StartHeigth
    = MainStartHeigth
    '-------------------再来开始------------------------
    '添加列头,按已经求出的最长宽度
    '起始位置为纸张可打印边框的左边
    StartPos = e.MarginBounds.Left
    Dim i As Integer
    For i = 0 To DGV.Columns.Count - 1
    '如果列为隐藏,不打印
    If DGV.Columns(i).Visible = False Then
    Continue For
    End If
    Dim dc As DataGridViewColumn
    dc
    = DGV.Columns(i)
    Dim sizeFHeader As New Drawing.SizeF
    sizeFHeader
    = e.Graphics.MeasureString(dc.HeaderText, PrintFont, ColumnsWidth(i)) '写表头
    g.DrawString(dc.HeaderText, PrintFont, Drawing.Brushes.Black, New RectangleF(StartPos + wInc, StartHeigth + hInc, ColumnsWidth(i) - wInc, RowHeigth - hInc)) '添加外边框
    g.DrawLine(Pens.Black, StartPos, StartHeigth, StartPos + ColumnsWidth(i), StartHeigth) '
    g.DrawLine(Pens.Black, StartPos, StartHeigth, StartPos, StartHeigth + RowHeigth) '
    StartPos += ColumnsWidth(i)
    Next '添加主体
    StartHeigth += RowHeigth
    While hi < DGV.Rows.Count And StartHeigth < e.MarginBounds.Height
    StartPos
    = e.MarginBounds.Left
    Dim obj As New Object
    Dim wi As Integer = 0
    For wi = 0 To DGV.Columns.Count - 1
    If DGV.Columns(wi).Visible = False Then Continue For '如果列为隐藏,不打印
    Dim dcWidth As Single
    dcWidth
    = ColumnsWidth(wi)

    g.DrawLine(Pens.Black, StartPos, StartHeigth, StartPos
    + dcWidth, StartHeigth) '
    g.DrawLine(Pens.Black, StartPos, StartHeigth, StartPos, StartHeigth + RowHeigth) '
    StartPos += dcWidth
    Try
    If Not IsDBNull(DGV.Rows(hi).Cells(wi).Value) Then
    g.DrawString(DGV.Rows(hi).Cells(wi).Value.ToString(), PrintFont, Drawing.Brushes.Black,
    New RectangleF(StartPos - dcWidth + 2, StartHeigth + 3, dcWidth + 2, RowHeigth))
    End If
    Catch ex As Exception
    MessageBox.Show(ex.Message,
    "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End Try
    Next
    StartHeigth
    += RowHeigth
    hi
    += 1
    End While
    '如果是第一页,添加表头
    '根据绘制表格的宽度添加标题()
    If pNo = 1 Then
    If StartPos - e.MarginBounds.Left < sizeFTitle.Width Then
    '如果标题的宽度大于表格的宽度,则缩小标题字号
    For i = 30 To 1 Step -1
    sizeFTitle
    = e.Graphics.MeasureString(Title, New Font("宋体", i, FontStyle.Bold))
    If sizeFTitle.Width < StartPos - e.MarginBounds.Left Then
    g.DrawString(Title,
    New Font("宋体", i, FontStyle.Bold), Brushes.Black, (StartPos - e.MarginBounds.Left - sizeFTitle.Width) / 2 + e.MarginBounds.Left, (MainStartHeigth - sizeFTitle.Height) / 2)
    Exit For
    End If
    Next
    Else
    g.DrawString(Title,
    New Font("宋体", 30, FontStyle.Bold), Brushes.Black, (StartPos - e.MarginBounds.Left - sizeFTitle.Width) / 2 + e.MarginBounds.Left, (MainStartHeigth - sizeFTitle.Height) / 2)
    End If
    End If

    g.DrawLine(Pens.Black, e.MarginBounds.Left, StartHeigth, StartPos, StartHeigth)
    '封底
    g.DrawLine(Pens.Black, StartPos, MainStartHeigth, StartPos, StartHeigth) '封右边
    If StartHeigth + RowHeigth > e.MarginBounds.Height And hi < DGV.Rows.Count Then
    e.HasMorePages
    = True
    pNo
    += 1 '页码加1
    StartPos = e.MarginBounds.Left
    StartHeigth
    = e.MarginBounds.Top
    Else
    e.HasMorePages
    = False
    End If '结尾标志
    'If hi.Equals(dgv.Rows.Count) Then 'And e.HasMorePages.Equals(False) Then
    If hi >= DGV.Rows.Count Then 'And e.HasMorePages.Equals(False) Then
    hi = 0
    pNo
    = 1
    Exit Sub
    End If
    End Sub

    '数据源,输入DataGridView
    Public Property MyDataGridView() As DataGridView
    Set(ByVal value As DataGridView)
    DGV
    = value
    End Set
    Get
    Return DGV
    End Get
    End Property

    '报表标题
    Public Property Title() As String
    Set(ByVal value As String)
    strTitle
    = value
    End Set
    Get
    Return strTitle
    End Get
    End Property

    '页面设置
    Public Sub PageSetup()
    Me.PageSetupDialog1.Document = Me.PrintDocument1
    Me.PageSetupDialog1.ShowDialog()
    Me.PrintDocument1.DefaultPageSettings = Me.PageSetupDialog1.PageSettings
    End Sub

    '打印预览
    Public Sub PrintPreview()
    Me.PrintPreviewDialog1.Document = Me.PrintDocument1
    Me.PrintPreviewDialog1.ShowDialog()
    End Sub

    '设置字体
    Public Sub PrintPreviewFont()
    Me.FontDialog1.ShowDialog()
    PrintFont
    = Me.FontDialog1.Font
    End Sub

    '打印
    Public Sub Print()
    Me.PrintDocument1.Print()
    End Sub
    End Class
  • 相关阅读:
    java学习第六天
    java学习第五天
    java学习第四天
    java学习第三天
    java学习第二天
    java学习第一天
    性能测试学习第十三天_性能测试报告编写
    性能测试学习第十二天_性能分析
    性能测试学习第十一天_Analysis
    性能测试学习第十天_controller
  • 原文地址:https://www.cnblogs.com/hcbin/p/1688984.html
Copyright © 2011-2022 走看看