ForgeDoc is a library for processing Word templates with placeholders and generating dynamic Word documents.
- Replace text placeholders in Word documents
- Add images to Word documents using
{% imageKey %}
syntax - Render tables in Word documents
- Support for rich text formatting
- Support for special characters with specific fonts (e.g., Wingdings)
- Works with headers, footers, and tables
ForgeDoc supports inserting images into Word documents using a special placeholder syntax:
{% imageKey %}
Where imageKey
is a key that references an image path you've added to the template data.
You can specify custom dimensions for your images using the following syntax:
{% imageKey:widthxheight %}
For example:
{% Logo:200x100 %}
This will resize the image to a maximum width of 200 pixels and a maximum height of 100 pixels, while maintaining the aspect ratio. If you don't specify dimensions, the default maximum size is 400x300 pixels.
- Make sure there are no spaces between the key and the colon:
{% Logo:200x100 %}
(correct) vs{% Logo: 200x100 %}
(incorrect) - Make sure there are no spaces in the dimensions:
200x100
(correct) vs200 x 100
(incorrect) - The full syntax should look exactly like:
{% SupervisorSignature:200x100 %}
// Create template data
var data = new WordTemplateData();
// Add image (path must be accessible at runtime)
data.AddImage("Logo", @"C:\path\to\logo.png");
data.AddImage("Signature", @"C:\path\to\signature.jpg");
// Process the template
var template = new WordTemplate("template.docx", data);
template.Process("output.docx");
You can also include images in tables by using the same placeholder syntax:
var tableData = new List<Dictionary<string, string>>
{
new Dictionary<string, string> { { "Name", "John Doe" }, { "SignatureKey", "Signature1" } },
new Dictionary<string, string> { { "Name", "Jane Smith" }, { "SignatureKey", "Signature2" } }
};
// Add the table data
data.AddTable("Employees", tableData);
// Add the images
data.AddImage("Signature1", @"C:\path\to\john_signature.png");
data.AddImage("Signature2", @"C:\path\to\jane_signature.png");
In your Word template, use:
{{#docTable Employees}}
Name: {{ item.Name }}
Signature: {% {{ item.SignatureKey }} %}
{{/docTable}}
When working with images from a database, save them to temporary files first:
// Save database image to a temporary file
string tempPath = Path.Combine(Path.GetTempPath(), $"signature_{Guid.NewGuid()}.png");
File.WriteAllBytes(tempPath, databaseImageBytes);
// Add the image to the template data
data.AddImage("Signature", tempPath);
// Remember to clean up temporary files after processing
try {
if (File.Exists(tempPath)) {
File.Delete(tempPath);
}
} catch {
// Handle cleanup errors
}
The processor supports common image formats:
• PNG • JPEG/JPG • GIF • BMP • TIFF
Images are inserted at their original size.
ForgeDoc supports three ways to render tables in Word documents:
Use the following syntax in your Word template to define where a table should be rendered:
{{#docTable tableName}}
{{item.column1}} {{item.column2}}
{{/docTable}}
This will create a new table at the location of the placeholder, with one row for each item in the table data.
You can also use placeholders directly in an existing table in your Word document:
| Header 1 | Header 2 | Header 3 |
|------------|------------|------------|
| {{column1}} | {{column2}} | {{column3}} |
The processor will replace the placeholders with values from the first row of data and duplicate the row for each additional data item.
ForgeDoc also supports a mixed syntax approach where you can have both table placeholders and regular placeholders in the same table:
| Header 1 | Header 2 | Header 3 |
|------------|------------|------------|
| {{#docTable tableName}}{{column1}} | {{column2}} | {{column3}}{{/docTable}} |
In this case, the processor will:
- Identify the table that contains the
{{#docTable}}
tag - Replace all placeholders in the row with values from the data
- Duplicate the row for each data item in the table data
- Remove any remaining table tags
This is particularly useful for complex tables with headers in different languages or when working with existing template documents.
ForgeDoc supports special characters with specific fonts in Word templates. This feature is particularly useful for inserting symbols like checkmarks, bullets, and other special characters that require specific fonts like Wingdings, Wingdings 2, Symbol, etc.
In your Word template, use the standard placeholder syntax with double curly braces:
{{CheckMark}}
When setting up your template data, use the AddSpecialCharacter
method to specify the character and its font:
var data = new WordTemplateData();
// Add a special character with a specific font
// \uf052 is a checkmark in Wingdings 2 font
data.AddSpecialCharacter("CheckMark", "\uf052", "Wingdings 2");
Here are some common special characters in the Wingdings 2 font:
Character | Unicode | Description |
---|---|---|
\uf052 | U+F052 | Checkmark |
\uf06E | U+F06E | Circle |
\uf06F | U+F06F | Square |
\uf070 | U+F070 | Diamond |
\uf071 | U+F071 | Triangle |
\uf0FC | U+F0FC | Arrow Right |
\uf0FB | U+F0FB | Arrow Left |
\uf0FC | U+F0FC | Arrow Up |
\uf0FD | U+F0FD | Arrow Down |
// Create template data
var data = new WordTemplateData();
// Add regular placeholders
data.AddPlaceholder("Title", "Special Character Example");
// Add special characters with specific fonts
data.AddSpecialCharacter("CheckMark", "\uf052", "Wingdings 2");
data.AddSpecialCharacter("Square", "\uf06F", "Wingdings 2");
data.AddSpecialCharacter("Circle", "\uf06E", "Wingdings 2");
// Create and process the template
var template = new WordTemplate("template.docx", data);
byte[] result = template.GetFile();
- The character must be provided as a Unicode escape sequence (e.g.,
\uf052
) or as the actual character. - The font name must exactly match the font name in Word (e.g., "Wingdings 2", "Symbol", etc.).
- This feature works in all parts of the document, including headers, footers, and tables.
// Create a new WordTemplateData object
var data = new WordTemplateData
{
Placeholders = new Dictionary<string, string>
{
{ "Title", "My Document" },
{ "Author", "John Doe" },
{ "Date", DateTime.Now.ToString("yyyy-MM-dd") }
}
};
// Create a new WordTemplate object
var template = new WordTemplate("path/to/template.docx", data);
// Get the generated document as a byte array
byte[] document = template.GetFile();
var data = new WordTemplateData
{
Placeholders = new Dictionary<string, string>
{
{ "Title", "My Document with Images" }
},
Images = new Dictionary<string, string>
{
{ "Logo", "path/to/logo.png" },
{ "Signature", "path/to/signature.jpg" }
}
};
In your Word template, use {% Logo %}
and {% Signature %}
to place the images.
Tables can be added to your Word template using the following syntax:
{{#docTable tableName}}
{{item.column1}} {{item.column2}} {{item.column3}}
{{/docTable}}
In your code, add the table data like this:
var tableData = new List<Dictionary<string, string>>
{
new Dictionary<string, string>
{
{ "column1", "Row 1, Column 1" },
{ "column2", "Row 1, Column 2" },
{ "column3", "Row 1, Column 3" }
},
new Dictionary<string, string>
{
{ "column1", "Row 2, Column 1" },
{ "column2", "Row 2, Column 2" },
{ "column3", "Row 2, Column 3" }
}
};
data.AddTable("tableName", tableData);
The table will be rendered with one row for each item in the list, and one column for each placeholder in the template.
Here's a complete example of using all features:
var data = new WordTemplateData
{
Placeholders = new Dictionary<string, string>
{
{ "Title", "Inventory Report" },
{ "Date", DateTime.Now.ToString("yyyy-MM-dd") },
{ "PreparedBy", "John Doe" }
},
Images = new Dictionary<string, string>
{
{ "CompanyLogo", "path/to/logo.png" },
{ "Signature", "path/to/signature.jpg" }
}
};
// Add inventory items table
var inventoryItems = new List<Dictionary<string, string>>
{
new Dictionary<string, string>
{
{ "itemName", "Laptop" },
{ "quantity", "10" },
{ "price", "1200.00" }
},
new Dictionary<string, string>
{
{ "itemName", "Monitor" },
{ "quantity", "15" },
{ "price", "300.00" }
},
new Dictionary<string, string>
{
{ "itemName", "Keyboard" },
{ "quantity", "20" },
{ "price", "50.00" }
}
};
data.AddTable("inventory", inventoryItems);
var template = new WordTemplate("inventory_template.docx", data);
byte[] document = template.GetFile();
In your Word template, you would have:
Title: {{Title}}
Date: {{Date}}
Prepared By: {{PreparedBy}}
Company Logo: {% CompanyLogo %}
Inventory Items:
{{#docTable inventory}}
{{item.itemName}} {{item.quantity}} {{item.price}}
{{/docTable}}
Signature: {% Signature %}
This project is licensed under the MIT License - see the LICENSE file for details.