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 TX Text Control .NET Server for ASP.NET
DocumentServer Namespace
MailMerge Class
The MailMerge class is a .NET component that can be used to effortlessly merge template documents with database content in .NET projects, such as ASP.NET web applications, web services or Windows services.
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; }
}
view raw test.cs hosted with ❤ by GitHub

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);
}
view raw test.cs hosted with ❤ by GitHub

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);
}
view raw test.cs hosted with ❤ by GitHub

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()
}
}
view raw test.cshtml hosted with ❤ by GitHub

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.");
}
});
});
}
view raw test.js hosted with ❤ by GitHub

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();
}
view raw test.cs hosted with ❤ by GitHub

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);
}
view raw test.cs hosted with ❤ by GitHub

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 TX Text Control .NET Server for ASP.NET
DocumentServer Namespace
MailMerge Class
The MailMerge class is a .NET component that can be used to effortlessly merge template documents with database content in .NET projects, such as ASP.NET web applications, web services or Windows services.
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");
}
}
view raw test.cs hosted with ❤ by GitHub

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.