Print PDF files in C# and VB.NET

With GemBox.Pdf you can do a silent printing or provide a print dialog and print preview as shown in examples for printing in WPF and printing in Windows Forms.

You can print PDF documents to default printer or specify any other local or networked printer that's connected to your machine.

Printing PDF files is currently supported on .NET Framework (and in future on .NET Core for Windows).

The following example demonstrates how to silently, without the user's interaction, print PDF files in C# and VB.NET.

Screenshot of printed PDF document with 'Microsoft Print to Pdf'
Printed PDF document with virtual printer in C# and VB.NET
using GemBox.Pdf;

class Program
{
    static void Main()
    {
        // If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");

        using (PdfDocument document = PdfDocument.Load("%#Print.pdf%"))
        {
            // Print PDF document to default printer (e.g. 'Microsoft Print to Pdf').
            string printerName = null;
            document.Print(printerName);
        }
    }
}
Imports GemBox.Pdf

Module Program

    Sub Main()

        ' If using Professional version, put your serial key below.
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")

        Using document As PdfDocument = PdfDocument.Load("%#Print.pdf%")
            ' Print PDF document to default printer (e.g. 'Microsoft Print to Pdf').
            Dim printerName As String = Nothing
            document.Print(printerName)
        End Using

    End Sub
End Module

GemBox.Pdf uses System.Printing namespace for managing print queues and print jobs. To leverage advance printing capabilities, like specifying printer's paper source (tray), specifying two-sided (duplex) printing, etc. you can use PrintTicket class.

You would create PrintTicket object and define or configure desired printer's features with it. You would provide that configuration in a form of an XML stream (by calling PrintTicket.GetXmlStream method) to GemBox.Pdf's PrintOptions.

Print PDF documents in WPF application

Commonly, in WPF applications you would use PrintDialog to enable users to select a printer, configure it, and perform a print job. For example, your user may specify to print only certain pages of Word document, or to print multiple pages on one sheet of paper, or something else.

The following example demonstrates how you can use PrintDialog to define GemBox.Pdf's print options. Also, the example shows how you can use DocumentViewer control for print previewing.

Screenshot of printing PDF document in WPF
Printing PDF document from WPF application
<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Printing in WPF application" Height="450" Width="800">
    <DockPanel>
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="5">
            <Button x:Name="LoadFileBtn" Content="Load" Width="100" Margin="5,0" Click="LoadFileBtn_Click"/>
            <Button x:Name="PrintFileBtn" Content="Print" Width="100" Margin="5,0" Click="PrintFileBtn_Click"/>
        </StackPanel>
        <DocumentViewer x:Name="DocViewer"/>
    </DockPanel>
</Window>
using System.Windows;
using System.Windows.Controls;
using System.Windows.Xps.Packaging;
using GemBox.Pdf;
using Microsoft.Win32;

public partial class MainWindow : Window
{
    private PdfDocument document;

    public MainWindow()
    {
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        InitializeComponent();
    }

    private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        if (this.document != null)
            this.document.Close();
    }

    private void LoadFileBtn_Click(object sender, RoutedEventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter =
            "PDF files (*.pdf)|*.pdf";

        if (openFileDialog.ShowDialog() == true)
        {
            if (this.document != null)
                this.document.Close();

            this.document = PdfDocument.Load(openFileDialog.FileName);
            this.ShowPrintPreview();
        }
    }

    private void PrintFileBtn_Click(object sender, RoutedEventArgs e)
    {
        if (this.document == null)
            return;

        PrintDialog printDialog = new PrintDialog() { UserPageRangeEnabled = true };
        if (printDialog.ShowDialog() == true)
        {
            PrintOptions printOptions = new PrintOptions(printDialog.PrintTicket.GetXmlStream());

            printOptions.FromPage = printDialog.PageRange.PageFrom - 1;
            printOptions.ToPage = printDialog.PageRange.PageTo == 0 ? int.MaxValue : printDialog.PageRange.PageTo - 1;

            this.document.Print(printDialog.PrintQueue.FullName, printOptions);
        }
    }

    private void ShowPrintPreview()
    {
        XpsDocument xpsDocument = this.document.ConvertToXpsDocument(SaveOptions.Xps);

        // Note, XpsDocument must stay referenced so that DocumentViewer can access additional resources from it.
        // Otherwise, GC will collect/dispose XpsDocument and DocumentViewer will no longer work.
        this.DocViewer.Tag = xpsDocument;
        this.DocViewer.Document = xpsDocument.GetFixedDocumentSequence();
    }
}
Imports System.Windows.Xps.Packaging
Imports GemBox.Pdf
Imports Microsoft.Win32

