# Saving and Converting Documents

> Convert a folder to PDF with ServerTextControl, save selections and paragraphs, write HTML with CSS, shrink PDF images and omit comments with SaveSettings.

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

---

Converting a Word file to PDF in a Windows Forms application takes two calls: `Load` in one format and `Save` in another. What comes out is decided by the details: which part of a document you save, where HTML keeps its styles, how large a PDF file becomes and which content stays behind. Code for three of these tasks follows: converting a whole folder, saving parts of a document and controlling the result with `SaveSettings`.

[Save as DOCX and PDF](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/document-processing/save-docx-pdf/llms-full.txt) covers the first steps: saving the editor's document, converting one file, byte arrays and PDF/A. PDF options such as passwords and attachments are in [PDF Processing](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/llms-full.txt). *Form1.cs* needs these `using` directives for the examples:

```csharp
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using TXTextControl;
```

### Convert a Folder of Documents

A conversion loads a document and saves it in another format. The following handler asks for a folder, converts every DOCX, DOC, RTF and HTML file in it to PDF in a subfolder *PDF* and reports the files that couldn't be converted:

```csharp
// The load format for each file extension
private static readonly Dictionary<string, StreamType> SourceFormats =
    new Dictionary<string, StreamType>(StringComparer.OrdinalIgnoreCase)
    {
        { ".docx", StreamType.WordprocessingML },
        { ".doc", StreamType.MSWord },
        { ".rtf", StreamType.RichTextFormat },
        { ".html", StreamType.HTMLFormat }
    };

private void convertFolderButton_Click(object sender, EventArgs e)
{
    using (FolderBrowserDialog dialog = new FolderBrowserDialog())
    {
        if (dialog.ShowDialog() != DialogResult.OK)
        {
            return;
        }

        string outputFolder = Path.Combine(dialog.SelectedPath, "PDF");
        Directory.CreateDirectory(outputFolder);

        int converted = 0;
        List<string> failed = new List<string>();

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

            foreach (string file in Directory.GetFiles(dialog.SelectedPath))
            {
                if (!SourceFormats.TryGetValue(Path.GetExtension(file), out StreamType format))
                {
                    continue;
                }

                try
                {
                    // Load replaces the previous document
                    tx.Load(file, format);
                    tx.Save(Path.Combine(outputFolder,
                        Path.GetFileNameWithoutExtension(file) + ".pdf"), StreamType.AdobePDF);
                    converted++;
                }
                catch (FilterException exception)
                {
                    failed.Add($"{Path.GetFileName(file)}: {exception.Reason}");
                }
            }
        }

        MessageBox.Show($"{converted} documents converted.\r\n" + string.Join("\r\n", failed));
    }
}
```

The code works as follows:

- The [ServerTextControl](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/llms-full.txt) converts the files without touching the document in the editor. [Load](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/load-method/llms-full.txt) replaces its contents with each file, so one instance serves the whole folder.
- [Save](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/servertextcontrol/save-method/llms-full.txt) writes the complete document and overwrites an existing file.
- A [FilterException](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/filterexception/llms-full.txt) with its [Reason](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/filterexception/reason-property/llms-full.txt) reports a file that couldn't be loaded or saved, and the loop goes on with the next one.

The handler runs on the thread of the form, so the window doesn't respond until the folder is done. For long conversions, run the work in the background, as [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/servertextcontrol/llms-full.txt) and [UI Threading and Background Operations](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/performance/threading/llms-full.txt) describe. For hundreds or thousands of documents, Text Control recommends separate processes over several threads, because threads that use TX Text Control can wait for each other on shared resources.

### Save With the Save As Dialog Box

