【问题标题】:Problems printing DataGridView打印 DataGridView 的问题
【发布时间】:2014-12-10 04:21:08
【问题描述】:

您好,我正在使用以下代码打印 datagridview。它可以工作,但它会打印每一列,甚至是那些在表单上不可见的列。有没有办法让它只打印可见的列。谢谢。

Private Structure pageDetails
    Dim columns As Integer
    Dim rows As Integer
    Dim startCol As Integer
    Dim startRow As Integer
End Structure

Private pages As Dictionary(Of Integer, pageDetails)
Dim maxPagesWide As Integer
Dim maxPagesTall As Integer

Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
    ''this removes the printed page margins
    PrintDocument1.OriginAtMargins = True
    PrintDocument1.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0)

    pages = New Dictionary(Of Integer, pageDetails)

    Dim maxWidth As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width) - 40
    Dim maxHeight As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Height) - 40 + Label1.Height

    Dim pageCounter As Integer = 0
    pages.Add(pageCounter, New pageDetails)

    Dim columnCounter As Integer = 0

    Dim columnSum As Integer = DataGridView1.RowHeadersWidth

    For c As Integer = 0 To DataGridView1.Columns.Count - 1
        If columnSum + DataGridView1.Columns(c).Width < maxWidth Then
            columnSum += DataGridView1.Columns(c).Width
            columnCounter += 1
        Else
            pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
            columnSum = DataGridView1.RowHeadersWidth + DataGridView1.Columns(c).Width
            columnCounter = 1
            pageCounter += 1
            pages.Add(pageCounter, New pageDetails With {.startCol = c})
        End If
        If c = DataGridView1.Columns.Count - 1 Then
            If pages(pageCounter).columns = 0 Then
                pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
            End If
        End If
    Next

    maxPagesWide = pages.Keys.Max + 1

    pageCounter = 0

    Dim rowCounter As Integer = 0

    Dim rowSum As Integer = DataGridView1.ColumnHeadersHeight

    For r As Integer = 0 To DataGridView1.Rows.Count - 2
        If rowSum + DataGridView1.Rows(r).Height < maxHeight Then
            rowSum += DataGridView1.Rows(r).Height
            rowCounter += 1
        Else
            pages(pageCounter) = New pageDetails With {.columns = pages(pageCounter).columns, .rows = rowCounter, .startCol = pages(pageCounter).startCol, .startRow = pages(pageCounter).startRow}
            For x As Integer = 1 To maxPagesWide - 1
                pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter).startRow}
            Next

            pageCounter += maxPagesWide
            For x As Integer = 0 To maxPagesWide - 1
                pages.Add(pageCounter + x, New pageDetails With {.columns = pages(x).columns, .rows = 0, .startCol = pages(x).startCol, .startRow = r})
            Next

            rowSum = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(r).Height
            rowCounter = 1
        End If
        If r = DataGridView1.Rows.Count - 2 Then
            For x As Integer = 0 To maxPagesWide - 1
                If pages(pageCounter + x).rows = 0 Then
                    pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter + x).startRow}
                End If
            Next
        End If
    Next

    maxPagesTall = pages.Count \ maxPagesWide

End Sub

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Dim rect As New Rectangle(20, 20, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), Label1.Height)
    Dim sf As New StringFormat
    sf.Alignment = StringAlignment.Center
    sf.LineAlignment = StringAlignment.Center

    e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, rect, sf)

    sf.Alignment = StringAlignment.Near

    Dim startX As Integer = 50
    Dim startY As Integer = rect.Bottom

    Static startPage As Integer = 0

    For p As Integer = startPage To pages.Count - 1
        Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight)
        e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
        e.Graphics.DrawRectangle(Pens.Black, cell)

        startY += DataGridView1.ColumnHeadersHeight

        For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
            cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height)
            e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
            e.Graphics.DrawRectangle(Pens.Black, cell)
            e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
            startY += DataGridView1.Rows(r).Height
        Next

        startX += cell.Width
        startY = rect.Bottom

        For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
            cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight)
            e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
            e.Graphics.DrawRectangle(Pens.Black, cell)
            e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
            startX += DataGridView1.Columns(c).Width
        Next

        startY = rect.Bottom + DataGridView1.ColumnHeadersHeight

        For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
            startX = 50 + DataGridView1.RowHeadersWidth
            For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
                cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height)
                e.Graphics.DrawRectangle(Pens.Black, cell)
                e.Graphics.DrawString(DataGridView1(c, r).Value, DataGridView1.Font, Brushes.Black, cell, sf)
                startX += DataGridView1.Columns(c).Width
            Next
            startY += DataGridView1.Rows(r).Height
        Next

        If p <> pages.Count - 1 Then
            startPage = p + 1
            e.HasMorePages = True
            Return
        Else
            startPage = 0
        End If

    Next

End Sub

Private Sub PrintAMToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PrintAMToolStripMenuItem.Click
    PrintDocument1.DefaultPageSettings.Landscape = True
    PrintDocument1.Print()
End Sub