Partial Public Class MainWindow
    Inherits Window

    Dim document As PdfDocument

    Public Sub New()
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        InitializeComponent()
    End Sub

    Private Sub Window_Closing(sender As Object, e As ComponentModel.CancelEventArgs)
        If Me.document IsNot Nothing Then
            Me.document.Close()
        End If
    End Sub

    Private Sub LoadFileBtn_Click(sender As Object, e As RoutedEventArgs)

        Dim openFileDialog As New OpenFileDialog()
        openFileDialog.Filter =
            "PDF files (*.pdf)|*.pdf"

        If (openFileDialog.ShowDialog() = True) Then
            If Me.document IsNot Nothing Then
                Me.document.Close()
            End If

            Me.document = PdfDocument.Load(openFileDialog.FileName)
            Me.ShowPrintPreview()
        End If

    End Sub

    Private Sub PrintFileBtn_Click(sender As Object, e As RoutedEventArgs)

        If document Is Nothing Then Return

        Dim printDialog As New PrintDialog() With {.UserPageRangeEnabled = True}
        If (printDialog.ShowDialog() = True) Then

            Dim printOptions As New PrintOptions(printDialog.PrintTicket.GetXmlStream())

            printOptions.FromPage = printDialog.PageRange.PageFrom - 1
            printOptions.ToPage = If(printDialog.PageRange.PageTo = 0, Integer.MaxValue, printDialog.PageRange.PageTo - 1)

            Me.document.Print(printDialog.PrintQueue.FullName, printOptions)
        End If

    End Sub

    Private Sub ShowPrintPreview()

        Dim xpsDocument As XpsDocument = document.ConvertToXpsDocument(SaveOptions.Xps)

        ' Note, XpsDocument must stay referenced so that DocumentViewer can access additional resources from it.
        ' Otherwise, GC will collect/dispose XpsDocument and DocumentViewer will no longer work.
        Me.DocViewer.Tag = xpsDocument
        Me.DocViewer.Document = xpsDocument.GetFixedDocumentSequence()

    End Sub

End Class

Print PDF documents in Windows Forms application

You can use the same DocumentViewer WPF control from the above example, to create a print preview in the Windows Forms application as well. You can accomplish this by hosting the WPF control inside the ElementHost Windows Forms control.

Or as an alternative, you can use PrintPreviewControl and preview the Word document by providing the PrintDocument object to the control. The following example demonstrates how to you can render document's pages as images and draw does images on PrintDocument.PrintPage event for print previewing.

Screenshot of printing PDF document in Windows Forms
Printing PDF document from Windows Forms application
using System;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using GemBox.Pdf;

public partial class Form1 : Form
{
    private PdfDocument document;

    public Form1()
    {
        ComponentInfo.SetLicense("FREE-LIMITED-KEY");
        InitializeComponent();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (this.document != null)
            this.document.Close();
    }

    private void LoadFileMenuItem_Click(object sender, EventArgs e)
    {
        OpenFileDialog openFileDialog = new OpenFileDialog();
        openFileDialog.Filter =
            "PDF files (*.pdf)|*.pdf";

        if (openFileDialog.ShowDialog() == DialogResult.OK)
        {
            if (this.document != null)
                this.document.Close();

            this.document = PdfDocument.Load(openFileDialog.FileName);
            this.ShowPrintPreview();
        }
    }

    private void PrintFileMenuItem_Click(object sender, EventArgs e)
    {
        if (this.document == null)
            return;

        PrintDialog printDialog = new PrintDialog() { AllowSomePages = true };
        if (printDialog.ShowDialog() == DialogResult.OK)
        {
            PrinterSettings printerSettings = printDialog.PrinterSettings;
            PrintOptions printOptions = new PrintOptions();

            // Set PrintOptions properties based on PrinterSettings properties.
            printOptions.CopyCount = printerSettings.Copies;
            printOptions.FromPage = printerSettings.FromPage - 1;
            printOptions.ToPage = printerSettings.ToPage == 0 ? int.MaxValue : printerSettings.ToPage - 1;

            this.document.Print(printerSettings.PrinterName, printOptions);
        }
    }

    private void ShowPrintPreview()
    {
        // Create image for each Word document's page.
        Image[] images = this.CreatePrintPreviewImages();
        int imageIndex = 0;

        // Draw each page's image on PrintDocument for print preview.
        var printDocument = new PrintDocument();
        printDocument.PrintPage += (sender, e) =>
        {
            using (Image image = images[imageIndex])
            {
                var graphics = e.Graphics;
                var region = graphics.VisibleClipBounds;

                // Rotate image if it has landscape orientation.
                if (image.Width > image.Height)
                    image.RotateFlip(RotateFlipType.Rotate270FlipNone);

                graphics.DrawImage(image, 0, 0, region.Width, region.Height);
            }

            ++imageIndex;
            e.HasMorePages = imageIndex < images.Length;
        };

        this.PageUpDown.Value = 1;
        this.PageUpDown.Maximum = images.Length;
        this.PrintPreviewControl.Document = printDocument;
    }

