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
相关产品推荐
相关产品推荐

