# Attachments

> Embed files in PDF and PDF/A-3 from a Windows Forms TextControl with EmbeddedFile, manage them in the DocumentSettings sidebar, extract them with Attachments.

- **Product:** TX Text Control .NET for Windows Forms
- **Section:** Documentation
- **Kind:** Topic
- **Path:** TX Text Control .NET for Windows Forms > PDF Processing > Attachments
- **4737 words**
- **Web URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/attachments/
- **LLMs URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/attachments/llms.txt
- **LLMs-Full URL:** https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/attachments/llms-full.txt

---

A PDF file can carry other files: the XML of an electronic invoice next to its printable pages, the JSON data a letter was merged from or a spreadsheet with the details of a contract. In a Windows Forms application, such attachments belong to the document in the `TextControl`. Your code adds them before it saves the document as PDF, users manage them in a sidebar panel, and the attachments of a PDF document that the editor loads are kept when it is saved again. Read on for the classes involved, the relationship and MIME type PDF/A-3 requires, electronic invoices and extracting attachments from PDF files you receive.

Saving the editor's document as PDF and PDF/A is introduced in [Create a PDF](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/getting-started/pdf/create/llms-full.txt) in Getting Started.

### How Attachments Work

An attachment is an [EmbeddedFile](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/llms-full.txt) object: a file name, the data of the file and optional properties. Embedded files are supported for PDF and PDF/A only: they are written when the document is saved with `StreamType.AdobePDF` or `StreamType.AdobePDFA`, and other formats leave them out.

| Property | Contains |
|---|---|
| [FileName](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/filename-property/llms-full.txt) | The name of the file, which can include a relative or absolute path; read only |
| [Data](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/data-property/llms-full.txt) | The content of the file, a string or a byte array; read only |
| [MIMEType](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/mimetype-property/llms-full.txt) | The MIME type, such as `application/json`; without one, `application/octet-stream` is used |
| [Relationship](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/relationship-property/llms-full.txt) | How the file relates to the document; written to PDF/A only |
| [Description](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/description-property/llms-full.txt) | A description of the file |
| [CreationDate](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/creationdate-property/llms-full.txt), [LastModificationDate](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/lastmodificationdate-property/llms-full.txt) | The dates of the file; when they are `null`, the dates of the PDF document are used |

The [EmbeddedFile constructor](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/embeddedfile/constructor/llms-full.txt) takes the file name, the data as a byte array or a string, and XMP metadata, which can be `null`. The metadata consists of `rdf:Description` elements that are added to the metadata of the PDF document, as electronic invoices require. A third overload takes a `SafeFileHandle` and reads the file when the document is saved.

Three properties hold attachments:

- **[TextControl.DocumentSettings](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/textcontrol/documentsettings-property/llms-full.txt)`.`[EmbeddedFiles](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/documentsettings/embeddedfiles-property/llms-full.txt)** are the attachments of the document in the editor. A loaded PDF fills them, the sidebar panel shows and changes them, and every save as PDF embeds them. The value is `null` when the document has none.
- **[SaveSettings.EmbeddedFiles](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/loadsavesettingsbase/embeddedfiles-property/llms-full.txt)** sets the files of one save and takes the place of those in `DocumentSettings`.
- **[LoadSettings.EmbeddedFiles](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/loadsavesettingsbase/embeddedfiles-property/llms-full.txt)** returns the files of a loaded PDF. They are loaded when [PDFImportSettings](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/pdfimportsettings/enumeration/llms-full.txt) contains `LoadEmbeddedFiles`, which is part of the default.

### Choose the Relationship and MIME Type

PDF/A-3 requires a MIME type and a relationship for every embedded file. `Relationship` is a string, and these values are predefined:

| Relationship | Use it for |
|---|---|
| `Source` | The original document the PDF was created from, such as a DOCX file |
| `Data` | Machine-readable data, such as XML, JSON or CSV |
| `Alternative` | Another representation of the document's content, such as the XML of a ZUGFeRD or Factur-X invoice |
| `Supplement` | Additional information, such as appendices |
| `Unspecified` | Anything else |