    private Image[] CreatePrintPreviewImages()
    {
        int pageCount = this.document.Pages.Count;
        var images = new Image[pageCount];

        for (int pageIndex = 0; pageIndex < pageCount; ++pageIndex)
        {
            var imageStream = new MemoryStream();
            var imageOptions = new ImageSaveOptions(ImageSaveFormat.Png) { PageNumber = pageIndex };

            this.document.Save(imageStream, imageOptions);
            images[pageIndex] = Image.FromStream(imageStream);
        }

        return images;
    }

    private void PageUpDown_ValueChanged(object sender, EventArgs e)
    {
        this.PrintPreviewControl.StartPage = (int)this.PageUpDown.Value - 1;
    }
}
Imports System.Drawing.Printing
Imports System.IO
Imports GemBox.Pdf

Partial Public Class Form1
    Inherits Form

    Dim document As PdfDocument

    Public Sub New()
        ComponentInfo.SetLicense("FREE-LIMITED-KEY")
        InitializeComponent()
    End Sub

    Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        If Me.document IsNot Nothing Then
            Me.document.Close()
        End If
    End Sub

    Private Sub LoadFileMenuItem_Click(sender As Object, e As EventArgs) Handles LoadFileMenuItem.Click

        Dim openFileDialog As New OpenFileDialog()
        openFileDialog.Filter =
            "PDF files (*.pdf)|*.pdf"

        If (openFileDialog.ShowDialog() = DialogResult.OK) Then
            If Me.document IsNot Nothing Then
                Me.document.Close()
            End If

            Me.document = PdfDocument.Load(openFileDialog.FileName)
            Me.ShowPrintPreview()
        End If

    End Sub

    Private Sub PrintFileMenuItem_Click(sender As Object, e As EventArgs) Handles PrintFileMenuItem.Click

        If document Is Nothing Then Return

        Dim printDialog As New PrintDialog() With {.AllowSomePages = True}
        If (printDialog.ShowDialog() = DialogResult.OK) Then

            Dim printerSettings As PrinterSettings = printDialog.PrinterSettings
            Dim printOptions As New PrintOptions()

            ' Set PrintOptions properties based on PrinterSettings properties.
            printOptions.CopyCount = printerSettings.Copies
            printOptions.FromPage = printerSettings.FromPage - 1
            printOptions.ToPage = If(printerSettings.ToPage = 0, Integer.MaxValue, printerSettings.ToPage - 1)

            Me.document.Print(printerSettings.PrinterName, printOptions)
        End If

    End Sub

    Private Sub ShowPrintPreview()

        ' Create image for each Word document's page.
        Dim images As Image() = Me.CreatePrintPreviewImages()
        Dim imageIndex As Integer = 0

        ' Draw each page's image on PrintDocument for print preview.
        Dim printDocument = New PrintDocument()
        AddHandler printDocument.PrintPage,
            Sub(sender, e)
                Using image As Image = images(imageIndex)
                    Dim graphics = e.Graphics
                    Dim region = graphics.VisibleClipBounds

                    ' Rotate image if it has landscape orientation.
                    If image.Width > image.Height Then image.RotateFlip(RotateFlipType.Rotate270FlipNone)

                    graphics.DrawImage(image, 0, 0, region.Width, region.Height)
                End Using

                imageIndex += 1
                e.HasMorePages = imageIndex < images.Length
            End Sub

        Me.PageUpDown.Value = 1
        Me.PageUpDown.Maximum = images.Length
        Me.printPreviewControl.Document = printDocument

    End Sub

    Private Function CreatePrintPreviewImages() As Image()

        Dim pageCount As Integer = Me.document.Pages.Count
        Dim images = New Image(pageCount - 1) {}

        For pageIndex As Integer = 0 To pageCount - 1
            Dim imageStream = New MemoryStream()
            Dim imageOptions = New ImageSaveOptions(ImageSaveFormat.Png) With {.PageNumber = pageIndex}

            Me.document.Save(imageStream, imageOptions)
            images(pageIndex) = Image.FromStream(imageStream)
        Next

        Return images

    End Function

    Private Sub PageUpDown_ValueChanged(sender As Object, e As EventArgs) Handles PageUpDown.ValueChanged
        Me.printPreviewControl.StartPage = Me.PageUpDown.Value - 1
    End Sub

End Class

Check next example or download examples from GitHub.