# Smart Documents: Embedding Documents in PDF Containers

> TX Text Control is able to embed and extract embedded files to and from PDF documents. This can be used to create smart document containers that consists of the original document for editing and additional information such as annotations.

- **Author:** Bjoern Meyer
- **Published:** 2021-06-24
- **Modified:** 2025-11-16
- **Description:** TX Text Control is able to embed and extract embedded files to and from PDF documents. This can be used to create smart document containers that consists of the original document for editing and additional information such as annotations.
- **5 min read** (906 words)
- **Tags:**
  - Angular
  - Annotations
  - ASP.NET
  - Collaboration
  - DocumentViewer
  - PDF
  - Smart Document
- **Web URL:** https://www.textcontrol.com/blog/2021/06/24/smart-document-containers-embedding-documents-in-pdf/
- **LLMs URL:** https://www.textcontrol.com/blog/2021/06/24/smart-document-containers-embedding-documents-in-pdf/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2021/06/24/smart-document-containers-embedding-documents-in-pdf/llms-full.txt
- **GitHub Repository:** https://github.com/TextControl/TextControl.Web.MVC.SmartDocument

---

PDF/A-3 permits the embedding of files in any format. PDF/A-3 documents allow the progression from electronic paper to an electronic container that holds the human and machine-readable versions of a document. Applications can extract the machine-readable portion of the PDF document in order to process it. A PDF/A-3 document can contain an unlimited number of embedded documents for different processes.

### Smart Document Container

In this sample application, we use a PDF document as a container to store an editable version and the DocumentViewer annotations as embedded files. The following illustration shows this container setup:

![Embedded document layers](https://s1-www.textcontrol.com/assets/dist/blog/2021/06/24/a/assets/layers.webp "Embedded document layers")

The advantage in this scenario is that the PDF can be send to anyone outside of your infrastructure and the current version of the document is always visible for everyone using a simple Acrobat Reader. The viewable version always reflects the most current version.

### Sample Concept

In this sample, you can create a new *Smart Document* by clicking *New Smart Document*:

![Embedded document layers](https://s1-www.textcontrol.com/assets/dist/blog/2021/06/24/a/assets/screenshot1.webp "Embedded document layers")

The static method *CreateNewDocument* of the *SmartDocument* class creates a blank document using a ServerTextControl instance. This document is saved in the internal Text Control format to be embedded into a newly created PDF document.

```
public static string CreateNewDocument() {

	var DocumentName = Guid.NewGuid().ToString() + ".pdf";

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

		byte[] dataTx;

		// save the blank document in the internal TX format
		tx.Save(out dataTx, TXTextControl.BinaryStreamType.InternalUnicodeFormat);

		// create an attachment
		EmbeddedFile embeddedFile = new EmbeddedFile("original.tx", dataTx, null);
		embeddedFile.Relationship = "Source";

		TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings() {
			EmbeddedFiles = new EmbeddedFile[] { embeddedFile }
		};

		// save a PDF with the attached Text Control document embedded
		tx.Save("App_Data/" + DocumentName,
			TXTextControl.StreamType.AdobePDF,
			saveSettings);
	}

	return DocumentName;
}
```

It opens the TX Text Control document editor that can be used to create a document:

![Embedded document layers](https://s1-www.textcontrol.com/assets/dist/blog/2021/06/24/a/assets/screenshot2.webp "Embedded document layers")

When loading the original, embedded document, the *ExtractSmartDocument* method opens the PDF in order to check the embedded files for the original document or the annotations JSON. In case the document should be edited, the embedded original document is loaded into the editor.

```
public static SmartDocument ExtractSmartDocument(string DocumentName) {

  SmartDocument smartDocument = new SmartDocument();

  using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl()) {

    tx.Create();

    // the load PDF document
    TXTextControl.LoadSettings loadSettings = new LoadSettings();
    tx.Load("App_Data/" + DocumentName,
      TXTextControl.StreamType.AdobePDF,
      loadSettings);

    // loop through all attachments to find the original document
    // and the annotations
    foreach (EmbeddedFile file in loadSettings.EmbeddedFiles) {

      if (file.FileName == "original.tx")
        smartDocument.Document = Convert.ToBase64String((byte[])file.Data);

      if (file.FileName == "annotations.json")
        smartDocument.Annotations = System.Text.Encoding.UTF8.GetString((byte[])file.Data);
    }

    smartDocument.Name = DocumentName;
  }

  return smartDocument;
}
```

When saving the original document, the method *SaveDocument* is loading the modified version into a *ServerTextControl* to create the updated PDF representation container by including itself as an embedded file.

```
public static void SaveDocument(SmartDocument smartDocument) {
  using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl()) {
    tx.Create();

    // load the edited document
    tx.Load(Convert.FromBase64String(smartDocument.Document), 
      TXTextControl.BinaryStreamType.InternalUnicodeFormat);

    // create an attachment from the edited document
    EmbeddedFile embeddedFile = new EmbeddedFile("original.tx",
      Convert.FromBase64String(smartDocument.Document),
      null);
    embeddedFile.Relationship = "Source";

    // attache the files
    TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings() {
      EmbeddedFiles = new EmbeddedFile[] { embeddedFile }
    };

    // save the document as PDF with the edited original attachment
    tx.Save("App_Data/" + smartDocument.Name, 
      TXTextControl.StreamType.AdobePDF,
      saveSettings);
  }
}
```

Back in the overview, this new document can be edited or viewed:

![Embedded document layers](https://s1-www.textcontrol.com/assets/dist/blog/2021/06/24/a/assets/screenshot3.webp "Embedded document layers")

When clicking *View (Annotations)*, the original, editable version of the document is opened in the TX Text Control DocumentViewer that can be used to add annotations:

![Embedded document layers](https://s1-www.textcontrol.com/assets/dist/blog/2021/06/24/a/assets/screenshot4.webp "Embedded document layers")

When clicking *Save Annotations*, the annotations JSON is stored as an embedded file in the container PDF. Therefore, the associated container PDF is loaded and the original document is extracted. This original document is then loaded and used to create the new PDF document to embed the original version and the annotation JSON.

```
public static void SaveAnnotations(SmartDocument smartDocument) {

  using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl()) {

    tx.Create();

    // load the SmartDocument PDF
    TXTextControl.LoadSettings loadSettings = new LoadSettings();
    tx.Load("App_Data/" + smartDocument.Name,
      TXTextControl.StreamType.AdobePDF,
      loadSettings);

    // find the original embedded document
    foreach (EmbeddedFile file in loadSettings.EmbeddedFiles) {

      if (file.FileName == "original.tx")
        smartDocument.Document = Convert.ToBase64String((byte[])file.Data);

    }

    // load the original document
    tx.Load(Convert.FromBase64String(smartDocument.Document),
      BinaryStreamType.InternalUnicodeFormat);

    // create an attachment for the original document
    EmbeddedFile efOriginal = new EmbeddedFile("original.tx",
      Convert.FromBase64String(smartDocument.Document),
      null);
    efOriginal.Relationship = "Source";

    // create an attachment for the annotations
    EmbeddedFile efAnnotations = new EmbeddedFile("annotations.json",
      Encoding.UTF8.GetBytes(smartDocument.Annotations),
      null);
    efAnnotations.Relationship = "Source";

    // attach the files
    TXTextControl.SaveSettings saveSettings = new TXTextControl.SaveSettings() {
      EmbeddedFiles = new EmbeddedFile[] { efOriginal, efAnnotations }
    };

    // save the SmartDocument as PDF with attachments
    tx.Save("App_Data/" + smartDocument.Name, 
      TXTextControl.StreamType.AdobePDF, 
      saveSettings);
  }
}
```

### Download the Sample

This concept is very flexible and can be used for your own formats and workflows. To test this on your own, download the fully-functional sample project from GitHub and let us know, if you have any questions or feedback.

Happy coding!

---

## About Bjoern Meyer

As CEO, Bjoern is the visionary behind our strategic direction and business development, bridging the gap between our customers and engineering teams. His deep passion for coding and web technologies drives the creation of innovative products. If you're at a tech conference, be sure to stop by our booth - you'll most likely meet Bjoern in person. With an advanced graduate degree (Dipl. Inf.) in Computer Science, specializing in AI, from the University of Bremen, Bjoern brings significant expertise to his role. In his spare time, Bjoern enjoys running, paragliding, mountain biking, and playing the piano.

- [LinkedIn](https://www.linkedin.com/in/bjoernmeyer/)
- [X](https://x.com/txbjoern)
- [GitHub](https://github.com/bjoerntx)

---

## Related Posts

- [DocumentViewer Annotations: Highlight Text](https://www.textcontrol.com/blog/2021/06/18/document-viewer-annotations-highlight-text/llms.txt)
- [DocumentViewer 29.2 (29.0.302.500) Final Released](https://www.textcontrol.com/blog/2021/07/27/documentviewer-29-302-final-released/llms.txt)
- [Creation of Custom Electronic Signature Boxes](https://www.textcontrol.com/blog/2021/06/15/creation-of-custom-electronic-signature-boxes/llms.txt)
- [DocumentViewer Collaboration: Live Share Document Annotations](https://www.textcontrol.com/blog/2021/06/08/documentviewer-collaboration-live-share-document-annotations/llms.txt)
- [DocumentViewer Pre-Release: Stamps, Sticky Notes and Comments](https://www.textcontrol.com/blog/2021/05/26/document-viewer-pre-release-stamps-sticky-notes-and-comments/llms.txt)
- [Creating Advanced Tables in PDF and DOCX Documents with C#](https://www.textcontrol.com/blog/2024/09/30/creating-advanced-tables-in-pdf-and-docx-documents-with-csharp/llms.txt)
- [Customizing Electronic Signature Fonts for Typed Signatures in Angular and ASP.NET Core](https://www.textcontrol.com/blog/2024/03/11/customizing-electronic-signature-fonts-for-typed-signatures-in-angular-and-asp-net-core/llms.txt)
- [How to Choose the Best C# Library for your Document Processing Needs](https://www.textcontrol.com/blog/2023/08/07/how-to-choose-the-best-library-for-your-document-processing-needs/llms.txt)
- [Preview: TX Text Control DocumentViewer Becomes a Web Component](https://www.textcontrol.com/blog/2023/03/10/preview-tx-text-control-documentviewer-is-becoming-a-web-component/llms.txt)
- [DocumentViewer: Aspect Ratio Scaling of Signature Annotations](https://www.textcontrol.com/blog/2022/12/28/documentviewer-aspect-ratio-scaling-of-signature-annotations/llms.txt)
- [Adding Attachments to Adobe PDF Documents using C#](https://www.textcontrol.com/blog/2022/02/25/adding-attachments-to-adobe-pdf-documents-using-csharp/llms.txt)
- [Deploying Documents with Annotations](https://www.textcontrol.com/blog/2022/01/07/deploying-documents-with-annotations/llms.txt)
- [Electronic Signatures: Document Audit Trails](https://www.textcontrol.com/blog/2021/10/14/electronic-signatures-document-audit-trails/llms.txt)
- [Combine Form Fields, Merge Fields and Signature Boxes to Request Signatures](https://www.textcontrol.com/blog/2021/10/12/combine-form-fields-merge-fields-and-signature-boxes-to-request-signatures/llms.txt)
- [eSign Demo: Requesting Signatures from Multiple Signers](https://www.textcontrol.com/blog/2021/10/07/esign-demo-requesting-signatures-from-multiple-signers/llms.txt)
- [DocumentViewer: Deploying Forms](https://www.textcontrol.com/blog/2021/07/02/document-viewer-deploying-forms/llms.txt)
- [Don't Print Your Documents! Streamlined Document Processes in Your Applications](https://www.textcontrol.com/blog/2021/06/09/dont-print-your-documents/llms.txt)
- [DocumentViewer Pre-Release: Forms with Conditional Instructions Support](https://www.textcontrol.com/blog/2021/05/31/forms-with-conditional-instructions-support/llms.txt)
- [Advantages of a Modern Contract Lifecycle Management](https://www.textcontrol.com/blog/2021/05/07/advantages-of-a-modern-contract-lifecycle-management/llms.txt)
- [Collaboration: New Annotations Sample](https://www.textcontrol.com/blog/2021/05/05/collaboration-new-annotations-sample/llms.txt)
- [Text Control eSign Demo: Reusable Templates](https://www.textcontrol.com/blog/2021/04/30/text-control-esign-demo-reusable-templates/llms.txt)
- [eSign Online Demo: Contract Collaboration Workflows](https://www.textcontrol.com/blog/2021/04/23/esign-online-demo-contract-collaboration-workflows/llms.txt)
- [Creating PDF Documents from MS Word DOCX in C#](https://www.textcontrol.com/blog/2021/02/26/creating-pdf-documents-from-ms-word-docx-in-csharp/llms.txt)
- [Creating Adobe PDF Forms in C#](https://www.textcontrol.com/blog/2021/02/10/creating-adobe-pdf-forms-in-csharp/llms.txt)
- [Extract ZUGFeRD/Factur-X XML Attachments from Adobe PDF/A-3b Documents](https://www.textcontrol.com/blog/2021/01/18/extract-zugferd-facturx-attachments-from-adobe-pdf-documents/llms.txt)