Common MIME types are `application/xml`, `application/json`, `text/csv`, `image/png` and `image/jpeg`. The blog article [Why Defining MIME Types for PDF/A Attachments Is Essential](https://www.textcontrol.com/blog/2025/12/10/why-defining-mime-types-for-pdfa-attachments-is-essential/) explains why validators reject PDF/A documents without them.

### Attach a File When Saving

The following handler in *Form1.cs* attaches the JSON data of an invoice to the document in `textControl1` and saves it as PDF/A. It needs `using System;`, `using System.IO;` and `using TXTextControl;` at the top of the file, and *data.json* in the folder of the application:

```csharp
private void attachDataButton_Click(object sender, EventArgs e)
{
    // PDF/A requires fonts that can be embedded
    textControl1.FontSettings.EmbeddableFontsOnly = true;

    EmbeddedFile data = new EmbeddedFile("data.json", File.ReadAllBytes("data.json"), null)
    {
        Description = "Invoice data",
        MIMEType = "application/json",
        Relationship = "Data",
        CreationDate = DateTime.Now
    };

    SaveSettings saveSettings = new SaveSettings()
    {
        EmbeddedFiles = new EmbeddedFile[] { data }
    };

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

The code works as follows:

- [FontSettings.EmbeddableFontsOnly](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol/fontsettings/embeddablefontsonly-property/llms-full.txt) restricts the document to fonts that can be embedded, which PDF/A requires. [PDF/A](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/pdf-a/llms-full.txt) explains the rules of the format.
- `EmbeddedFiles` takes an array, so one save embeds any number of files.
- Because the array is passed in `SaveSettings`, the attachment goes into this file only. To make it part of the document, so that every later save embeds it, assign the array to `textControl1.DocumentSettings.EmbeddedFiles` instead.

PDF readers list the attachments of a document in a panel of their own. Adobe Acrobat shows them with their names and descriptions:

![Adobe Acrobat showing a contract PDF with the Attachments panel open, which lists agreement.docx, data.json, data.xlsx and thumbnail.jpg.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/pdf-attachments-panel.cb5c8608.webp)

### Let Users Manage Attachments in the Sidebar

The [Sidebar](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-windows-forms/sidebar/llms-full.txt) has a **DocumentSettings** panel for the properties of the document. Its **Embedded Files in PDF** category lists the attachments of `DocumentSettings.EmbeddedFiles`. With its buttons, users add a file (**Add...**), write an attachment to a file (**Save...**), delete it (**Remove**) and change its description, relationship and MIME type (**Edit...**). When the user adds a file, the panel sets a MIME type that matches the file name extension.

![The Document Settings sidebar of TX Words beside the editor, with the Embedded Files in PDF category listing two files and the Edit Embedded File dialog box offering the relationships Source, Alternative, Data, Supplement and Unspecified.](https://docs.textcontrol.com/assets/img/tx-text-control-dotnet-winforms/document-settings-sidebar.d0782f9e.webp)

To show the panel, set the [ContentLayout](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-windows-forms/sidebar/contentlayout-property/llms-full.txt) of a sidebar connected to `textControl1` to `DocumentSettings`, in its smart tag or in code. The following handler opens it in a sidebar named `sidebarLeft`. It needs `using TXTextControl.Windows.Forms;`:

```csharp
private void documentSettingsButton_Click(object sender, EventArgs e)
{
    sidebarLeft.ContentLayout = Sidebar.SidebarContentLayout.DocumentSettings;
    sidebarLeft.IsShown = true;
}
```

The panel also edits the title, author, subject, keywords and custom properties of the document, as [Document Metadata](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/metadata/llms-full.txt) describes. If your application doesn't offer attachments, hide their category with [FindItem](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-windows-forms/sidebar/finditem-method/llms-full.txt) and a value of [DocumentSettingsItem](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-windows-forms/sidebar/documentsettingsitem-enumeration/llms-full.txt):

```csharp
// Hide the Embedded Files in PDF category of the panel
Control embeddedFiles = sidebarLeft.FindItem(Sidebar.DocumentSettingsItem.TXITEM_EmbeddedFilesPanel);

if (embeddedFiles != null)
{
    embeddedFiles.Visible = false;
}
```

How a sidebar is added in the designer and connected to the ribbon is shown in [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/ribbon-ui/sidebar/llms-full.txt).

### Create an Electronic Invoice

ZUGFeRD and its French counterpart Factur-X are hybrid invoices: a PDF/A-3 document for people to read, with the invoice as XML attached for software to process. Since ZUGFeRD 2.1, XRechnung XML can be embedded in a PDF the same way. TX Text Control creates the readable invoice and embeds the XML; the XML itself comes from your ERP system or an e-invoice library such as ZUGFeRD-csharp.

The following handler embeds *factur-x.xml* in the invoice shown in the editor, together with the XMP metadata in *metadata.xml* that declares the standard, and saves a PDF/A-3 document:

```csharp
private void createEInvoiceButton_Click(object sender, EventArgs e)
{
    // PDF/A requires fonts that can be embedded
    textControl1.FontSettings.EmbeddableFontsOnly = true;

    // The XML invoice, created by your ERP system or an e-invoice library
    byte[] invoiceXml = File.ReadAllBytes("factur-x.xml");

    // rdf:Description elements that declare the invoice standard
    string metadata = File.ReadAllText("metadata.xml");

    EmbeddedFile invoice = new EmbeddedFile("factur-x.xml", invoiceXml, metadata)
    {
        Description = "factur-x",
        MIMEType = "application/xml",
        Relationship = "Alternative",
        LastModificationDate = DateTime.Now
    };

    SaveSettings saveSettings = new SaveSettings()
    {
        EmbeddedFiles = new EmbeddedFile[] { invoice }
    };

    textControl1.Save("e-invoice.pdf", StreamType.AdobePDFA, saveSettings);
}
```

*metadata.xml* contains the XMP extension schema of ZUGFeRD with the conformance level, the document type, the version and the name of the embedded file. The blog article [Creating ZUGFeRD 2.3 (XRechnung, Factur-X) Documents with .NET C#](https://www.textcontrol.com/blog/2025/01/02/creating-zugferd-2-3-xrechnung-factur-x-documents-with-net-c-sharp/) shows its complete content and creates the XML with ZUGFeRD-csharp. Check the result with a validation service for ZUGFeRD and Factur-X, and sign the PDF to make later changes to the invoice detectable, as [Digital Signatures](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/llms-full.txt) describes.

### Extract Attachments From a PDF

To read the attachments of a PDF without loading it into the editor, use the static class [Attachments](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/attachments/llms-full.txt) of the `TXTextControl.DocumentServer.PDF` namespace. That namespace has an `EmbeddedFile` class of its own, which clashes with `TXTextControl.EmbeddedFile` in a file that imports both namespaces. An alias avoids the clash: add `using Pdf = TXTextControl.DocumentServer.PDF;` at the top of *Form1.cs*.

The following handler lets the user choose a PDF file and a folder and writes every attachment of the file to the folder:

```csharp
private void extractAttachmentsButton_Click(object sender, EventArgs e)
{
    using (OpenFileDialog openDialog = new OpenFileDialog() { Filter = "PDF documents (*.pdf)|*.pdf" })
    using (FolderBrowserDialog folderDialog = new FolderBrowserDialog())
    {
        if (openDialog.ShowDialog(this) != DialogResult.OK ||
            folderDialog.ShowDialog(this) != DialogResult.OK)
        {
            return;
        }

        Pdf.EmbeddedFile[] files = Pdf.Attachments.GetFromFile(openDialog.FileName)
            ?? Array.Empty<Pdf.EmbeddedFile>();

        foreach (Pdf.EmbeddedFile file in files)
        {
            // The file name can contain a path
            string path = Path.Combine(folderDialog.SelectedPath, Path.GetFileName(file.FileName));

            if (file.HasBinaryData)
            {
                File.WriteAllBytes(path, file.BinaryData);
            }
            else if (file.HasStringData)
            {
                File.WriteAllText(path, file.StringData);
            }
        }

        MessageBox.Show($"{files.Length} attachments saved to {folderDialog.SelectedPath}");
    }
}
```

The code works as follows:

- [GetFromFile](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/attachments/getfromfile-method/llms-full.txt) takes the complete path of a PDF file, and [GetFromData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/attachments/getfromdata-method/llms-full.txt) the PDF as a byte array. Both return an array of [DocumentServer.PDF.EmbeddedFile](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/embeddedfile/llms-full.txt) objects.
- The properties of this class are read only, and its MIME type is named [MimeType](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/embeddedfile/mimetype-property/llms-full.txt).
- [HasBinaryData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/embeddedfile/hasbinarydata-property/llms-full.txt) and [HasStringData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/embeddedfile/hasstringdata-property/llms-full.txt) tell whether the content is in [BinaryData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/embeddedfile/binarydata-property/llms-full.txt) or in [StringData](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/reference/txtextcontrol-documentserver-pdf/embeddedfile/stringdata-property/llms-full.txt).

To pick the XML of an e-invoice, look for the attachment whose `Relationship` is `Alternative` and whose `MimeType` ends with `xml`: older invoices use `text/xml`, newer ones `application/xml`.

### Keep, Add and Replace Attachments

When `textControl1` loads a PDF, its attachments go into `DocumentSettings.EmbeddedFiles`, and a save as PDF writes them again, so a PDF that the user opens, changes and saves keeps its attachments. `SaveSettings.EmbeddedFiles` replaces them for one save: the array you pass is what the file contains. To add a file and keep the existing ones, extend the array of `DocumentSettings`; the handler needs `using System.Collections.Generic;`:

```csharp
private void addAttachmentButton_Click(object sender, EventArgs e)
{
    // The attachments of the loaded PDF, or none
    List<EmbeddedFile> files = new List<EmbeddedFile>(
        textControl1.DocumentSettings.EmbeddedFiles ?? Array.Empty<EmbeddedFile>());

    files.Add(new EmbeddedFile("line-items.csv", File.ReadAllBytes("line-items.csv"), null)
    {
        Description = "Line items",
        MIMEType = "text/csv"
    });

    // Saved with the document from now on
    textControl1.DocumentSettings.EmbeddedFiles = files.ToArray();

    textControl1.Save("invoice-with-line-items.pdf", StreamType.AdobePDF);
}
```

The attachments of a PDF are loaded only when `LoadEmbeddedFiles` is part of `LoadSettings.PDFImportSettings`. A value you set yourself, such as `PDFImportSettings.GenerateLines` for the text only, has to include it, as [Loading Documents](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-processing/loading/#control-the-import-with-loadsettings) describes for the other settings. The saved PDF is a new document built from the content of the editor, with the same attachments.

### Next Steps

- [PDF/A](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/pdf-a/llms-full.txt): create archivable PDF/A-3 documents.
- [Document Metadata](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/metadata/llms-full.txt): write and read the title, author and keywords.
- [Signing PDF Documents](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/digital-signatures/signing/llms-full.txt): protect a PDF and its attachments with a signature.
- [Sidebar and Panels](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/document-editor/ribbon-ui/sidebar/llms-full.txt): add the sidebar that shows the DocumentSettings panel.

---

## Nearby

- **Previous:** [Exporting Interactive and Flattened Forms](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/forms/exporting/llms-full.txt)
- **Next:** [Text Extraction](https://docs.textcontrol.com/tx-text-control-dotnet-winforms/pdf/text-extraction/llms-full.txt)
