vb.net 打印到多页

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22469493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 17:08:19  来源:igfitidea点击:

Printing to Multiple Pages

vb.netwinformsprinting

提问by Abbas1999

The code below that can nicely print image and text.

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

The problem now is, how can I automatically move printing to next page when a page is filled.

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

Will be nice to add a page number, too:

添加页码也很好:

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

回答by dotNET

PrintPageEventArgscontains a member HasMorePagesthat you can set to True to raise the same event again at the end of current iteration.

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

To print page numbers, you'll need to keep a local class variable to track current page number. Then use an e.Graphics.DrawString()overload to print page numbers anywhere on the page.

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

An example using your own code:

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

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

Going to next page is entirely dependent upon how you want to compute next page. Specifically, you'll need to print each character in its own font (since it is a RichTextBox) and then take care of paragraphs etc. as well. And as if that were not enough, you may need to tackle bidirectional text, text wrapping, alignment and what not too. Welcome to the world of printing!!

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

I won't be writing the exact code here, but will give you some hints so you could start your journey. RichTextBoxhas a method named GetPositionFromCharIndex()that gives you the x,y coordinates of the specified character index. You could use a loop to determine the last character whose Y-coordinate is less than or equal to e.MarginBounds.Heightin your PrintPageevent handler and then send all words upto that index to DrawString()function. You should keep a class level variable to track the last character upto which you have printed on the current page and then start from that point forward in the next iteration. You could use DrawString()overload that takes layout rectangle as parameter and send e.MarginBoundsto it to let it automatically do word-wrapping for you.

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

Remember that this will only work with RichTextBox that has a single font used for all its text, which is highly unlikely given the very purpose of RichTextBox. For situations where you have multiple fonts, you'll need to call DrawString()many times for each character range comprising of a single font. As I said, this has lots of details (such as font kerning, hanging edges and other devils) that cannot be covered here. Keep reading and you'll find lots of good stuff on SO and other places.

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