# Creating Invoices from DOCX Templates in C# from Scratch

> This tutorial shows how to create an invoice using TX Text Control .NET Server from scratch including creating a template, merging data and to generate the resulting PDF.

- **Author:** Bjoern Meyer
- **Published:** 2022-11-01
- **Modified:** 2025-11-16
- **Description:** This tutorial shows how to create an invoice using TX Text Control .NET Server from scratch including creating a template, merging data and to generate the resulting PDF.
- **9 min read** (1675 words)
- **Tags:**
  - ASP.NET
  - Invoice
  - JSON
- **Web URL:** https://www.textcontrol.com/blog/2022/11/01/creating-invoices-from-docx-templates-in-csharp-from-scratch/
- **LLMs URL:** https://www.textcontrol.com/blog/2022/11/01/creating-invoices-from-docx-templates-in-csharp-from-scratch/llms.txt
- **LLMs-Full URL:** https://www.textcontrol.com/blog/2022/11/01/creating-invoices-from-docx-templates-in-csharp-from-scratch/llms-full.txt

---

Generating invoices in business applications is a very typical scenario for digital document processing. In this tutorial, the required steps of generating an invoice in a C# ASP.NET Core application is shown:

- Template creation
- Data merging
- PDF generation

#### Resulting Template

First, let's have a look at a typical invoice template (later, we will create a more simplistic version of it). The following animation is alternating between the template with placeholders and with merged data:

![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/animation_merge.webp "Invoice creation with TX Text Control")

> **Download Template**
> 
> This template is discussed in another blog post that also provides links to download the template and JSON data.
> 
> [Creating Templates: Typical Invoice Elements ](https://www.textcontrol.com/blog/2019/04/16/typical-invoice-elements/llms-full.txt)

### JSON Data

JSON data is used as the data source that is merged into the template. This JSON data string is also beginning of the template creation process. The JSON file is loaded into the *DocumentEditor* to provide the user ("template designer") the available merge field names.

The following JSON data contains the typical elements that should be included on an invoice including invoice meta data, information about the payer, the sold products and payment information. In this sample, the total amount, tax and discount values are calculated using formulas in the template itself.

```
[
    { 
        "invoice" : {
            "number" : "R2019041151",
            "date" : "4/15/2019",
            "duedate" : "5/15/2019",
            "discount" : 15,
            "tax": 7.5
        },
        "company" : {
            "name" : "Text Control, LLC",
            "street" : "6676 Text Control Rd",
            "address" : "28210 Charlotte, NC",
            "country" : "United States"
        },
        "payer" : {
            "companyname" : "Payer Corporation",
            "name" : "Peter Jackson",
            "street" : "2212 Payer Dr",
            "address" : "28210 PayCity, NC",
            "country" : "United States"
        },
        "payment" : {
            "routing" : "7783478",
            "account" : "877874627654"
        },
        "items" : [
            {
                "product" : "Product 1",
                "description" : "Description Product 1",
                "qty" : 2,
                "unitprice": 6762
            },
            {
                "product" : "Product 2",
                "description" : "Description Product 2",
                "qty" : 1,
                "unitprice": 222
            },
            {
                "product" : "Product 3",
                "description" : "Longer Description Product 3 with more text than product 1 and 2",
                "qty" : 6,
                "unitprice": 122.88
            }
        ]
    }  
]
```

### Creating the Template

Assuming that you created an ASP.NET Core web application according to our [getting started tutorial](https://www.textcontrol.com/blog/2022/09/01/getting-started-document-editor-with-aspnet-core/llms-full.txt), the following steps describe how to load the JSON data into the document editor to insert available merge fields.

1. In the *Solution Explorer*, select your project and insert a new folder by clicking *Project -> New Folder* from the main menu. Name this folder *App\_Data*.
2. Create a new JSON file in that folder and name it *data.json*. Copy and paste the content of the JSON file above into the newly created file.
3. Find the *Index.cshtml* file in the *Views -> Home* folder. Replace the complete content with the following code to add the document editor to the view:
    
    ```
    @using TXTextControl.Web.MVC
    	    
    @{
    	var jsonData = File.ReadAllText("App_Data/data.json");
    }
    
    @Html.TXTextControl().TextControl().LoadDataFromJson(jsonData).Render()
    ```

After the document editor is initialized, all available merge fields and merge blocks are listed in the drop-down lists in the *Reporting* tab:

![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template1.webp "Invoice creation with TX Text Control")

This way, users can focus on creating and designing the template and don't have to care about proper merge field names that can be added to a template. Let's start to design the template by adding merge fields.

1. Insert the string *Invoice:* and select *invoice -> number* from the *Insert Merge Field* drop-down list.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template2.webp "Invoice creation with TX Text Control")
    
    > **Pro Tip**
    > 
    > By looking at the name of the inserted field (*invoice.number*), you can see that it uses the dot-notation to access fields from a child table. This way, you can access field columns of any level in the data hierarchy.
2. Repeat the same for the field *invoice -> date*. After adding the field, click the field with the mouse to set the input position into it and choose *Field Properties* from the ribbon bar.
    
    In the dialog, set the *Date / time format* to *dddd, MM/dd/yyyy*. This defines a custom string formatter for this field.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template3.webp "Invoice creation with TX Text Control")
