You are on page 1of 5

Printing and Reports

Printing
For desktop apps, printing is very similar to drawing to the screen. But instead of drawing into a Graphics
object of a Canvas control, you draw to a Graphics object created specifically for printing. There are methods
available to allow you to create new pages and get printer settings.
For web apps, printing is far more limited. Usually what works best is to simply create HTML, display it in an
HTML Viewer control and then print that.

Desktop Printing
Printer Settings
Before printing anything, you usually want to give the user the ability to select the printer they want to use.
This is done using the PrinterSetup class, which displays the Page Setup dialog for the operating system. In
addition, this class returns the settings so that you can use them again later without prompting the user.

' mPrinterSettings is a String property on the Window


Dim ps As New PrinterSetup
ps.SetupString = mPrinterSettings

If ps.PageSetupDialog Then
mPrinterSettings = ps.SetupString
End If

Since mPrinterSettings is a String, you can save it outside of your app (such as in a database or a file) for use
the next time the user prints.
The PrinterSetup class has properties for printer settings such as landscape, page size and resolution. The
Reference Guide topic for PrinterSetup has more details on these properties.

PrinterSetup is not supported in Linux apps.

Printing Text and Graphics


To print text and graphics you simply draw to the Graphics object for the printer. To get this Graphics objects,
you call either the OpenPrinterDialog or OpenPrinter global methods. The only difference between these two
methods is that one displays the Print dialog and the other does not. Since the printing system on macOS has
the automatic capability to print to PDF, you can use this method to easily generate PDF files. On Windows
you can install a "Print to PDF" printer driver to enable sending printed output to PDF files.
Since you are drawing to a Graphics object, all the commands that you learned about in the Graphics and
Multimedia section can be used.
In addition, you also use the printing-specific method, NextPage to create multiple pages. This example prints
“Hello” on page 1 and “World” on page 2:

Dim ps As New PrinterSetup


If ps.PageSetupDialog Then
Dim page As Graphics
page = OpenPrinterDialog(ps)
If page <> Nil Then
' Draw text on page 1 with 1 inch left/top margin
page.DrawString("Hello", ps.HorizontalResolution, ps.VerticalResolution)
page.NextPage

1
Printing and Reports

' Draw text on page 2 with 1 inch left/top margin


page.DrawString("World", ps.HorizontalResolution, ps.VerticalResolution)
End If
End If

You can also use any printer settings that were previously stored from using the PrinterSetup class.

Dim ps As New PrinterSetup


ps.SetupString = mPrinterSettings ' Property containing previously saved settings

If ps.PageSetupDialog Then
mPrinterSettings = ps.SetupString ' Get new settings
Dim page As Graphics
' Use Printer Settings
page = OpenPrinterDialog(ps)
If page <> Nil Then
' Draw text on page 1 with 1 inch left/top margin
page.DrawString("Hello", ps.HorizontalResolution, ps.VerticalResolution)
page.NextPage
' Draw text on page 2 with 1 inch left/top margin
page.DrawString("World", ps.HorizontalResolution, ps.VerticalResolution)
End If
End If

Each time you call NextPage, the current page is sent to the printer and the graphics object (in this case page)
is cleared so that you can immediately begin drawing the new content. The final page gets sent to the printer
when the page goes out of scope.
To print without displaying the Printer dialog, you just call the OpenPrinter method:

Dim ps As New PrinterSetup


Dim page As Graphics
page = OpenPrinter(ps)
If page <> Nil Then
' Draw text on page 1 with 1 inch left/top margin
page.DrawString("Hello", ps.HorizontalResolution, ps.VerticalResolution)
page.NextPage
' Draw text on page 2 with 1 inch left/top margin
page.DrawString("World", ps.HorizontalResolution, ps.VerticalResolution)
page.NextPage
End If

Printing Multiple Pages of Text


To print multiple pages, you need to parse each line and print it if it will fit on the page. If it will not fit, then
you call NextPage so that your text will start printing at the top of the next page.
A common thing to do is to split the text into paragraphs and then track the height of the page and the height
of the next paragraph to print to make sure that it will fit onto the page. If it will not fit, then the current page
is sent to the printer and a new page is created to start printing the next paragraph.
This code shows you how you can print text from a TextArea onto multiple pages:

Dim ps As New PrinterSetup


If ps.PageSetupDialog Then
Dim page As Graphics
page = OpenPrinterDialog(ps)
If page <> Nil Then
' Draw text on page 1 with 1 inch left/top margin
Dim leftMargin As Double = ps.HorizontalResolution
Dim topMargin As Double = ps.VerticalResolution
page.TextSize = Val(FontPopup.Text)
' To print multiple pages, you need to parse each line and print it
' if it will fit on the page. If it will not fit, then
' you call NextPage so that your text will start printing at the top

2
Printing and Reports

' of the next page.


