# Printing

> Print from Windows Forms code with a PrintDocument: page ranges, copies, several files in one job, background printing, MailMerge.Print and FormattingPrinter.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > Document Processing > Printing
- **3981 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/printing/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/printing/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/printing/llms-full.txt

---

Printing from code means printing without asking the user each time: a delivery note after an order is saved, a stack of merged letters, all documents of a folder. TX Text Control prints through the `PrintDocument` class of .NET, both from the `TextControl` on your form and from a `ServerTextControl` that never shows the document. You choose the printer, the pages and the copies, combine several documents into one print job, print mail merge results and pick the printer whose measurements format the document.

The print dialog, the print preview and printing a single page from the editor are covered in [Print a Document](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/document-processing/print/llms-full.txt) and [Printing and Print Preview](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/printing/llms-full.txt). The examples here are handlers in *Form1.cs* with the `TextControl` named `textControl1`; *Form1.cs* needs these `using` directives:

```csharp
using System;
using System.Drawing.Printing;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using TXTextControl;
```

### How Printing Works

Three classes print, all with a `System.Drawing.Printing.PrintDocument`:

| Member | Prints |
|---|---|
| [TextControl.Print](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/print-method/llms-full.txt) | The document in the editor; with a document name, after the user confirmed the print dialog |
| [ServerTextControl.Print](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/print-method/llms-full.txt) | A document your code loaded or created, without showing it and without a dialog |
| [MailMerge.Print](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/print-method/llms-full.txt) | The document a mail merge created |

