【问题标题】:How print more than one page in VB?如何在VB中打印多页?
【发布时间】:2019-01-17 20:08:23
【问题描述】:

我应该在我的代码中进行哪些更改才能在打印预览中看到多页并打印多页?

Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDoc.PrintPage
    Static intStart As Integer
    Dim font0 As New Font("arial", 24, FontStyle.Underline)
    Dim fntText As Font = font0
    Dim txtHeight As Integer
    Dim LeftMargin As Integer = PrintDoc.DefaultPageSettings.Margins.Left
    Dim TopMargin As Integer = PrintDoc.DefaultPageSettings.Margins.Top
    txtHeight = PrintDoc.DefaultPageSettings.PaperSize.Height - PrintDoc.DefaultPageSettings.Margins.Top - PrintDoc.DefaultPageSettings.Margins.Bottom

    Dim LinesPerPage As Integer = CInt(Math.Round(txtHeight / (fntText.Height + 0.025)))


    e.Graphics.DrawRectangle(Pens.White, e.MarginBounds)
    Dim intLineNumber As Integer
    e.Graphics.DrawString("Support", font0, Brushes.Black, 75, 50)
    For intCounter = intStart To lstLinesToPrint.Count - 1

        e.Graphics.DrawString(lstLinesToPrint(intCounter), fntText, Brushes.Black, LeftMargin, fntText.Height * intLineNumber + TopMargin)
        intLineNumber += 1
        If intLineNumber > LinesPerPage - 1 Then
            intStart = intCounter
            e.HasMorePages = True
            Exit For
        End If

    Next
End Sub    

【问题讨论】:

  • 看起来代码已经被编写为一次输出一个页面。要输出第二页,您需要再次调用该函数。
  • @RPM 这就是 e.HasMorePages = True 应该导致发生的事情。
  • 它已经做到了。但是它有一个错误,它只能工作一次。您必须将 intStart 变量移出方法,使其成为类的字段。并且您需要处理 BeginPrint 事件以将变量重置回 0。

标签: vb.net


【解决方案1】:

事实上,您的代码确实打印了不止一页...只要它具有提供它所需的其他代码。

我在表单上放了两个按钮,bnPrint 和 bnPreview,并创建了一些数据来测试:

Option Strict On

Imports System.Drawing.Printing

