# Exporting Interactive and Flattened Forms

> Export forms from a WPF application as fillable PDF with permissions or flattened into text: GetTextFields, TextFieldCollection.Remove and MailMerge Replace.

- **Product:** TX Text Control .NET for WPF
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for WPF > PDF Processing > PDF Forms > Exporting Interactive and Flattened Forms
- **2839 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/forms/exporting/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/forms/exporting/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/forms/exporting/llms-full.txt

---

A form that leaves your WPF application is either still a form or already a record. As an *interactive* PDF, it carries fields that the recipient fills in. As a *flattened* PDF, each field has been replaced by the text it showed, so the values can no longer be changed in a PDF reader: the right state for confirmations, signed contracts and archived applications. You decide at the time of saving, for all fields or for some.

The examples work with the form of [Create a PDF Form](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/getting-started/pdf/form/llms-full.txt) in `textControl1`, with the form fields `name`, `country` and `newsletter`.

### Interactive or Flattened

|  | Interactive form | Flattened form |
|---|---|---|
| In the PDF | AcroForm fields with names and values | Text, check box characters and dates where the fields were |
| Users can | Fill in and change the values in a PDF reader | Read and print the document |
| Your code can | Read the values with `Forms.GetAcroFormFields` | Only extract text, as [Text Extraction](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/text-extraction/llms-full.txt) describes |
| Typical use | Forms sent out to be filled in | Confirmations, contracts and archived forms |

Flattening removes a form field and leaves the text it displayed:

| Form field | Text that remains |
|---|---|
| [TextFormField](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textformfield/llms-full.txt) | The entered text |
| [SelectionFormField](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/selectionformfield/llms-full.txt) | The text of the selected item |
| [DateFormField](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/dateformfield/llms-full.txt) | The date as the field displays it, formatted with its [DateFormat](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/dateformfield/dateformat-property/llms-full.txt) |
| [CheckFormField](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/checkformfield/llms-full.txt) | The character for the state of the check box, set with [CheckedCharacter](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/checkformfield/checkedcharacter-property/llms-full.txt) and [UncheckedCharacter](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/checkformfield/uncheckedcharacter-property/llms-full.txt) |

Read the values first, as [Reading Form Fields and Values](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/forms/reading-fields/llms-full.txt) describes, because a flattened PDF has no fields to read. Signature fields aren't form fields: a [SignatureField](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/signaturefield/llms-full.txt) stays where it is.

### Save a Fillable Form

`StreamType.AdobePDF` always saves form fields as fillable fields. A master password with permissions restricts readers to filling in and printing:

