# Printing

> Print documents from ServerTextControl on Windows with a PrintDocument: printers, page ranges, copies, batch print jobs, MailMerge.Print and FormattingPrinter.

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

---

A service that prints delivery notes or merged letters sends documents to a printer without any user interface. `ServerTextControl` prints through the `PrintDocument` class of .NET, with the printer, page range and number of copies you choose, and it prints several documents in one print job. For web applications, a PDF that users print in the browser is often the better way.

Printing in the browser is described in [Printing](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/printing/llms-full.txt) in the Document Viewer section and in [Viewing and Printing](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-editor/viewing-printing/#print-the-document) in the Document Editor section.

### Requirements

[ServerTextControl.Print](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/print-method/llms-full.txt) takes a `System.Drawing.Printing.PrintDocument`, which uses the printers installed on Windows. That class comes with `System.Drawing.Common`, a dependency of the Classic package `TXTextControl.TextControl.ASP.SDK` and not of the Core package, so the examples use Classic in a .NET console application on Windows, as the blog article [Print MS Word DOCX Documents in .NET using C# Without Interop](https://www.textcontrol.com/blog/2024/06/28/print-ms-word-docx-documents-in-net-using-c-sharp-without-interop/) does. [Create Your First Application](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-processing/first-application/#choose-core-or-classic) compares the two packages.

Applications that run on Linux or in containers create a PDF instead and let users print it, as described in [Let Users Print in the Browser](#let-users-print-in-the-browser).

### Print a Document

The following program loads a DOCX document and prints it to the printer "Microsoft Print to PDF", which writes the output to a file:

```csharp
using System.Drawing.Printing;
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/sample.docx", StreamType.WordprocessingML);

    PrintDocument printDocument = new PrintDocument();
    printDocument.DocumentName = "sample.docx";
    printDocument.PrinterSettings.PrinterName = "Microsoft Print to PDF";
    printDocument.PrinterSettings.PrintToFile = true;
    printDocument.PrinterSettings.PrintFileName = Path.GetFullPath("printed.pdf");

    // Print without a status dialog
    printDocument.PrintController = new StandardPrintController();

    tx.Print(printDocument);
}
```

The code works as follows:

- `Print` prints the document with the settings of the `PrintDocument`. Without `PrinterName`, the default printer is used.
- `PrintToFile` and `PrintFileName` send the output to a file instead of paper. Leave them out to print on the printer.
- By default, .NET shows a status dialog while a document is printed. A `StandardPrintController` prints without it, which is what a service or console application needs.

`Print` uses these settings of the `PrintDocument`: `DocumentName`, `PrintController`, `DefaultPageSettings.Color` and, in `PrinterSettings`, `PrinterName`, `PrintToFile`, `FromPage`, `ToPage`, `Copies`, `Collate` and `PrintRange`.

### Print Pages, Copies and Collated Sets

To print part of a document, set `FromPage` and `ToPage`, and set `PrintRange` to `PrintRange.SomePages` so that the page numbers are used. The following program prints two collated copies of pages 2 and 3 on the default printer:

```csharp
using System.Drawing.Printing;
using TXTextControl;

using (ServerTextControl tx = new ServerTextControl())
{
    tx.Create();
    tx.Load("Documents/sample.docx", StreamType.WordprocessingML);

    PrintDocument printDocument = new PrintDocument();
    printDocument.PrintController = new StandardPrintController();

    // FromPage and ToPage are only used with PrintRange.SomePages
    printDocument.PrinterSettings.PrintRange = PrintRange.SomePages;
    printDocument.PrinterSettings.FromPage = 2;
    printDocument.PrinterSettings.ToPage = 3;
    printDocument.PrinterSettings.Copies = 2;
    printDocument.PrinterSettings.Collate = true;

    Console.WriteLine($"The document has {tx.Pages} pages.");
    tx.Print(printDocument);
}
```

[ServerTextControl.Pages](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/pages-property/llms-full.txt) returns the number of pages, which helps you check a page range before printing.

### Print Several Documents in One Print Job

A second overload, `Print(int page, PrintPageEventArgs e)`, prints a single page from the `PrintPage` event of a `PrintDocument`. With it, several documents go to the printer as one print job. The following program prints a letter and an invoice page by page and loads the next document when all pages of the current one are printed:

```csharp
using System.Drawing.Printing;
using TXTextControl;

string[] files = { "Documents/letter.docx", "Documents/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 += (sender, e) =>
    {
        tx.Print(pageNumber, e);
        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;
            }
        }

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

    printDocument.Print();
}
```

The code works as follows:

- `printDocument.Print()` starts the print job, and .NET raises `PrintPage` for each page.
- `tx.Print(pageNumber, e)` prints one page of the loaded document into the page that .NET is printing.
- `e.HasMorePages` tells .NET whether another page follows. It's `false` after the last page of the last document.

To print documents as one document with continuous page numbers instead, combine them with `Append` first, as described in [Creating Documents](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/creating/#combine-several-documents).

#### Print Over a Background

Output that your own `PrintPage` handler draws, such as a watermark, an image or a form background, stays on the page: the document is printed transparently on top of it. The following handler, used in place of the one above for a single document, draws a gray "COPY" before it prints each page:

```csharp
printDocument.PrintPage += (sender, e) =>
{
    // Drawn first, so the text of the page is printed on top of it
    using (System.Drawing.Font font = new System.Drawing.Font("Arial", 72))
    using (System.Drawing.Brush brush = new System.Drawing.SolidBrush(System.Drawing.Color.LightGray))
    {
        e.Graphics.DrawString("COPY", font, brush, 150, 400);
    }

    tx.Print(pageNumber, e);
    pageNumber++;
    e.HasMorePages = pageNumber <= tx.Pages;
};
```

### Print a Merged Document

After a mail merge, the merged document is in the `ServerTextControl`, and `tx.Print` prints it like any other document. [MailMerge.Print](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol-documentserver/mailmerge/print-method/llms-full.txt) prints the merged document directly, either with a `PrintDocument` or with a document name, a printer name, a number of copies and a collate flag:

```csharp
mailMerge.MergeJsonData(jsonData);
mailMerge.Print("Invoices", "Microsoft Print to PDF", 1, false);
```

[Simple Mail Merge](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/mail-merge/simple/llms-full.txt) shows the merge that comes before these lines.

### Choose the Formatting Printer

TX Text Control formats text with the measurements of a device: the exact character widths, kerning and spacing. [ServerTextControl.FormattingPrinter](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/formattingprinter-property/llms-full.txt) sets the name of the printer whose measurements are used, so that a document printed on that printer has the same line and page breaks as on screen:

| Value | Formats with |
|---|---|
| The name of a printer | The measurements of that printer; if it isn't installed, the standard printer is used |
| `"Standard"` | The standard printer of the system |
| `"Display"` | The measurements of the display device, which are similar on all machines |

On a server, the formatting printer matters for two reasons:

- **Templates look different on another machine** when it formats with another printer. Using the same printer, or `"Display"` on both machines, avoids this, as the blog article [WYSIWYG: What You Need to Know!](https://www.textcontrol.com/blog/2014/06/19/wysiwyg-what-you-need-to-know/) explains.
- **Printers slow down initialization.** A network printer or a printer in energy-saving mode that responds late delays the creation of an instance, 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/) describes.

[GetSupportedFonts](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/getsupportedfonts-method/llms-full.txt) and [GetSupportedPaperSizes](https://docs.textcontrol.com/tx-text-control-dotnet-server/reference/txtextcontrol/servertextcontrol/getsupportedpapersizes-method/llms-full.txt) return the fonts and paper sizes of the formatting printer.

### Let Users Print in the Browser

In a web application, users print on their own printers, not on the server's. Create a PDF on the server and let users print it:

- **Save the document as PDF** and return it from a controller, as [Save as DOCX and PDF](https://docs.textcontrol.com/tx-text-control-dotnet-server/getting-started/document-processing/save-docx-pdf/#return-a-document-from-an-asp-net-core-controller) shows. Creating the PDF needs no printer driver.
- **Show the document in the Document Viewer**, whose Print button and `printDocument` method print it from the browser, as [Printing](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/printing/llms-full.txt) in the Document Viewer section describes.

### Next Steps

- [Saving and Converting Documents](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/saving-converting/llms-full.txt): create the PDF that users print.
- [Printing](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-viewer/printing/llms-full.txt) in the Document Viewer: print documents from the browser.
- [Overview](https://docs.textcontrol.com/tx-text-control-dotnet-server/mail-merge/overview/llms-full.txt) of Mail Merge and Reporting: create the documents you print from templates and data.

---

## Nearby

- **Previous:** [Document Comparison](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/comparison/llms-full.txt)
- **Next:** [Events](https://docs.textcontrol.com/tx-text-control-dotnet-server/document-processing/events/llms-full.txt)
