VB.NET中如何打印DataGridView中复选框选中的行?
解决VB.NET中DataGridView仅打印选中行的问题
我明白你现在的困扰——之前尝试的代码总是打印整个DataGridView,而你只需要打印那些复选框被选中的行。其实核心思路是不要直接打印控件本身,而是筛选出选中的行,手动绘制这些行的内容到打印页面上。下面是具体的实现步骤和代码示例:
实现步骤
- 在你的窗体上添加两个控件:
PrintDocument(建议命名为printDoc)和PrintDialog(建议命名为printDialog1),这两个控件是VB.NET打印功能的核心。 - 编写
PrintDocument的PrintPage事件处理逻辑,在这里我们会遍历选中的行,逐行绘制数据。 - 用一个按钮触发打印流程,弹出打印对话框后执行打印。
完整代码示例
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
关键注意事项
- 复选框列的判断:你需要根据自己DataGridView中复选框列的实际名称或索引修改代码中的判断部分,确保能正确识别选中的行。如果复选框列的
Value不是布尔值,记得先设置列的TrueValue和FalseValue属性为True和False。 - 分页处理:代码中通过
currentRowIndex变量跟踪当前打印到哪一行,当行内容超出页面底部时,会自动触发分页,继续打印剩余的选中行。 - 样式调整:你可以修改字体、颜色、边距等参数,比如调整
headerFont和cellFont的样式,或者设置printDoc.DefaultPageSettings.Margins来修改页面边距。 - 测试建议:测试时可以先选择打印到PDF,避免浪费纸张,方便快速查看效果。
内容的提问来源于stack exchange,提问作者ABDUL MAJEED ALI