`Save` with a `StreamType` and a [SaveSettings](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/llms-full.txt) object opens the **Save As** dialog box, and afterward the same object reports the file, its size and its format. [Offer Options in the Save As Dialog Box](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/load-save/#offer-options-in-the-save-as-dialog-box) shows the call, the options it adds to the dialog box and the properties `SavedFile`, `BytesWritten` and `SavedStreamType`. `SavedFile` is empty when the document went to a byte array or a string.

### Save Part of a Document

[Selection.Save](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/selection/save-method/llms-full.txt) saves only the selected text, to a file, a byte array or a string. [Paragraph.Save](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/paragraph/save-method/llms-full.txt) saves one paragraph to a byte array or a string:

```csharp
private void savePartButton_Click(object sender, EventArgs e)
{
    // The paragraph at the input position as an HTML string
    Paragraph paragraph = textControl1.Paragraphs.GetItem(textControl1.Selection.Start);

    string paragraphHtml;
    paragraph.Save(out paragraphHtml, StringStreamType.HTMLFormat);

    // The selected text as RTF and as a DOCX file
    if (textControl1.Selection.Length > 0)
    {
        string rtf;
        textControl1.Selection.Save(out rtf, StringStreamType.RichTextFormat);

        textControl1.Selection.Save("excerpt.docx", StreamType.WordprocessingML);
    }

    MessageBox.Show(paragraphHtml);
}
```

[ParagraphCollection.GetItem](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/paragraphcollection/getitem-method/llms-full.txt) with a zero-based text position returns the paragraph there. PDF and PDF/A are the exception: only complete documents are saved in these formats.

### Save HTML With Stylesheets and Images

For HTML, two settings decide where formatting and images go. [SaveSettings.CssSaveMode](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/csssavemode-property/llms-full.txt) sets where the formatting is written:

| Value | The formatting is written |
|---|---|
| `None` | Into the HTML tags of the body |
| `Inline` | As stylesheets in the head of the HTML document |
| `CreateFile` | Into a CSS file with the name of the HTML file, or the name in `CssFileName`; an existing file is kept |
| `OverwriteFile` | Like `CreateFile`, but an existing CSS file is overwritten |

[SaveSettings.ImageSaveMode](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/imagesavemode-property/llms-full.txt) set to `SaveAsData` embeds the images, so the HTML needs no image files. The following handler writes the editor's document as an HTML file with a CSS file and as an HTML string with its styles in the head:

```csharp
private void saveHtmlButton_Click(object sender, EventArgs e)
{
    // An HTML file with a stylesheet file of the same name, newsletter.css
    SaveSettings fileSettings = new SaveSettings()
    {
        CssSaveMode = CssSaveMode.OverwriteFile,
        ImageSaveMode = ImageSaveMode.SaveAsData
    };

    textControl1.Save("newsletter.html", StreamType.HTMLFormat, fileSettings);

    // An HTML string can't have a stylesheet file, so the styles go into the head
    SaveSettings stringSettings = new SaveSettings()
    {
        CssSaveMode = CssSaveMode.Inline,
        ImageSaveMode = ImageSaveMode.SaveAsData
    };

    string html;
    textControl1.Save(out html, StringStreamType.HTMLFormat, stringSettings);
}
```

`CreateFile` and `OverwriteFile` can't be used when HTML is saved to a string or a byte array.

### Reduce the Size of PDF Files

Photos make up most of the size of many PDF files. Two settings reduce them when the document is saved:

```csharp
private void smallPdfButton_Click(object sender, EventArgs e)
{
    SaveSettings saveSettings = new SaveSettings()
    {
        ImageCompressionQuality = 70, // 1 to 100
        ImageMaxResolution = 150      // dpi; larger images are reduced
    };

    textControl1.Save("invoice.pdf", StreamType.AdobePDF, saveSettings);
}
```

- [ImageCompressionQuality](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/imagecompressionquality-property/llms-full.txt) is the quality of lossy compression, from 1 to 100. It applies to images whose data is compressed with a lossy algorithm, and 0 selects a default.
- [ImageMaxResolution](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/imagemaxresolution-property/llms-full.txt) reduces images with a higher resolution. The default, 0, keeps the resolution of each image.

The blog article [Best Practices for Image Compression when Exporting to PDF in .NET C#](https://www.textcontrol.com/blog/2025/08/22/best-practices-for-image-compression-when-exporting-to-pdf-in-dotnet-csharp/) compares values for documents read on screen and printed.

### Leave Out Content and Add Properties

Before a document goes to a customer, internal comments shouldn't go with it. [SaveSettings.OmittedContent](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/omittedcontent-property/llms-full.txt) leaves parts of the document out of the saved file, without changing the document in the editor:

```csharp
private void saveForCustomerButton_Click(object sender, EventArgs e)
{
    UserDefinedPropertyDictionary properties = new UserDefinedPropertyDictionary();
    properties.Add("InvoiceNumber", "INV-2025-001");
    properties.Add("AmountDue", 299.97);

    SaveSettings saveSettings = new SaveSettings()
    {
        DocumentTitle = "Invoice INV-2025-001",
        UserDefinedDocumentProperties = properties,
        OmittedContent = OmittedContent.Comments
    };

    textControl1.Save("invoice-customer.docx", StreamType.WordprocessingML, saveSettings);
}
```

The values of `OmittedContent`:

| Value | Leaves out |
|---|---|
| `Comments`, `Footnotes` | Comments and footnotes |
| `TextFields` | All kinds of text fields |
| `TrackedChanges` | The markup of tracked changes; text and formatting are saved |
| `SubTextParts`, `EditableRegions`, `TablesOfContents` | The markers or data of these elements; text and formatting are saved |
| `Sections` | The section data |

`OmittedContent` can't be used with PDF and PDF/A. The values of [UserDefinedDocumentProperties](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/savesettings/userdefineddocumentproperties-property/llms-full.txt) are strings, Boolean values, integers or double values, and `DocumentTitle` overrides the title in `DocumentSettings` for this save.

### Save to Streams

`Save` writes to a `FileStream`. Another stream, such as a `MemoryStream` that a mail library expects, is filled from a byte array:

```csharp
private void saveToStreamButton_Click(object sender, EventArgs e)
{
    // A FileStream is written at its current position
    using (FileStream fileStream = new FileStream("invoice.rtf", FileMode.Create))
    {
        textControl1.Save(fileStream, StreamType.RichTextFormat);
    }

    // Other streams: save to a byte array and wrap it
    byte[] pdf;
    textControl1.Save(out pdf, BinaryStreamType.AdobePDF);

    using (MemoryStream memoryStream = new MemoryStream(pdf))
    {
        MessageBox.Show($"Stream length: {memoryStream.Length}");
    }
}
```

### What Changes When Converting

Formats differ in what they can store, so a conversion can change a document:

- **Plain text** keeps only the text, with a carriage return and a line feed at the end of each paragraph.
- **Fields** of Word documents become fields only when `LoadSettings.ApplicationFieldFormat` is set before loading, as [Loading Documents](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/loading/#control-the-import-with-loadsettings) describes.
- **Images** are saved in their original format, or in the default image format of the target format when it doesn't support theirs, as [Control How Images Are Saved](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/images/#control-how-images-are-saved) lists for each document format.
- **Fonts** that aren't available on the computer that converts are replaced, which can change line and page breaks. [Fonts](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/fonts/#choose-the-replacement-fonts) shows how to find and choose the replacements.
- **PDF/A** needs fonts that can be embedded, which [PDF/A](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/pdf-a/llms-full.txt) covers.

[Document Conversion](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/troubleshooting/conversion/llms-full.txt) in the Troubleshooting section helps when the result isn't what you expect.

### Next Steps

- [PDF Creation and Conversion](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/creation-conversion/llms-full.txt): PDF options, metadata and PDF/UA.
- [Loading Documents](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/loading/llms-full.txt): load documents with all their options.
- [Using ServerTextControl in Desktop Applications](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/servertextcontrol/llms-full.txt): convert documents in the background.
- [Supported File Formats](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/overview/file-formats/llms-full.txt): the formats you can load and save.

---

## Nearby

- **Previous:** [Loading Documents](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/loading/llms-full.txt)
- **Next:** [Text, Paragraphs, and Stylesheets](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/text-paragraphs/llms-full.txt)