Public Class Form1

    Enum PrintOperation
        Print
        Preview
    End Enum

    Dim pageSetupDialog1 As PageSetupDialog
    Dim pd As PrintDocument
    Dim selectedPrinter As String

    Dim lstLinesToPrint As New List(Of String)

    Sub PrintDoc(operation As PrintOperation)

        Try
            pd = New PrintDocument()

            pageSetupDialog1 = New PageSetupDialog
            pageSetupDialog1.PageSettings = New PageSettings

            ' initialize dialog's PrinterSettings property to hold user-set printer settings.
            pageSetupDialog1.PrinterSettings = New PrinterSettings

            pageSetupDialog1.AllowMargins = True
            pageSetupDialog1.ShowNetwork = True

            If selectedPrinter <> "" Then
                pageSetupDialog1.PrinterSettings.PrinterName = selectedPrinter
            End If

            Dim result As DialogResult = pageSetupDialog1.ShowDialog()

            If result = DialogResult.OK Then
                selectedPrinter = pageSetupDialog1.PrinterSettings.PrinterName
                AddHandler pd.BeginPrint, AddressOf pd_BeginPrint
                AddHandler pd.QueryPageSettings, AddressOf pd_QueryPageSettings
                AddHandler pd.PrintPage, AddressOf pd_PrintPage

                Try
                    If operation = PrintOperation.Print Then
                        pd.Print()
                    Else
                        Using ppd As New PrintPreviewDialog
                            ppd.Document = pd
                            ppd.ShowDialog()
                        End Using
                    End If

                Catch ex As Exception
                    MsgBox("Oops: " & ex.Message)

                Finally
                    RemoveHandler pd.BeginPrint, AddressOf pd_BeginPrint
                    RemoveHandler pd.QueryPageSettings, AddressOf pd_QueryPageSettings
                    RemoveHandler pd.PrintPage, AddressOf pd_PrintPage
                End Try

            End If

        Finally
            pageSetupDialog1.Dispose()
            pd.Dispose()

        End Try

    End Sub

    Sub pd_BeginPrint(ByVal sender As Object, ByVal ev As PrintEventArgs)
        pd.PrinterSettings.PrinterName = selectedPrinter
        pd.DocumentName = "Test document"
    End Sub

    Sub pd_QueryPageSettings(ByVal sender As Object, ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs)
        ' make sure the orientation is set /before/ it gets to pd_PrintPage
        e.PageSettings.Landscape = pageSetupDialog1.PageSettings.Landscape
    End Sub

    Private Sub pd_PrintPage(sender As Object, e As Printing.PrintPageEventArgs)
        Static intStart As Integer

        Using font0 As New Font("Arial", 24, FontStyle.Underline), fntText As Font = font0

            Dim LeftMargin As Integer = pd.DefaultPageSettings.Margins.Left
            Dim TopMargin As Integer = pd.DefaultPageSettings.Margins.Top
            Dim txtHeight = pd.DefaultPageSettings.PaperSize.Height - pd.DefaultPageSettings.Margins.Top - pd.DefaultPageSettings.Margins.Bottom

            Dim LinesPerPage As Integer = CInt(Math.Round(txtHeight / (fntText.Height + 0.025)))

            e.Graphics.DrawRectangle(Pens.White, e.MarginBounds)
            Dim intLineNumber As Integer
            e.Graphics.DrawString("Support", font0, Brushes.Black, 75, 50)

            For intCounter = intStart To lstLinesToPrint.Count - 1
                e.Graphics.DrawString(lstLinesToPrint(intCounter), fntText, Brushes.Black, LeftMargin, fntText.Height * intLineNumber + TopMargin)
                intLineNumber += 1

                If intLineNumber > LinesPerPage - 1 Then
                    intStart = intCounter
                    e.HasMorePages = True
                    Exit For
                End If

            Next

        End Using


        If Not e.HasMorePages Then
            ' reset in case the user does a preview then a print etc.
            intStart = 0
        End If

    End Sub

    Private Sub bnPrint_Click(sender As Object, e As EventArgs) Handles bnPrint.Click
        PrintDoc(PrintOperation.Print)

    End Sub

    Private Sub bnPreview_Click(sender As Object, e As EventArgs) Handles bnPreview.Click
        PrintDoc(PrintOperation.Preview)

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' Create some test data...
        For i = 1 To 100
            lstLinesToPrint.Add("Line" & i)
        Next

    End Sub


End Class

我对您的代码进行了一些调整:字体需要在使用完毕后调用 .Dispose() 以释放系统资源 - 这是由 Using 构造处理的。我本可以在其中放置更多 Using 语句,但有时我使用 Try 的 finally 子句。我更改了 PrintDoc 的名称,因为这已经是我从其他程序中复制的方法的名称了。

如果您想保持以横向格式打印的可能性,请注意,如果打印横向,边距与预期的一样(左边是左边等),但宽度和高度是错误的。我没有更改显示的代码以考虑到这一点。

打印预览最后一页的示例输出:

【讨论】:

  • @DanielPelka 只是出于兴趣,代码的任何特定部分是否有帮助?
  • 不,我使用了整个代码。现在我放大我的程序(这是用于桥梁支持设计的工程计算器)并在 Form1_load 中打印整个文档,例如: lstLinesToPrint1.Add(" -wymiar pilastra b0=" + CStr(b0) + "m") lstLinesToPrint1.Add(" -wymiar Bprim=" + CStr(Bprim) + "m") 现在我的问题是,如果您在计算器中更改预览打印或打印中的任何变量(如 b0 或 Bprim),我看不到这种变化。
  • @DanielPełka 最好不要将代码直接放在 Form1_load 中(有时不会从那里引发异常),而是将它放在一个单独的 sub 中并从 Form1_load 中调用它。然后,如果需要再次运行代码,只需调用 sub 即可。
  • 在最后一句中你的意思是调用子表单1_load?
  • @DanielPełka 不,单独的子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
  • 1970-01-01
  • 2014-08-30
  • 1970-01-01
  • 2015-08-07
相关资源
最近更新 更多