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

如何实现PrintDocument多页打印?当前仅计数页面无实际输出

多页打印实现方案

你的代码存在几个核心问题,导致无法正常输出多页,且陷入无限打印计数的循环:

  1. 缺少全局状态记录:PrintPage事件会在每一页打印时触发,需要用类级变量记录当前已经打印到ListView的哪一项,否则每次触发都会从头开始打印。
  2. 无效循环占用资源:For List = 0 To ListView1.Items.Count - 1 Next 这个循环没有任何执行逻辑,完全多余。
  3. HasMorePages设置错误:代码末尾强制将e.HasMorePages = True,导致打印系统一直认为还有更多页需要打印,陷入无限循环,所以会持续计数但无法正常输出。
  4. 页面边界判断逻辑错误:用固定值1000判断是否换页,没有结合打印页面的实际可打印区域高度,且判断时机不对。

修正后的代码

首先在窗体类中添加类级变量,用来记录当前打印的项索引:

' 类级变量,记录当前打印到第几个ListView项
Private currentItemIndex As Integer = 0

然后修改PrintDocument1_PrintPage事件处理代码:

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Dim Head As Integer = 30 ' 直接初始化,不需要先设0再加30
    Dim currentY As Integer ' 记录当前打印的Y坐标

    ' 打印标题
    e.Graphics.DrawString("Pocket bok collection", New Drawing.Font("Times new roman", 20), Brushes.Black, 250, Head)
    Head += 40

    ' 打印表头
    e.Graphics.DrawString("Pocket Serie Name", New Drawing.Font("Times new roman", 10), Brushes.Black, 50, Head)
    e.Graphics.DrawString("Single/Double", New Drawing.Font("Times new roman", 10), Brushes.Black, 100, Head)
    e.Graphics.DrawString("Pocket Nr", New Drawing.Font("Times new roman", 10), Brushes.Black, 200, Head)
    e.Graphics.DrawString("Year", New Drawing.Font("Times new roman", 10), Brushes.Black, 300, Head)
    e.Graphics.DrawString("Bought Date", New Drawing.Font("Times new roman", 10), Brushes.Black, 450, Head)
    e.Graphics.DrawString("Cost", New Drawing.Font("Times new roman", 10), Brushes.Black, 550, Head)
    e.Graphics.DrawString("Own", New Drawing.Font("Times new roman", 10), Brushes.Black, 650, Head)

    currentY = Head + 30 ' 表头下方留30间距开始打印内容

    ' 循环打印ListView项,直到超出页面可打印区域或所有项打印完成
    While currentItemIndex < ListView1.Items.Count
        Dim itm As ListViewItem = ListView1.Items(currentItemIndex)
        ' 检查当前Y坐标是否超出页面可打印区域的底部
        If currentY + 30 > e.MarginBounds.Bottom Then
            ' 还有未打印的项,标记需要打印下一页
            e.HasMorePages = True
            Exit While
        End If

        ' 打印当前项
        e.Graphics.DrawString(itm.Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 50, currentY)
        e.Graphics.DrawString(itm.SubItems(1).Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 100, currentY)
        e.Graphics.DrawString(itm.SubItems(2).Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 200, currentY)
        e.Graphics.DrawString(itm.SubItems(3).Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 300, currentY)
        e.Graphics.DrawString(itm.SubItems(4).Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 450, currentY)
        e.Graphics.DrawString(itm.SubItems(5).Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 550, currentY)
        e.Graphics.DrawString(itm.SubItems(6).Text, New Drawing.Font("Times new roman", 10), Brushes.Black, 650, currentY)

        ' 更新索引和Y坐标
        currentItemIndex += 1
        currentY += 30
    End While

    ' 如果所有项都打印完成,标记没有更多页
    If currentItemIndex >= ListView1.Items.Count Then
        e.HasMorePages = False
        currentItemIndex = 0 ' 重置索引,方便下次打印
    End If
End Sub

关键说明

  • 类级变量currentItemIndex:跨PrintPage事件记录打印进度,确保每一页从上次结束的位置继续打印。
  • 页面边界判断:使用e.MarginBounds.Bottom获取打印页面的实际可打印区域底部坐标,避免内容超出页面范围。
  • HasMorePages逻辑:只有当还有未打印的项且当前页已打满时,才标记需要下一页;所有项打印完成后,标记为无更多页,终止打印循环。
  • 重置索引:打印完成后重置currentItemIndex,避免下次打印时从上次结束的位置开始。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 10:37:47