You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VB.NET中如何打印DataGridView中复选框选中的行?

解决VB.NET中DataGridView仅打印选中行的问题

我明白你现在的困扰——之前尝试的代码总是打印整个DataGridView,而你只需要打印那些复选框被选中的行。其实核心思路是不要直接打印控件本身,而是筛选出选中的行,手动绘制这些行的内容到打印页面上。下面是具体的实现步骤和代码示例:

实现步骤

  1. 在你的窗体上添加两个控件:PrintDocument(建议命名为printDoc)和PrintDialog(建议命名为printDialog1),这两个控件是VB.NET打印功能的核心。
  2. 编写PrintDocumentPrintPage事件处理逻辑,在这里我们会遍历选中的行,逐行绘制数据。
  3. 用一个按钮触发打印流程,弹出打印对话框后执行打印。

完整代码示例

Imports System.Drawing.Printing

Public Class Form1
    ' 用于跟踪当前打印的行索引,处理分页(当选中行太多一页放不下时)
    Private currentRowIndex As Integer = 0

    ' 打印按钮的点击事件
    Private Sub btnPrintSelected_Click(sender As Object, e As EventArgs) Handles btnPrintSelected.Click
        currentRowIndex = 0 ' 每次打印前重置行索引
        printDialog1.Document = printDoc
        ' 弹出打印对话框,用户确认后开始打印
        If printDialog1.ShowDialog() = DialogResult.OK Then
            printDoc.Print()
        End If
    End Sub

    ' PrintDocument的打印页面事件,核心绘制逻辑在这里
    Private Sub printDoc_PrintPage(sender As Object, e As PrintPageEventArgs) Handles printDoc.PrintPage
        ' 定义打印用到的字体和画笔
        Dim headerFont As New Font("Arial", 10, FontStyle.Bold) ' 表头字体
        Dim cellFont As New Font("Arial", 10) ' 单元格内容字体
        Dim blackPen As New Pen(Color.Black) ' 绘制边框的画笔
        Dim yPos As Integer = e.MarginBounds.Top ' 当前绘制的Y坐标(从页面上边距开始)
        Dim xPos As Integer = e.MarginBounds.Left ' 当前绘制的X坐标(从页面左边距开始)
        Dim columnWidths As New List(Of Integer)() ' 存储每列的打印宽度

        ' 第一步:计算每列的打印宽度(按DataGridView列宽的比例分配打印区域宽度)
        Dim totalGridWidth As Integer = 0
        For Each col As DataGridViewColumn In DataGridView1.Columns
            totalGridWidth += col.Width
        Next

        For Each col As DataGridViewColumn In DataGridView1.Columns
            Dim colWidth As Integer = CInt((col.Width / totalGridWidth) * e.MarginBounds.Width)
            columnWidths.Add(colWidth)
        Next

        ' 第二步:绘制表头
        xPos = e.MarginBounds.Left
        For i As Integer = 0 To DataGridView1.Columns.Count - 1
            e.Graphics.DrawString(DataGridView1.Columns(i).HeaderText, headerFont, Brushes.Black, xPos, yPos)
            ' 绘制表头单元格边框(可选,去掉的话注释掉这行)
            e.Graphics.DrawRectangle(blackPen, xPos, yPos, columnWidths(i), headerFont.Height + 5)
            xPos += columnWidths(i)
        Next
        yPos += headerFont.Height + 10 ' 下移到行内容区域

        ' 第三步:遍历并绘制选中的行
        While currentRowIndex < DataGridView1.Rows.Count
            Dim row As DataGridViewRow = DataGridView1.Rows(currentRowIndex)
            ' 跳过DataGridView的空新行(如果允许添加新行的话)
            If row.IsNewRow Then
                currentRowIndex += 1
                Continue While
            End If

            ' 判断当前行的复选框是否被选中
            ' 这里要注意:替换成你自己的复选框列名称或索引
            ' 示例1:按列名称判断(假设复选框列Name是"chkSelect")
            ' If CBool(row.Cells("chkSelect").Value) = True Then
            ' 示例2:按列索引判断(假设复选框列是第0列)
            If CBool(row.Cells(0).Value) = True Then
                ' 检查当前行是否超出页面底部,需要分页
                If yPos + cellFont.Height + 5 > e.MarginBounds.Bottom Then
                    e.HasMorePages = True ' 标记需要打印下一页
                    Return
                End If

                xPos = e.MarginBounds.Left
                ' 绘制当前行的每个单元格内容
                For i As Integer = 0 To DataGridView1.Columns.Count - 1
                    ' 处理单元格为空的情况
                    Dim cellValue As String = If(row.Cells(i).Value IsNot Nothing, row.Cells(i).Value.ToString(), "")
                    e.Graphics.DrawString(cellValue, cellFont, Brushes.Black, xPos, yPos)
                    ' 绘制单元格边框(可选)
                    e.Graphics.DrawRectangle(blackPen, xPos, yPos, columnWidths(i), cellFont.Height + 5)
                    xPos += columnWidths(i)
                Next
                yPos += cellFont.Height + 10 ' 下移到下一行的位置
            End If

            currentRowIndex += 1
        End While

        e.HasMorePages = False ' 所有选中行都打印完成,没有更多页
    End Sub
End Class

关键注意事项

  1. 复选框列的判断:你需要根据自己DataGridView中复选框列的实际名称或索引修改代码中的判断部分,确保能正确识别选中的行。如果复选框列的Value不是布尔值,记得先设置列的TrueValueFalseValue属性为TrueFalse
  2. 分页处理:代码中通过currentRowIndex变量跟踪当前打印到哪一行,当行内容超出页面底部时,会自动触发分页,继续打印剩余的选中行。
  3. 样式调整:你可以修改字体、颜色、边距等参数,比如调整headerFontcellFont的样式,或者设置printDoc.DefaultPageSettings.Margins来修改页面边距。
  4. 测试建议:测试时可以先选择打印到PDF,避免浪费纸张,方便快速查看效果。

内容的提问来源于stack exchange,提问作者ABDUL MAJEED ALI

火山引擎 最新活动