【问题标题】:Printing to Multiple Pages打印到多页
【发布时间】:2014-03-18 02:51:35
【问题描述】:

下面的代码可以很好地打印图像和文本。

现在的问题是,如何在填满页面时自动将打印移到下一页。

也可以添加页码:

Public Class Form1

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    PrintPreviewDialog1.Document = PrintDocument1
    PrintPreviewDialog1.ShowDialog()
  End Sub

  Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    PrintDocument1.Print()
  End Sub

  Private Sub printDocument1_PrintPage(sender As Object, e As PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Dim rect1 As Rectangle = New Rectangle(New Point(0, 0), PictureBox1.Image.Size)
    Dim rect2 As Rectangle = New Rectangle(New Point(100, 200), PictureBox1.Image.Size)
    Dim fmt As StringFormat = New StringFormat()
    e.Graphics.DrawImage(PictureBox1.Image, rect1)
    e.Graphics.DrawString(RichTextBox1.Text, RichTextBox1.Font, New SolidBrush(Color.Red), rect2, fmt)
  End Sub

  Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    For S = 1 To 200
      RichTextBox1.AppendText("Test Line No. - " & S & vbCrLf)
    Next
  End Sub

End Class

【问题讨论】:

  • 当您认为您有更多页面时,您应该在printDocument1_PrintPage 中设置e.HasMorePages = True。您确定是否有更多页面的方式取决于您。一旦将HasMorePages 设置为true,printDocument1_PrintPage 将再次被调用。此外,您有责任跟踪页码。
  • 我是初学者,在任何地方都找不到 e.HasMorePages 或 HasMorePages;您可以发布示例代码或图片来说明您的意思吗?
  • 刚试了一下,报错,好像没有解决这个问题?

标签: vb.net winforms printing


【解决方案1】:

PrintPageEventArgs 包含一个成员 HasMorePages,您可以将其设置为 True 以在当前迭代结束时再次引发相同的事件。

要打印页码,您需要保留一个本地类变量来跟踪当前页码。然后使用e.Graphics.DrawString() 重载在页面的任何位置打印页码。

使用您自己的代码的示例:

Private mPageNumber As Integer = 1

Private Sub printDocument1_PrintPage(ByVal sender As System.Object, ByVal e As  _
             System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Dim rect1 As Rectangle = New Rectangle(New Point(0, 0), PictureBox1.Image.Size)
    Dim rect2 As Rectangle = New Rectangle(New Point(100, 200), PictureBox1.Image.Size)
    Dim fmt As StringFormat = New StringFormat()
    e.Graphics.DrawImage(PictureBox1.Image, rect1)
    e.Graphics.DrawString(RichTextBox1.Text, RichTextBox1.Font, New SolidBrush(Color.Red), rect2, fmt)

    Using f as New Font("Arial" , 10)
        e.Graphics.DrawString(mPageNumber.ToString(), , Brushes.Black, 0, 0) 'Page number at top-left of the page
    End Using

    mPageNumber += 1        


    e.HasMorePages = (mPageNumber <= 10) 'Will keep printing till 10 pages are printed
 End Sub

转到下一页完全取决于您要如何计算下一页。具体来说,您需要以自己的字体打印每个字符(因为它是RichTextBox),然后还要处理段落等。好像这还不够,您可能需要处理双向文本、文本换行、对齐等等。欢迎来到印刷世界!!

我不会在这里编写确切的代码,但会给您一些提示,以便您开始您的旅程。 RichTextBox 有一个名为 GetPositionFromCharIndex() 的方法,它为您提供指定字符索引的 x、y 坐标。您可以使用循环来确定 PrintPage 事件处理程序中 Y 坐标小于或等于 e.MarginBounds.Height 的最后一个字符,然后将所有单词发送到该索引到 DrawString() 函数。您应该保留一个类级别变量来跟踪您在当前页面上打印的最后一个字符,然后在下一次迭代中从该点开始。您可以使用DrawString() 重载,将布局矩形作为参数并将e.MarginBounds 发送给它,让它自动为您自动换行。

请记住,这仅适用于所有文本都使用单一字体的 RichTextBox,考虑到 RichTextBox 的目的,这不太可能。对于有多种字体的情况,您需要为包含单个字体的每个字符范围多次调用DrawString()。正如我所说,这有很多细节(例如字体字距调整、悬挂边缘和其他问题)在这里无法涵盖。继续阅读,您会在 SO 和其他地方找到很多好东西。

【讨论】:

  • 感谢 dotNET;我使用了您的代码并遇到了 2 个问题: 1- 将 (e.Graphics.DrawString(mPageNumber.ToString(), 0, 0) 'Page number at the top-left of the page) 标记为错误; 2-它只打印 10 份第一页。
  • 我解决了第一个问题。然而,第二个更复杂。请参阅上面的编辑。
  • 感谢 dotNET 的尝试,但我仍然遇到与第一次完全相同的 2 个错误。
  • @Abbas1999:添加了更多细节
猜你喜欢
  • 1970-01-01
  • 2018-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 2019-06-09
  • 2015-08-07
相关资源
最近更新 更多