DocxTemplater
DocxTemplater: C# library for generating DOCX documents with templates, supporting placeholders, loops, tables, charts, Markdown/HTML, and image embedding. Ideal for document automation.
Install / Use
/learn @Amberg/DocxTemplaterREADME
DocxTemplater
DocxTemplater is a library to generate docx documents from a docx template. The template can be bound to multiple datasources and be edited by non-programmers. It supports placeholder replacement, loops, and images.
Features
- Variable Replacement
- Collections - Bind to collections
- Conditional Blocks
- Images - Replace placeholder with Image data
- Chart Data Binding - Bind a chart to a data source
- Markdown Support - Converts Markdown to OpenXML
- HTML Snippets - Replace placeholder with HTML Content
- Dynamic Tables - Columns are defined by the datasource
Quickstart
Create a docx template with placeholder syntax:
This Text: {{ds.Title}} - will be replaced
Open the template, add a model, and store the result to a file:
var template = DocxTemplate.Open("template.docx");
// To open the file from a stream use the constructor directly
// var template = new DocxTemplate(stream);
template.BindModel("ds", new { Title = "Some Text" });
template.Save("generated.docx");
The generated word document will contain:
This Text: Some Text - will be replaced
Install DocxTemplater via NuGet
To include DocxTemplater in your project, you can install it directly from NuGet.
Run the following command in the Package Manager Console:
PM> Install-Package DocxTemplater
Additional Extension Packages
Enhance DocxTemplater with these optional extension packages:
| Package | Description
|--------------|-----------------------------------
| DocxTemplater.Images |Enables embedding images in generated Word documents|
| DocxTemplater.Markdown | Allows use of Markdown syntax for generating parts of Word documents|
Placeholder Syntax
A placeholder can consist of three parts: {{property:formatter(arguments)}}
- property: The path to the property in the datasource objects.
- formatter: Formatter applied to convert the model value to OpenXML (e.g.,
toupper,tolower,imgformat). - arguments: Formatter arguments - some formatters have arguments.
The syntax is case insensitive.
Quick Reference Examples
| Syntax | Description |
| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| {{SomeVar}} | Simple Variable replacement. |
| {?{someVar > 5}}...{{:}}...{{/}} | Conditional blocks. |
| {{#Items}}...{{Items.Name}} ... {{/Items}} | Text block bound to collection of complex items. |
| {{#Items}}...{{.Name}} ... {{/Items}} | Same as above with dot notation - implicit iterator. |
| {{#Items}}...{{.}:toUpper} ... {{/Items}} | A list of string all upper case - dot notation. |
| {{#Items}}{{.}}{{:s:}},{{/Items}} | A list of strings comma separated - dot notation. |
| {{SomeString}:ToUpper()} | Variable with formatter to upper. |
| {{SomeDate}:Format('MM/dd/yyyy')} | Date variable with formatting. |
| {?{!.IsHw && .Name.Contains('Item')}}...{{}} | Logical Expression with string operation. Careful; Word Replaces ' with ‘ and " with ”. |
| {{SomeDate}:F('MM/dd/yyyy')} | Date variable with formatting - short syntax. |
| {{(1 + 2)}} | Evaluate simple math expressions. |
| {{(ds.Name.ToUpper() + "!")}} | Expressions with variables and string operations. |
| {{(ds.Val?.ToString() ?? "N/A")}} | Expressions with null-conditional and coalescing operators. |
| {{(ds.Price * 1.19)}:f(c)} | Expressions with calculations and formatters. |
| {{SomeBytes}:img()} | Image Formatter for image data. |
| {{SomeHtmlString}:html()} | Inserts HTML string into the word document. |
| {{@i:ItemCount}}...{{i}}...{{/}} | Range loop that repeats its content ItemCount times. |
| {{#Items}}{?{Items._Idx % 2 == 0}}{{.}}{{/}}{{/Items}} | Renders every second item in a list. |
| {{#switch: SomeVar}}{{#case: 'A'}}...{{/}}{{#default}}...{{/}}{{/}} | Evaluates switch cases and renders the matching block. there is a short syntax too |
| {{:ignore}} ... {{/:ignore}} | Ignore DocxTemplater syntax, which is helpful around a Table of Contents. |
| {{:break}} | Insert a line break after this keyword block. |
| {{:PageBreak}} | Start a new page after this keyword block. |
| {{:SectionBreak}} | Start a new "Section Break" on the next page after this keyword block. |
Collections
To repeat document content for each item in a collection, use the loop syntax: {{#<collection>}} ... content ... {{</collection>}}
All document content between the start and end tag is rendered for each element in the collection:
{{#Items}} This text {{Items.Name}} is rendered for each element in the items collection {{/Items}}
This can be used, for example, to bind a collection to a table. In this case, the start and end tag have to be placed in the row of the table: | Name | Position | |--------------|-----------| | {{#Items}} {{Items.Name}} | {{Items.Position}} {{/Items}} |
This template bound to a model:
var template = DocxTemplate.Open("template.docx");
var model = new
{
Items = new[]
{
new { Name = "John", Position = "Developer" },
new { Name = "Alice", Position = "CEO" }
}
};
template.BindModel("ds", model);
template.Save("generated.docx");
Will render a table row for each item in the collection: | Name | Position | |-------|-----------| | John | Developer | | Alice | CEO |
Shortcut for Dot Notation - accessing the current item
To access the current item in the collection, use the dot notation {{.}}:
{{#Items}} This text {{.Name}} is rendered for each element in the items collection {{/Items}}
To access the outer item in a nested collection, use the dot notation {{..}} This is useful when you have nested collections and want to access a property from the outer scope:
{{#Items}} This text {{..SomePropertyFromTheOuterScope}} is rendered for each element in the items collection {{/Items}}
Accessing the Index of the Current Item
To access the index of the current item, use the special variable Items._Idx In this example, the collection is called "Items".
Range Loops
To repeat document content a specific number of times based on an integer count or the length of a collection without directly iterating over it, use the range loop syntax: {{@i:count}} ... content ... {{/}}
Here, count can be an integer, a string parseable to an integer, or an IEnumerable (in which case its count is used). The variable i is the index of the current iteration (starting from 0). If you omit the index variable name (e.g. {{@count}}), it defaults to Index.
Separator
To render a separator between the items in the collection, use the separator syntax:
{{#Items}} This text {{.Name}} is rendered for each element in the items collection {{:s:}} This is rendered between each element {{/Items}}
Chart Data binding
Charts can be fully styled within the template, and a data source can then be bound to each chart.
To bind a chart to a data source, the chart’s title in the template must match the property name in the model. MyChart

To bind the chart correctly, the corresponding model property must be of th ChartData type.
Currently, only bar charts are supported.
using var fileStream = F
