首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > VB Dotnet >

datagridview打印有关问题

2012-05-05 
datagridview打印问题各位达人,我在datagridview动态显示了资料,并用在网上下载打印类设置打印,现在想在这

datagridview打印问题
各位达人,我在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", 12)
  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

[解决办法]
g.DrawString(Title, New Font("宋体", 30, FontStyle.Bold), Brushes.Black, (StartPos - e.MarginBounds.Left - sizeFTitle.Width) / 2 + e.MarginBounds.Left, (MainStartHeigth - sizeFTitle.Height) / 2)

下面加一行你要的汇总就可以了.


看你代码,标题好象就只有在第一页显示.
那就写在,If pNo = 1 Then判断里面吧,这是从你的需求上看的,对不对,你试下吧.

顺便说下,摆托以后那么长的代码少弄上来了,真心不想看....

热点排行