Products Technologies Demo Docs Blog Support Company

Store and Merge Templates in a Database using LiteDB and ASP.NET Core C#

Editing the template, storing it in a database, and then merging it is a typical workflow for TX Text Control. This example will show you how to create a new template and how to store it in a LiteDB database. The template is then loaded from the database and merged with data.

Store and Merge Templates in a Database using LiteDB and ASP.NET Core C#

A very typical application for the variety of components that are part of TX Text Control is the visual creation of templates that are stored in a database. Documents in formats such as PDF are created by merging data into the stored templates.

To store the templates, this sample application uses a file-based database called LiteDB. The templates are created using the Document Editor visual component, and the templates are finally merged using the MailMerge class.

Template Overview

When you start the application, you will see an overview of all the templates you have created.

Creating documents with TX Text Control

Data Excerpt Files

When you create a new template, the Document Editor is opened and dummy JSON data is generated to fill in the drop-down lists that contain the names of the fields that can be used.

Creating documents with TX Text Control

A simple invoice structure is used as the data source.

public class Invoice
{
        public string InvoiceID { get; set; }
        public Customer Customer { get; set; }
        public string InvoiceNumber { get; set; }
        public string InvoiceDate { get; set; }

        public List<LineItem> LineItems { get; set; }
}

public class LineItem
{
        public string LineItemID { get; set; }
        public string Description { get; set; }
        public string Quantity { get; set; }
        public string Price { get; set; }
        public string Tax { get; set; }
        public string Total { get; set; }
}

public class Customer
{
        public string CustomerID { get; set; }
        public string Name { get; set; }
        public string Email { get; set; }
        public string Phone { get; set; }

        public string Address { get; set; }
        public string City { get; set; }
        public string State { get; set; }

        public string Zip { get; set; }
        public string Country { get; set; }
}

The GetDummyInvoiceData method generates a dummy JSON file from the data structure, which is then used in the Document Editor.

public static string GetDummyInvoiceData()
{
        Invoice invoice = new Invoice
        {
                InvoiceID = "123456789",
                InvoiceNumber = "123456789",
                InvoiceDate = "2020-01-01",
                Customer = new Customer
                {
                        CustomerID = "123456789",
                        Name = "John Doe",
                        Email = ""
                },
                LineItems = new List<LineItem>
                {
                        new LineItem
                        {
                                LineItemID = "123456789",
                                Description = "Item 1",
                                Quantity = "1",
                                Price = "100.00",
                                Tax = "10.00",
                                Total = "110.00"
                        },
                        new LineItem
                        {
                                LineItemID = "123456789",
                                Description = "Item 2",
                                Quantity = "1",
                                Price = "100.00",
                                Tax = "10.00",
                                Total = "110.00"
                        },
                        new LineItem
                        {
                                LineItemID = "123456789",
                                Description = "Item 3",
                                Quantity = "1",
                                Price = "100.00",
                                Tax = "10.00",
                                Total = "110.00"
                        }
                }
        };

        List<Invoice> invoices = new List<Invoice>();
        invoices.Add(invoice);

        return JsonConvert.SerializeObject(invoices);
}

Creating the Editor

In the controller method Editor, the dummy data is created, and if an existing template is to be opened, the template is retrieved from the database.

public IActionResult Editor(string id = null)
{
    EditorViewModel model = new EditorViewModel()
    {
        InvoiceData = InvoiceData.GetDummyInvoiceData(),
        DocumentId = id
    };

    if (id != null)
    {
        // url encoded
        id = id.Replace("%2F", "/");

        model.TemplateData = Storage.GetTemplate(id);
    }

        return View(model);
}

In the view itself, the data and template are loaded into a Document Editor instance.

@{
    if (Model.TemplateData != null)
    {
        @Html.TXTextControl().TextControl().LoadDataFromJson(Model.InvoiceData).LoadText(Convert.FromBase64String(Model.TemplateData), TXTextControl.Web.BinaryStreamType.InternalUnicodeFormat).Render()
    }
    else
    {
        @Html.TXTextControl().TextControl().LoadDataFromJson(Model.InvoiceData).Render()
    }
}

Template Storage