【问题讨论】:

    标签: vb.net printing datagridview


    【解决方案1】:

    我在您的 PrintDocument1_PrintPage 和 PrintDocument1_BeginPrint 事件中添加了 If 条件,以检查每次针对您的列出现循环时该列是否可见:

    Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
    
        ''this removes the printed page margins
        PrintDocument1.OriginAtMargins = True
        PrintDocument1.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0)
    
        pages = New Dictionary(Of Integer, pageDetails)
    
        Dim maxWidth As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width) - 40
        Dim maxHeight As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Height) - 40 + Label1.Height
    
        Dim pageCounter As Integer = 0
        pages.Add(pageCounter, New pageDetails)
    
        Dim columnCounter As Integer = 0
    
        Dim columnSum As Integer = DataGridView1.RowHeadersWidth
    
        For c As Integer = 0 To DataGridView1.Columns.Count - 1
    
            If columnSum + DataGridView1.Columns(c).Width < maxWidth Then
                columnSum += DataGridView1.Columns(c).Width
                columnCounter += 1
            Else
                If DataGridView1.Columns(c).Visible = True Then
                    pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
                    columnSum = DataGridView1.RowHeadersWidth + DataGridView1.Columns(c).Width
                    columnCounter = 1
                    pageCounter += 1
                    pages.Add(pageCounter, New pageDetails With {.startCol = c})
                End If
            End If
            If c = DataGridView1.Columns.Count - 1 Then
    
                If pages(pageCounter).columns = 0 Then
                    pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
                End If
    
            End If
    
        Next
    
        maxPagesWide = pages.Keys.Max + 1
    
        pageCounter = 0
    
        Dim rowCounter As Integer = 0
    
        Dim rowSum As Integer = DataGridView1.ColumnHeadersHeight
    
        For r As Integer = 0 To DataGridView1.Rows.Count - 2
            If rowSum + DataGridView1.Rows(r).Height < maxHeight Then
                rowSum += DataGridView1.Rows(r).Height
                rowCounter += 1
            Else
                pages(pageCounter) = New pageDetails With {.columns = pages(pageCounter).columns, .rows = rowCounter, .startCol = pages(pageCounter).startCol, .startRow = pages(pageCounter).startRow}
                For x As Integer = 1 To maxPagesWide - 1
                    pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter).startRow}
                Next
    
                pageCounter += maxPagesWide
                For x As Integer = 0 To maxPagesWide - 1
                    pages.Add(pageCounter + x, New pageDetails With {.columns = pages(x).columns, .rows = 0, .startCol = pages(x).startCol, .startRow = r})
                Next
    
                rowSum = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(r).Height
                rowCounter = 1
            End If
            If r = DataGridView1.Rows.Count - 2 Then
                For x As Integer = 0 To maxPagesWide - 1
                    If pages(pageCounter + x).rows = 0 Then
                        pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter + x).startRow}
                    End If
                Next
            End If
        Next
    
        maxPagesTall = pages.Count \ maxPagesWide
    
    End Sub
    
    Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        Dim rect As New Rectangle(20, 20, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), Label1.Height)
        Dim sf As New StringFormat
        sf.Alignment = StringAlignment.Center
        sf.LineAlignment = StringAlignment.Center
    
        e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, rect, sf)
    
        sf.Alignment = StringAlignment.Near
    
        Dim startX As Integer = 50
        Dim startY As Integer = rect.Bottom
    
        Static startPage As Integer = 0
    
        For p As Integer = startPage To pages.Count - 1
            Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight)
            e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
            e.Graphics.DrawRectangle(Pens.Black, cell)
    
            startY += DataGridView1.ColumnHeadersHeight
    
            For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
    
                cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height)
                e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
                e.Graphics.DrawRectangle(Pens.Black, cell)
                e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
                startY += DataGridView1.Rows(r).Height
            Next
    
            startX += cell.Width
            startY = rect.Bottom
    
            For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
                If DataGridView1.Columns(c).Visible = True Then
                    cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight)
                    e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
                    e.Graphics.DrawRectangle(Pens.Black, cell)
                    e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
                    startX += DataGridView1.Columns(c).Width
                End If
    
            Next
    
            startY = rect.Bottom + DataGridView1.ColumnHeadersHeight
    
            For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
                startX = 50 + DataGridView1.RowHeadersWidth
                For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
                    If DataGridView1.Columns(c).Visible = True Then
                        cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height)
                        e.Graphics.DrawRectangle(Pens.Black, cell)
                        e.Graphics.DrawString(DataGridView1(c, r).Value, DataGridView1.Font, Brushes.Black, cell, sf)
                        startX += DataGridView1.Columns(c).Width
                    End If
                Next
                startY += DataGridView1.Rows(r).Height
            Next
    
            If p <> pages.Count - 1 Then
                startPage = p + 1
                e.HasMorePages = True
                Return
            Else
                startPage = 0
            End If
    
        Next
    
    End Sub
    

    【讨论】:

    • 效果很好。谢谢你。现在我希望它扩展字段以尝试适应所有数据,但也将其保留在 A4 页面内。你能帮我解决这个问题还是我应该问一个新问题。
    • 我要做的是在将数据加载到 datagridview 后设置列宽,例如: DataGridView1.Columns(0).Width = 50 DataGridView1.Columns(1).Width = 70 等等。
    • 我将 DataGridView AutoSizeColumnsMode 设置为填充。所以它在不添加滚动条的情况下填充了控件的宽度。因此,当我调整列的宽度时,它会搞乱其他所有内容。
    • 如果显示的数据太长,我不会将其设置为专门填充。设置宽度是更好的做法。除此之外,我不确定它不适合你。目前我能想到的就这些了。
    • 没关系,我找到了解决问题的替代方法。谢谢。我将其设置为答案。
    猜你喜欢
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 2016-02-26
    相关资源
    最近更新 更多