繁体   English   中英

如何在vb.net中打印带有标题的datagridview表?

[英]How to print datagridview table with its header in vb.net?

我正在开发的系统中创建打印预览功能,该功能将预览我要打印的datagridview。 我使用了ooopsoft的代码作为参考,除了有一个小问题外,它工作正常。

问题:

在此处输入图片说明

在中,您会看到序列号为1的dgv行丢失了。 标题似乎已覆盖第一行。 我尝试了无数种方法来解决它,但仍然找不到解决方案。 我试图退出打印预览对话框,然后再次打开它,不过是结果我得到了。 我想我缺少一行代码,但是我不知道是什么。 请帮忙。

原始代码是一个不错的开始,但是存在一些错误和低效率:

  • 当有新页面时,它使用newpage标志打印标题第一行。 显然,您真的希望它同时做到
  • 每页打印一次列标题,因此根本不需要在数据打印循环中
  • 它不允许不可见的列或具有默认对齐方式以外的其他列,您可能要考虑其他此类设置。
  • 因为它实际上没有打印正确的行数,所以一旦修复,您会发现它会将前一页的最后一行重新打印为新页面的第一行。
  • 有一个内部装订线或页边距,因此文本不会打印得离网格线太近-这仅使用1或2的偏移量
  • 也不必要使用singleRectangleF
  • 还没有准备好再次显示或打印文档。 你也将要重置mRownewpage无论是在点击按钮或BeginPrint事件。

我添加了一些注释,以及为标题行着色并演示了如何实现类似RowPrePaint规则的内容。

Private mRow As Integer = 0
Private newpage As Boolean = True

Private Sub PrintDocument1_PrintPage(sender As System.Object,
                    e As PrintPageEventArgs) Handles PrintDocument1.PrintPage

    ' sets it to show '...' for long text
    Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
    fmt.LineAlignment = StringAlignment.Center
    fmt.Trimming = StringTrimming.EllipsisCharacter
    Dim y As Int32 = e.MarginBounds.Top
    Dim rc As Rectangle
    Dim x As Int32
    Dim h As Int32 = 0
    Dim row As DataGridViewRow

    ' print the header text for a new page
    '   use a grey bg just like the control
    If newpage Then
        row = dgvZZ.Rows(mRow)
        x = e.MarginBounds.Left
        For Each cell As DataGridViewCell In row.Cells
            ' since we are printing the control's view,
            ' skip invidible columns
            If cell.Visible Then
                rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)

                e.Graphics.FillRectangle(Brushes.LightGray, rc)
                e.Graphics.DrawRectangle(Pens.Black, rc)

                ' reused in the data pront - should be a function
                Select Case dgvZZ.Columns(cell.ColumnIndex).DefaultCellStyle.Alignment
                    Case DataGridViewContentAlignment.BottomRight,
                         DataGridViewContentAlignment.MiddleRight
                        fmt.Alignment = StringAlignment.Far
                        rc.Offset(-1, 0)
                    Case DataGridViewContentAlignment.BottomCenter,
                        DataGridViewContentAlignment.MiddleCenter
                        fmt.Alignment = StringAlignment.Center
                    Case Else
                        fmt.Alignment = StringAlignment.Near
                        rc.Offset(2, 0)
                End Select

                e.Graphics.DrawString(dgvZZ.Columns(cell.ColumnIndex).HeaderText,
                                            dgvZZ.Font, Brushes.Black, rc, fmt)
                x += rc.Width
                h = Math.Max(h, rc.Height)
            End If
        Next
        y += h

    End If
    newpage = False

    ' now print the data for each row
    Dim thisNDX As Int32
    For thisNDX = mRow To dgvZZ.RowCount - 1
        ' no need to try to print the new row
        If dgvZZ.Rows(thisNDX).IsNewRow Then Exit For

        row = dgvZZ.Rows(thisNDX)
        x = e.MarginBounds.Left
        h = 0

        ' reset X for data
        x = e.MarginBounds.Left

        ' print the data
        For Each cell As DataGridViewCell In row.Cells
            If cell.Visible Then
                rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)

                ' SAMPLE CODE: How To 
                ' up a RowPrePaint rule
                'If Convert.ToDecimal(row.Cells(5).Value) < 9.99 Then
                '    Using br As New SolidBrush(Color.MistyRose)
                '        e.Graphics.FillRectangle(br, rc)
                '    End Using
                'End If

                e.Graphics.DrawRectangle(Pens.Black, rc)

                Select Case dgvZZ.Columns(cell.ColumnIndex).DefaultCellStyle.Alignment
                    Case DataGridViewContentAlignment.BottomRight,
                         DataGridViewContentAlignment.MiddleRight
                        fmt.Alignment = StringAlignment.Far
                        rc.Offset(-1, 0)
                    Case DataGridViewContentAlignment.BottomCenter,
                        DataGridViewContentAlignment.MiddleCenter
                        fmt.Alignment = StringAlignment.Center
                    Case Else
                        fmt.Alignment = StringAlignment.Near
                        rc.Offset(2, 0)
                End Select

                e.Graphics.DrawString(cell.FormattedValue.ToString(),
                                      dgvZZ.Font, Brushes.Black, rc, fmt)

                x += rc.Width
                h = Math.Max(h, rc.Height)
            End If

        Next
        y += h
        ' next row to print
        mRow = thisNDX + 1

        If y + h > e.MarginBounds.Bottom Then
            e.HasMorePages = True
            ' mRow -= 1   causes last row to rePrint on next page
            newpage = True
            Return
        End If
    Next


End Sub

在此处输入图片说明 在此处输入图片说明

请注意,在DGV中有一个Id列设置为不可见,在Color列居中,并且Price左对齐-这些都是从控件中选取的设置。 还要注意,文本只是稍微偏离了网格线。


上述最后一颗子弹点, 你也将要重置mRownewpage在点击按钮或任BeginPrint事件。 意味着:

Private Sub PrintDocument1_BeginPrint(sender As Object, 
          e As PrintEventArgs) Handles PrintDocument1.BeginPrint
    mRow = 0
    newpage = True
    PrintPreviewDialog1.PrintPreviewControl.StartPage = 0
    PrintPreviewDialog1.PrintPreviewControl.Zoom = 1.0
End Sub

预览后, mRow变量将指示所有行均已打印。 如果用户单击“打印”或返回另一个“预览”,则不会打印任何内容。 此代码还重置要显示的第一页和初始“缩放”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM