Fill a Word template in C# without Office
Somebody made invoice.docx in Word with {{customer}} where the name goes. This guide shows how to fill it from C#: text, repeating table rows and images, and how to check the result.
byte[] template = await HtmlToDocxConverter.ConvertAsync("<p>Customer: {{customer}}</p>");
byte[] filled = DocxEditor.ReplaceText(template, new Dictionary<string, string>
{
["{{customer}}"] = "Contoso Ltd",
});Placeholders that Word splits
- Word often splits a placeholder such as
{{customer}}into three or four separate<w:t>elements, for example after a typo fix or a spell check. - A find-and-replace over the XML then finds nothing and reports success.
ReplaceTextsplices the pieces back together before it matches.ReplaceTextalso reaches headers and footers, so a name in a letterhead is replaced too.- A key with no placeholder leaves the document unchanged. A placeholder with no key stays as literal text, such as
{{unknown}}.
One row per record
- Put one template row in the table and
FillRowsclones it once for each record. - Each new row keeps the template row's borders, shading, fonts and column widths.
- Expand rows first, then fill single values.
FillRowsclones the row, so a placeholder already inside it is copied into every line. - The collection name in the placeholder,
{{item.Desc}}, matches thecollectionargument,"item".
Swap in an image
ReplaceImageswaps a text placeholder for image bytes.- Sizes are in points. Give one size and the other scales to keep the aspect ratio.
- The format is decided by the bytes, never by a filename. A file called
logo.pngthat holds JPEG bytes is read as the JPEG it is.
Check the fill
ExtractTextreturns the document's text as a string, so a test can assert that the fill worked.- By default it leaves out headers and footers. Pass
includeHeadersAndFooters: trueto include them.
What it will not do
- Per-section headers and odd/even (mirrored) pages are not supported. A distinct first page is.
DocxBlockhas four factories,Heading,Paragraph,TableandImage. It is deliberately not a document model; for real layout control, use a template.- PDF fonts depend on the machine doing the conversion. With no fonts installed, the PDF falls back to the base-14 standard fonts. Both render, but they are not byte-identical.
Install
dotnet add package Ank.DocToolkitRead it in the DocToolkit docsNuGetGitHub