' First, split the text into multiple paragraphs
Dim paragraphs() As String = ReplaceLineEndings(TextArea1.Text,
EndOfLine).Split(EndOfLine)
Dim pageTextHeight As Double = topMargin
Dim newpageTextHeight As Double
Dim lineWidth As Double
For i As Integer = 0 To paragraphs.Ubound
newpageTextHeight = pageTextHeight + page.StringHeight(paragraphs(i), ps.Width -
leftMargin * 2)
If newPageTextHeight > ps.Height - topMargin * 2 Then
' String does not fit on page, so move to next page
page.NextPage
pageTextHeight = topMargin
newpageTextHeight = pageTextHeight + page.StringHeight(paragraphs(i), ps.Width -
leftMargin * 2)
End If
' If string fits on page, then draw it
page.DrawString(paragraphs(i), leftMargin, pageTextHeight, ps.Width - leftMargin *
2)
' Keep a cumulative count of the pageheight as strings are added to it
pageTextHeight = newpageTextHeight ' Adjust page text height
pageTextHeight = pageTextHeight + topMargin / 8 ' 1/8 inch between paragraphs
Next
End If
End If

The above code gives you a lot of control, but it is more work to track everything yourself. In the next section
you'll see how you can take advantage of StyledTextPrinter to make this easier. In addition, using a Report.

Printing Styled Text


Because TextAreas are capable of displaying styled text and multiple font sizes, you will usually want to retain
the styled text when you print. The StyledTextPrinter class is used for this purpose, using the DrawBlock
method.

The StyledTextPrinter class only works with MacOS apps.

To print styled text, you first create a StyledTextPrinter object and then call the StyledTextPrinter method of
the TextArea (specifying the graphics to use and the width of the text) to get an instance of a
StyledTextPrinter that can be used for printing.
With this instance, you can call the DrawBlock method to draw the styled text to the page (specifying the
starting coordinates and the height).
This example prints styled text in a TextArea:

Dim stp As StyledTextPrinter


Dim g As Graphics
Dim p As New PrinterSetup

If p.PageSetupDialog Then
g = OpenPrinterDialog(p)
If g <> Nil Then
' Set width as 7.5 inches
stp = PrintTextArea.StyledTextPrinter(g, 7.5 * p.HorizontalResolution)
Do Until stp.EOF
' Fill the page with text
' at 10 inches height
stp.DrawBlock(0, 0, 10 * p.VerticalResolution)
If Not stp.EOF Then
' There is more text, so add a page
g.NextPage
End If
Loop
End If

3
Printing and Reports

End If

In order to support styled printing, the Text Area must have both its Multiline and Styled
properties ON (True).

If the text to print is larger than what will fit in the specified block, then you can iterate through the text until
it is all printed. You do this by checking the EOF property of the StyledTextPrinter class after each call to
DrawBlock.
This example prints the contents of a Text Area into two columns with a quarter inch spacing between the
columns:

Dim g As Graphics
Dim p As New PrinterSetup

If p.PageSetupDialog Then
g = OpenPrinterDialog(p)
' 1 inch margin
Dim leftRightMargin As Double = 1 * p.HorizontalResolution
Dim topBottomMargin As Double = 1 * p.VerticalResolution
' Page width after accounting for margins
Dim pageWidth As Double = p.Width - (leftRightMargin * 2)
' Column gap is 1/4 of the margin (so, 1/4 inch)
Dim columnGap As Double = leftRightMargin / 4
' Calculate the column width
' Subtract column gap from page with and
' split result 2
Dim columnWidth As Double = (pageWidth - columnGap) / 2
' Page size after accounting for margins
Dim pageHeight As Double = p.Height - (topBottomMargin * 2)
Dim stp As StyledTextPrinter
stp = PrintTextArea.StyledTextPrinter(g, pageWidth)
stp.Width = columnWidth
Dim columnToPrint As Integer = 1
Do Until stp.EOF
stp.DrawBlock(leftRightMargin + (columnWidth + columnGap) * (columnToPrint - 1), _
topBottomMargin, pageHeight)
If columnToPrint = 2 Then ' printing last column
If Not stp.EOF Then ' more text to print
g.NextPage
columnToPrint = 1
End If
Else ' more columns to print on this page
columnToPrint = columnToPrint + 1
End If
Loop
End If

HTML Printing
Another technique you can use is to create what you want to print using HTML, display it in an HTMLViewer
and then call its print method. This can sometimes be useful for simple reports. As a simple example, this
code loads an HTMLViewer with some HTML:

Dim html As String = "<html><body><em>Hello</em>, World!</body></html>"


HTMLViewer1.LoadPage(html, GetTemporaryFolderItem)

This code then displays the print dialog for the user to print the HTML:

HTMLViewer1.Print(True)

4
Printing and Reports

Example Projects
These example projects demonstrate desktop printing:
Printing and Reporting/Printing/GraphicsPrintingExample

Printing and Reporting/Printing/Labels

Printing and Reporting/Printing/Printing To Screen or Printer

Printing and Reporting/Printing/PrintingGraphics

Printing and Reporting/Printing/PrintingText

Printing and Reporting/StyledTextPrinterExample

Web Printing
Web printing is considerably simpler than desktop printing because it is much more restricted. Your web
application runs in a web browser, so you are limited by what a web browser can print.
Web browsers generally do a good job of printing HTML, so in order to generate something to print, you want
to first render it as HTML (either to a string or a file) and use an HTML Viewer control to display the HTML.
Once you have what you want displayed in an HTML Viewer, you can have a button that calls the Print method
of the HTML Viewer to ask the browser to print its contents:

HTMLViewer1.Print

You might also like