```csharp
private void SaveFillableFormButton_Click(object sender, RoutedEventArgs e)
{
    SaveSettings saveSettings = new SaveSettings()
    {
        MasterPassword = "owner1234",

        // Fill in the fields and print, nothing else
        DocumentAccessPermissions = DocumentAccessPermissions.AllowAuthoringFields |
                                    DocumentAccessPermissions.AllowHighLevelPrinting
    };

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

With [DocumentAccessPermissions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/savesettings/documentaccesspermissions-property/llms-full.txt), `AllowAuthoringFields` allows filling in existing form fields and `AllowHighLevelPrinting` printing. The permissions take effect only with a [MasterPassword](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/loadsavesettingsbase/masterpassword-property/llms-full.txt), and without a user password, everyone can open the form. [Passwords and Access Permissions](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/passwords/llms-full.txt) lists all permissions.

Adobe Acrobat Reader highlights the fields of an interactive form:

![A PDF form in Adobe Acrobat Reader with highlighted form fields: text fields, a check box and drop-down lists.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/pdf-form-fillable.09e3ba10.webp)

### Save a Flattened Copy

The user can keep working with the form in the window while a flattened copy is saved from a `ServerTextControl`:

```csharp
private void SaveFlattenedFormButton_Click(object sender, RoutedEventArgs e)
{
    // A copy of the form in the editor, which keeps its form fields
    byte[] document;
    textControl1.Save(out document, BinaryStreamType.InternalUnicodeFormat);

    using (ServerTextControl tx = new ServerTextControl())
    {
        // Initialize the new instance before using it
        tx.Create();
        tx.Load(document, BinaryStreamType.InternalUnicodeFormat);

        // The main text, headers, footers and text frames
        foreach (IFormattedText textPart in tx.TextParts)
        {
            // true: the fields are removed, their text stays
            textPart.GetTextFields(TextFieldType.FormFields).Clear(true);
        }

        tx.Save("form-flattened.pdf", StreamType.AdobePDF);
    }
}
```

The code works as follows:

- [ServerTextControl.TextParts](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/servertextcontrol/textparts-property/llms-full.txt) covers the main text, headers, footers and text frames.
- [IFormattedText.GetTextFields](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/iformattedtext/gettextfields-method/llms-full.txt) returns the fields of the [TextFieldType](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textfieldtype/enumeration/llms-full.txt) values you pass, as a [TextFieldCollection](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textfieldcollection/llms-full.txt). `FormFields` stands for all form field types; values such as `TextFieldType.CheckFormField | TextFieldType.DateFormField` select single types.
- [TextFieldCollection.Clear](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textfieldcollection/clear-method/llms-full.txt) with `true` removes the fields and keeps their text. [FormFieldCollection.Clear](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/formfieldcollection/clear-method/llms-full.txt) has no such parameter.

Flattened, the form shows its values as plain text:

![The same PDF form in Adobe Acrobat Reader after flattening: the values and check box characters are plain text without form fields.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-wpf/pdf-form-flattened.87fcff47.webp)

### Flatten Some Fields and Keep Others

Fields your application has filled can be fixed, while the fields the recipient must fill in stay interactive. The following handler flattens every form field in `textControl1` except `newsletter`, so the user sees the result in the window:

```csharp
private void FlattenSomeFieldsButton_Click(object sender, RoutedEventArgs e)
{
    foreach (IFormattedText textPart in textControl1.TextParts)
    {
        TextFieldCollection formFields = textPart.GetTextFields(TextFieldType.FormFields);

        // Collect first: removing a field changes the collection
        List<TextField> flatten = new List<TextField>();

        foreach (TextField field in formFields)
        {
            if (field.Name != "newsletter")
            {
                flatten.Add(field);
            }
        }

        foreach (TextField field in flatten)
        {
            formFields.Remove(field, true);
        }
    }

    textControl1.Save("form-partly-flattened.pdf", StreamType.AdobePDF);
}
```

The handler needs `using System.Collections.Generic;`. [TextFieldCollection.Remove](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/textfieldcollection/remove-method/llms-full.txt) with `true` removes a field and keeps its text; with one parameter, the text is deleted, too. Reload the form to get its fields back.

### Flatten While Merging Data

When a form is final as soon as data is merged into it, [MailMerge.FormFieldMergeType](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-documentserver/mailmerge/formfieldmergetype-property/llms-full.txt) `Replace` fills and flattens in one step:

```csharp
private void MergeAndFlattenButton_Click(object sender, RoutedEventArgs e)
{
    textControl1.Load("form.tx", StreamType.InternalUnicodeFormat);

    using (MailMerge mailMerge = new MailMerge()
    {
        TextComponent = textControl1,

        // Fill the form fields and replace them with their values
        FormFieldMergeType = FormFieldMergeType.Replace
    })
    {
        mailMerge.MergeJsonData(File.ReadAllText("registration.json"));
    }

    textControl1.Save("registration-final.pdf", StreamType.AdobePDF);
}
```

The handler needs `using System.IO;` and `using TXTextControl.DocumentServer;`. `Replace` replaces the form fields with the values of the data, and empty form fields are removed according to [RemoveEmptyFields](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol-documentserver/mailmerge/removeemptyfields-property/llms-full.txt). `Preselect` fills the fields and keeps them interactive, and `None`, the default, leaves them alone.

### Flatten Before Signing and Archiving

- **Signing.** A digital signature covers the document as it is saved. Flatten first and then save with [SaveSettings.DigitalSignature](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/reference/txtextcontrol/savesettings/digitalsignature-property/llms-full.txt), so that the signature covers the final values, as [Signing PDF Documents](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/digital-signatures/signing/llms-full.txt) describes.
- **Archiving.** Saved with `StreamType.AdobePDFA`, a flattened form is a PDF/A document with fixed values; see [PDF/A](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/pdf-a/llms-full.txt).

The blog article [Convert MS Word DOCX to PDF with Form Fields in C# .NET: Preserve or Flatten Form Fields](https://www.textcontrol.com/blog/2025/02/26/convert-ms-word-docx-to-pdf-with-form-fields-in-csharp-dotnet/) converts a Word form both ways.

### Next Steps

- [Reading Form Fields and Values](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/forms/reading-fields/llms-full.txt): read the values before you flatten.
- [PDF/A](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/pdf-a/llms-full.txt): archive flattened forms.
- [Digital Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/digital-signatures/llms-full.txt): sign the final document.

---

## Nearby

- **Previous:** [Reading Form Fields and Values](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/forms/reading-fields/llms-full.txt)
- **Next:** [Attachments](https://docs.textcontrol.com/tx-text-control-dotnet-wpf/pdf/attachments/llms-full.txt)