All three use these settings of the `PrintDocument`: `DocumentName`, `PrintController`, `DefaultPageSettings.Color` and, in `PrinterSettings`, `PrinterName`, `FromPage`, `ToPage`, `Copies`, `Collate`, `PrintToFile` and `PrintRange`. `FromPage` and `ToPage` take effect only when `PrintRange` is `PrintRange.SomePages`, and without a `PrinterName`, the default printer prints. The overloads of `TextControl.Print` are listed in [The Print Methods](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/printing/#the-print-methods).

Before printing the editor's document, check [CanPrint](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/canprint-property/llms-full.txt): a protected document can forbid printing.

### Print Pages, Copies and Collated Sets

The following handler prints two collated copies of the pages the user enters in two `NumericUpDown` controls, on the printer the user selected in a `ComboBox`:

```csharp
private void printPagesButton_Click(object sender, EventArgs e)
{
    if (!textControl1.CanPrint)
    {
        return;
    }

    PrintDocument printDocument = new PrintDocument();
    printDocument.DocumentName = "Quarterly Report";
    printDocument.PrinterSettings.PrinterName = printerComboBox.Text;

    // FromPage and ToPage are only used with PrintRange.SomePages
    printDocument.PrinterSettings.PrintRange = PrintRange.SomePages;
    printDocument.PrinterSettings.FromPage = (int)fromPageBox.Value;
    printDocument.PrinterSettings.ToPage = Math.Min((int)toPageBox.Value, textControl1.Pages);
    printDocument.PrinterSettings.Copies = 2;
    printDocument.PrinterSettings.Collate = true;

    // No "Printing page n" status dialog
    printDocument.PrintController = new StandardPrintController();

    textControl1.Print(printDocument);
}

private void Form1_Load(object sender, EventArgs e)
{
    // The names of the installed printers
    foreach (string printer in PrinterSettings.InstalledPrinters)
    {
        printerComboBox.Items.Add(printer);
    }

    printerComboBox.Text = new PrinterSettings().PrinterName;
}
```

The code works as follows:

- `PrinterSettings.InstalledPrinters` lists the printers of the machine, and a new `PrinterSettings` object names the default printer.
- [Pages](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/pages-property/llms-full.txt) is the number of pages, which limits the range.
- A `StandardPrintController` prints without the status dialog that .NET shows by default.

`PrintToFile` together with `PrintFileName` sends the output to a file, for example with the printer **Microsoft Print to PDF**. To create a PDF file, saving the document as PDF is the direct way, as [Saving and Converting Documents](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/saving-converting/llms-full.txt) describes.

### Print Several Documents in One Print Job

The second overload of `ServerTextControl.Print`, `Print(int page, PrintPageEventArgs e)`, prints one page into the page that .NET is printing. Called from the `PrintPage` event of a `PrintDocument`, it combines several documents into one print job, so that they come out of the printer together. The following handler prints a letter and an invoice with a `ServerTextControl`, page by page:

```csharp
private void printBatchButton_Click(object sender, EventArgs e)
{
    string[] files = { "letter.docx", "invoice.docx" };

    using (ServerTextControl tx = new ServerTextControl())
    {
        tx.Create();

        int fileIndex = 0;
        int pageNumber = 1;
        tx.Load(files[fileIndex], StreamType.WordprocessingML);

        PrintDocument printDocument = new PrintDocument();
        printDocument.DocumentName = "Letter and invoice";
        printDocument.PrintController = new StandardPrintController();

        printDocument.PrintPage += (s, args) =>
        {
            tx.Print(pageNumber, args);
            pageNumber++;

            // All pages of this document are printed: load the next one
            if (pageNumber > tx.Pages)
            {
                fileIndex++;

                if (fileIndex < files.Length)
                {
                    tx.Load(files[fileIndex], StreamType.WordprocessingML);
                    pageNumber = 1;
                }
            }

            args.HasMorePages = fileIndex < files.Length;
        };

        printDocument.Print();
    }
}
```

The code works as follows:

- The [ServerTextControl](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/llms-full.txt) is created with [Create](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/create-method/llms-full.txt) before any other member is used, and the `using` block disposes it after printing. The editor on the form keeps its document.
- `printDocument.Print()` starts the job, and .NET raises `PrintPage` for each page. [ServerTextControl.Pages](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/pages-property/llms-full.txt) tells when the last page of a document is reached.
- `HasMorePages` tells .NET whether another page follows.

A `PrintPage` handler can also draw its own content with `args.Graphics` before it calls `Print`, which prints the page on top of it, for example over a form background. [Print Pages From Your Own PrintDocument](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/printing/#print-pages-from-your-own-printdocument) explains the overload with the page of the editor.

### Print Without Blocking the Form

Printing a long document takes time, and while `Print` runs, the form doesn't respond. A `ServerTextControl` can print on another thread, because it doesn't belong to the form:

```csharp
private async void printInBackgroundButton_Click(object sender, EventArgs e)
{
    printInBackgroundButton.Enabled = false;

    await Task.Run(() =>
    {
        using (ServerTextControl tx = new ServerTextControl())
        {
            tx.Create();
            tx.Load("report.docx", StreamType.WordprocessingML);

            PrintDocument printDocument = new PrintDocument();
            printDocument.DocumentName = "report.docx";
            printDocument.PrintController = new StandardPrintController();

            tx.Print(printDocument);
        }
    });

    // Back on the UI thread
    printInBackgroundButton.Enabled = true;
}
```

The `TextControl` itself belongs to the UI thread and must not be used inside `Task.Run`. To print the document of the editor in the background, save it to a byte array first and load the array into the `ServerTextControl`, as [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/servertextcontrol/llms-full.txt) shows.

### Print a Merged Document

[MailMerge](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/llms-full.txt) merges a template with data into the document of the text component it is connected to. Its `Print` method prints the result, with a `PrintDocument` or with a document name, a printer name, a number of copies and a collate flag:

```csharp
private void printLettersButton_Click(object sender, EventArgs e)
{
    string jsonData = File.ReadAllText("customers.json");

    using (ServerTextControl tx = new ServerTextControl())
    {
        tx.Create();

        TXTextControl.DocumentServer.MailMerge mailMerge = new TXTextControl.DocumentServer.MailMerge();
        mailMerge.TextComponent = tx;

        mailMerge.LoadTemplate("letter-template.docx", TXTextControl.DocumentServer.FileFormat.WordprocessingML);
        mailMerge.MergeJsonData(jsonData);

        // Document name, printer name, copies, collate
        mailMerge.Print("Customer letters", "Microsoft Print to PDF", 1, false);
    }
}
```

[TextComponent](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/textcomponent-property/llms-full.txt) connects the `MailMerge` with the `ServerTextControl`, [LoadTemplate](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/loadtemplate-method/llms-full.txt) loads the template and [MergeJsonData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver/mailmerge/mergejsondata-method/llms-full.txt) merges it with the JSON data. [Mail Merge and Reporting](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/mail-merge/llms-full.txt) describes templates and data.

### Choose the Formatting Printer

TX Text Control formats text with the measurements of a device, so that line and page breaks on the screen match those on paper. [FormattingPrinter](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/formattingprinter-property/llms-full.txt) names the printer whose measurements are used:

| Value | Formats with |
|---|---|
| The name of a printer | The measurements of that printer; if it isn't installed, the standard printer |
| `"Standard"` | The standard printer of the system |
| `"Display"` | The font measurements of the display device |

A document printed on its formatting printer has the same breaks as on the screen, and the paper sizes the editor offers depend on it, as [Print Exactly What the Screen Shows](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/printing/#print-exactly-what-the-screen-shows) shows. [ServerTextControl.FormattingPrinter](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/formattingprinter-property/llms-full.txt) does the same for a `ServerTextControl`; give both the same value when a document goes from one to the other. A printer that responds late, such as a network printer in energy-saving mode, can delay the initialization of TX Text Control, as the blog article [Initialize Text Control Without a Printer (Completely)](https://www.textcontrol.com/blog/2022/02/28/initialize-text-control-without-a-printer-completely/) explains.

### Next Steps

- [Printing and Print Preview](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/printing/llms-full.txt): the print dialog and preview of the editor.
- [Printing](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/troubleshooting/printing/llms-full.txt) in Troubleshooting: when the printout differs from the screen.
- [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/servertextcontrol/llms-full.txt): work in the background.
- [Sections, Pages, Headers, and Footers](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/sections-headers/llms-full.txt): pages and page numbers.

---

## Nearby

- **Previous:** [XML Processing](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/xml/llms-full.txt)
- **Next:** [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/servertextcontrol/llms-full.txt)
