You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET打印2页内容重叠 如何实现无重叠正确分页打印

问题根因

分页重叠是两个逻辑错误导致的:

  • 你把遍历所有勾选行的循环全部写在PrintPage事件内部,每次触发单页打印时,循环都会从第0行开始执行,同一坐标位置会被多次写入不同行的ContainerNo、备注等内容,直接造成重叠。
  • 计数用的index变量没有和实际待打印行绑定,HasMorePages分页触发逻辑完全错位,没有做到“一页只打印一条记录”。
修复方案

第一步:声明窗体级全局变量

不要把进度变量写在PrintPage事件内部,在窗体类的最外层声明两个变量,用来跟踪打印进度、缓存待打印数据:

' 记录当前需要打印的行索引
Private currentPrintRowIndex As Integer = 0
' 缓存所有选中的待打印行,避免每次打印页事件都遍历整个表格
Private printRows As New List(Of DataGridViewRow)()

第二步:打印前初始化状态

在触发打印的按钮点击事件中(也就是调用PrintDocument.Print()方法前),重置打印进度、筛选出所有需要打印的勾选行:

' 重置打印进度
currentPrintRowIndex = 0
printRows.Clear()

' 筛选第一列勾选的所有行
For Each row As DataGridViewRow In DataGridView1.Rows
    ' 如果单元格存的是字符串"True",就把判断条件改成 row.Cells(0).Value.ToString().Trim() = "True"
    If Convert.ToBoolean(row.Cells(0).Value) = True Then
        printRows.Add(row)
    End If
Next

' 无待打印内容直接终止
If printRows.Count = 0 Then
    MessageBox.Show("未选中需要打印的集装箱记录")
    Return
End If

' 启动打印
PrintDocument1.Print()

第三步:重写PrintPage事件逻辑

每次触发PrintPage事件时只打印1条记录,打印完成后移动索引,根据剩余待打印记录判断是否需要开新页:

Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    If ComboBox1.Text <> "Sampled" Then
        e.HasMorePages = False
        Return
    End If

    ' 仅取当前索引对应的单条记录,不要循环所有行
    Dim currentRow = printRows(currentPrintRowIndex)
    Dim ContainerNo = currentRow.Cells(18).Value
    Dim TotalContainer = currentRow.Cells(19).Value

    ' 固定坐标绘制当前页内容,不会出现重叠
    e.Graphics.DrawString("SAMPLED", font3, Brushes.Black, 120, 70)
    e.Graphics.DrawString("CONTAINER No:________________OF________________", font1, Brushes.Black, 90, 140)
    e.Graphics.DrawString("REMARKS:_______________________________________", font1, Brushes.Black, 90, 160)
    e.Graphics.DrawString("SAMPLED BY:", font1, Brushes.Black, 170, 220)
    e.Graphics.DrawString("____________________", font1, Brushes.Black, 155, 235)
    e.Graphics.DrawString("QC SAMPLER/DATE", font1, Brushes.Black, 160, 250)

    ' 填充当前记录的动态值
    e.Graphics.DrawString(ContainerNo.ToString(), font1, Brushes.Black, 190, 138)
    e.Graphics.DrawString(TotalContainer.ToString(), font1, Brushes.Black, 280, 138)
    e.Graphics.DrawString(TextBox12.Text, font1, Brushes.Black, 160, 158)

    ' 索引后移,指向下一条待打印记录
    currentPrintRowIndex += 1

    ' 还有未打印记录则开启新页,否则结束打印
    e.HasMorePages = currentPrintRowIndex < printRows.Count
End Sub
注意事项
  • 不要在PrintPage事件中用MessageBox调试,弹窗会打断打印事件流,调试时请用Debug.Print()把变量值输出到VS输出窗口。
  • 打印用到的font1、font3请在窗体级初始化,打印结束后及时释放,避免字体资源泄漏。
  • 修复后会严格按选中顺序逐页打印:第一页显示2 of 3,第二页显示3 of 3,无内容重叠问题。

当前错误输出效果

内容的提问来源于stack exchange,提问作者Jomar Apellido

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 17:57:20