3. Click on *Preview* to see first results.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template4.webp "Invoice creation with TX Text Control")
    
    You can close the preview by clicking the *Exit* button in the opened contextual ribbon tab.
4. Following the above steps, insert as many fields from the data source as required into the template.

#### Inserting Merge Blocks

A merge block (or repeating block) is a reporting element that repeats content based on data rows. A merge block can contain anything including tables, paragraphs or single words. Typically, a table row is repeated that represents an invoice line item in our scenario.

1. Click *items* in the list of available merge blocks from the *Insert Merge Block* drop-down list.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template5.webp "Invoice creation with TX Text Control")
2. In the opened dialog, select all columns and move the item *product* to top as this should be our first table column.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template6.webp "Invoice creation with TX Text Control")
3. After confirming with *OK*, a table is added that consists of a repeating table header and the actual merge block that is highlighted in red. Manually, you can change the column titles to reflect proper descriptions.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template7.webp "Invoice creation with TX Text Control")
4. Click on *Preview* to see the first merge block results.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template8.webp "Invoice creation with TX Text Control")
    
    You can close the preview by clicking the *Exit* button in the opened contextual ribbon tab.
5. Resize the table columns using the mouse interface to provide the inserted columns a better ratio:
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template9.webp "Invoice creation with TX Text Control")
6. Set the input position into the field *unitprice* and set the alignment to top/right in the *Table Layout* ribbon tab.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template10.webp "Invoice creation with TX Text Control")
7. Back in the *Reporting* tab, select *Field Properties* to change the properties of the field *unitprice*. As it is a currency, set the value of the *Numeric format* to *C* or to your desired format such as *$##.##,##*.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template11.webp "Invoice creation with TX Text Control")
8. In the *Preview*, the currency values are perfectly aligned and formatted in the desired format.
    
    ![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/template12.webp "Invoice creation with TX Text Control")

Using the document editor, there are various ways to save the document for example using the JavaScript API by sending it to a Web API controller method. This is shown in another blog article:

[Loading and Saving Documents Through Controller HttpPost Methods](https://www.textcontrol.com/blog/2016/11/15/x14-preview-build-your-own-template-designer-with-the-new-datasourcemanager-class/llms-full.txt)

For TX Text Control, the template format can be any supported document format. You can save the template as an Office Open XML (DOCX) document, as RTF or in the internal TX Text Control format. In the next steps, we will use the internal TX Text Control format.

### Merging the Data

In the next step, the template is merged with the actual data. Typically, this is done server-side in a non-UI process.

> **Pro Tip**
> 
> The JSON data loaded into the Document Editor is not necessarily the actual data, but only dummy data with the correct structure or hierarchy. When merging the data into the template, you can use any form of data object (IEnumerable) with the same structure and naming.

Assuming that you created an ASP.NET Core web application according to our [getting started tutorial](https://www.textcontrol.com/blog/2022/09/01/getting-started-servertextcontrol-and-mailmerge-with-aspnet-core/llms-full.txt), the following steps describe how to load the prepared template and to how to merge it with JSON data.

1. In the *Solution Explorer*, select your project and insert a new folder by clicking *Project -> New Folder* from the main menu. Name this folder *App\_Data*.
2. Copy the created template into this folder and name it *template.tx*.
3. Create a new JSON file in that folder and name it *data.json*. Copy and paste the content of the JSON file above into the newly created file.
4. Find the *HomeController.cs* file in the *Controllers* folder. Replace the *Index()* method with the following code:
    
    ```
    public IActionResult Index() {
    
      // load the JSON data
      string jsonData = System.IO.File.ReadAllText("App_Data/data.json");
    
      using (TXTextControl.ServerTextControl tx = new TXTextControl.ServerTextControl()) {
        tx.Create();
    
        // load the template
        tx.Load("App_Data/template.tx", TXTextControl.StreamType.InternalUnicodeFormat);
    
        // use MailMerge to merge data
        using (TXTextControl.DocumentServer.MailMerge mm =
              new TXTextControl.DocumentServer.MailMerge()) {
          mm.TextComponent = tx;
          mm.MergeJsonData(jsonData);
        }
    
        // return result as HTML
        string result = "";
        tx.Save(out result, TXTextControl.StringStreamType.HTMLFormat);
    
        ViewBag.Document = result;
      }
    
      return View();
    }
    ```

In the above method, the template is merged automatically with data from the JSON string. The results are returned in form of an HTML document that is rendered in the view:

![Invoice creation with TX Text Control](https://s1-www.textcontrol.com/assets/dist/blog/2022/11/01/a/assets/results.webp "Invoice creation with TX Text Control")

In order to create a PDF from the results, the document can be simply exported as an Adobe PDF using this code in the controller method:

```
byte[] baPdf;
tx.Save(out baPdf, TXTextControl.BinaryStreamType.AdobePDF);
```

### Getting Started

You will find this tutorial and many more in our *Getting Started* tutorial collection:

[Getting Started](https://www.textcontrol.com/product/tx-text-control-dotnet-server/getting-started/)

---

## 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

- [Automatically Mapping TX Text Control Form Fields to JSON Data in .NET C#](https://www.textcontrol.com/blog/2026/06/03/automatically-mapping-tx-text-control-form-fields-to-json-data-in-dotnet-csharp/llms.txt)
- [Adjusting the Maximum Request Length for ASP.NET Core and ASP.NET Applications](https://www.textcontrol.com/blog/2024/04/12/adjusting-the-maximum-request-length-for-asp-net-core-and-asp-net-applications/llms.txt)
- [How to Detect and Extract Table Data as JSON from PDF Documents in C#](https://www.textcontrol.com/blog/2023/08/15/how-to-detect-and-extract-table-data-as-json-from-pdf-documents-in-csharp/llms.txt)
- [Generating Hierarchical Tables from JSON Data in .NET C#](https://www.textcontrol.com/blog/2023/08/03/generating-hierarchical-tables-from-json-data-in-csharp/llms.txt)
- [Typical Use-Case: Invoice Generation with TX Text Control in C#](https://www.textcontrol.com/blog/2023/03/19/typical-usecase-invoice-generation-with-tx-text-control-in-csharp/llms.txt)
- [Creating 100% Compliant ZUGFeRD and Factur-X Invoices using MailMerge in C#](https://www.textcontrol.com/blog/2023/02/09/creating-compliant-zugferd-and-facturx-invoices-using-mailmerge-in-csharp/llms.txt)
- [Using MailMerge Events to Remove Trailing Text in a Merge Block](https://www.textcontrol.com/blog/2022/11/07/using-mailmerge-events-to-remove-trailing-text-in-a-merge-block/llms.txt)
- [Mail Merge MS Word Office Open XML (DOCX) Templates in C#](https://www.textcontrol.com/blog/2022/05/05/mail-merge-ms-word-templates-in-csharp/llms.txt)
- [MailMerge: Field Mapping and Handling of Unmerged Fields](https://www.textcontrol.com/blog/2022/05/04/mailmerge-field-mapping-and-handling-of-unmerged-fields/llms.txt)
- [Invoice Deployment Strategies: Building an Invoice Portal](https://www.textcontrol.com/blog/2021/10/28/invoice-deployment-strategies/llms.txt)
- [Preparing ASP.NET for Long JSON Requests](https://www.textcontrol.com/blog/2021/05/20/preparing-asp-net-for-long-json-requests/llms.txt)