Once the template with merge fields and repeating blocks is created, the template can be saved using the Save button.

Creating documents with TX Text Control

The saveDocument JavaScript function saves the document and posts it to the Home/Save endpoint along with the document ID.

function saveDocument() {
    TXTextControl.saveDocument(TXTextControl.StreamType.InternalUnicodeFormat, function (content) {
        $.ajax({
            type: "POST",
            url: "/Home/Save?id=@Model.DocumentId",
            contentType: "application/json",
            data: JSON.stringify(content),
            success: function () {
                setDirtyFlag();
                $("#save").addClass("disabled");
            },
            error: function () {
                alert("An error occurred while saving the data.");
            }
        });
    });
}

The endpoint calls the Storage.AddTemplate method with the document data and ID.

[HttpPost]
public IActionResult Save([FromBody] Content data, string id)
{
    Storage.AddTemplate(new MemoryStream(Convert.FromBase64String(data.Data)), id);
    return Ok();
}

This method uses LiteDB to store the file in the database with the unique identifier.

private static readonly LiteDatabase db = new LiteDatabase(@"Filename=App_Data/documents.db; Connection=shared");

 public static void AddTemplate(MemoryStream stream, string id = null, string name = "template.tx")
 {
     var templateId = id ?? "$/templates/" + Guid.NewGuid().ToString();

     db.FileStorage.Upload(templateId, name, stream);
 }

Mail Merge

When you click Merge, the template is retrieved from the database and merged with the invoice data.

Creating documents with TX Text Control

A PDF is created and downloaded directly.

Creating documents with TX Text Control

The Merge method retrieves the template from the database by the given ID and uses MailMerge to merge the invoice data into the template.

public IActionResult Merge(string id)
{
    // url encoded
    id = id.Replace("%2F", "/");

    var templateData = Storage.GetTemplate(id);

    using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl())
    {
        tx.Create();
        tx.Load(Convert.FromBase64String(templateData), TXTextControl.BinaryStreamType.InternalUnicodeFormat);
        
        using (MailMerge mailMerge = new MailMerge())
        {
            mailMerge.TextComponent = tx;
            mailMerge.MergeJsonData(InvoiceData.GetDummyInvoiceData());
        }
        
        tx.Save(out byte[] data, TXTextControl.BinaryStreamType.AdobePDF);

        // return pdf document
        return File(data, "application/pdf", "document.pdf");
    }
}

To see how the database interface works to store templates and merge data into them to generate PDF documents, you can download the full sources of this sample.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

GitHub

Download and Fork This Sample on GitHub

We proudly host our sample code on github.com/TextControl.

Please fork and contribute.

Download ZIP

Open on GitHub

Open in Visual Studio

Requirements for this sample

  • TX Text Control .NET Server Core
  • Visual Studio 2022

Related Posts

ASP.NETASP.NET CoreDOCX

Use MailMerge in .NET on Linux to Generate Pixel-Perfect PDFs from DOCX…

This article explores how to use the TX Text Control MailMerge feature in .NET applications on Linux to generate pixel-perfect PDFs from DOCX templates. This powerful combination enables…


ASP.NETASP.NET CoreContract

Generating Dynamic NDAs Using TX Text Control MailMerge in C# .NET

This article demonstrates how to generate dynamic NDAs using TX Text Control MailMerge in C# .NET. It covers the process of creating a template, binding data, and generating the final document.


ASP.NETASP.NET CoreBackend

Designing a Maintainable PDF Generation Web API in ASP.NET Core (Linux) C#…

This article shows how to create a PDF generation Web API in ASP.NET Core on Linux using TX Text Control .NET Server. The clean architecture is used to create a maintainable and testable solution.


ASP.NETDockerLinux

Getting Started: ServerTextControl and MailMerge in a .NET 8 Console…

This article shows how to create a .NET 8 console application on Linux using Docker and WSL that uses the ServerTextControl to create a document and MailMerge to merge JSON data into the document.…


ASP.NETASP.NET CoreMailMerge

Manipulating Table Cells During the MailMerge Process in .NET C#

This article shows how to manipulate table cells during the mail merge process in .NET C#. The FieldMerged event can be used to manipulate the table cells after they are merged.