Replace ,, and other placeholders in a .docx template.
IWordService word = new Regira.Office.Word.Spire.WordService();
byte[] templateBytes = await File.ReadAllBytesAsync("Templates/Invoice.docx");
IMemoryFile doc = await word.Create(new WordTemplateInput
{
Template = templateBytes.ToMemoryFile(),
GlobalParameters = new Dictionary<string, object>
{
["CustomerName"] = "Alice Corp",
["InvoiceDate"] = DateTime.Today.ToString("d"),
["InvoiceNo"] = "INV-2024-0042",
["Total"] = "€ 1 250,00"
}
});
await fileService.Save("invoices/INV-2024-0042.docx", doc.GetBytes()!);
The template contains a bookmark or placeholder row named Items. Each dictionary entry maps a column header to a cell value.
IMemoryFile doc = await word.Create(new WordTemplateInput
{
Template = templateBytes.ToMemoryFile(),
GlobalParameters = new Dictionary<string, object> { ["OrderNo"] = "ORD-001" },
CollectionParameters = new Dictionary<string, ICollection<IDictionary<string, object>>>
{
["Items"] = orderLines.Select(l => (IDictionary<string, object>)new Dictionary<string, object>
{
["Description"] = l.ProductName,
["Qty"] = l.Quantity,
["UnitPrice"] = l.UnitPrice.ToString("C"),
["LineTotal"] = l.LineTotal.ToString("C")
}).ToList()
}
});
byte[] logoBytes = await File.ReadAllBytesAsync("assets/logo.png");
IMemoryFile doc = await word.Create(new WordTemplateInput
{
Template = templateBytes.ToMemoryFile(),
Images =
[
new WordImage
{
Name = "CompanyLogo",
File = logoBytes.ToMemoryFile("image/png"),
Size = new ImageSize(200, 60)
}
]
});
IMemoryFile pdf = await word.Convert(
new WordTemplateInput { Template = docxFile },
new ConversionOptions
{
OutputFormat = FileFormat.Pdf,
AutoScaleTables = true,
AutoScalePictures = true,
Settings = new DocumentSettings { PageSize = PageSize.A4 }
});
var inputs = reportSections.Select(s => new WordTemplateInput
{
Template = s.TemplateBytes.ToMemoryFile(),
GlobalParameters = s.Parameters
}).ToArray();
IMemoryFile merged = await word.Merge(inputs);
string text = await word.GetText(new WordTemplateInput { Template = docxFile });
await searchIndex.AddDocumentAsync(documentId, text);
var images = (await word.ToImages(new WordTemplateInput { Template = docxFile })).ToList();
for (int i = 0; i < images.Count; i++)
await fileService.Save($"previews/page-{i + 1}.jpg", images[i].GetBytes()!);
Word.Mini fills the template and a Gotenberg server lays it out. Register both, with a PDF rasteriser for page previews:
services.AddSingleton<IImageService, Regira.Drawing.SkiaSharp.Services.ImageService>();
services.AddSingleton<IPdfToImageService, Regira.Office.PDF.DocNET.PdfManager>();
services.AddSingleton<IWordCreator, Regira.Office.Word.Mini.WordService>();
services.AddGotenbergWord(o => o.BaseUrl = configuration["Gotenberg:BaseUrl"]!);
The converter renders the template input through Word.Mini before it uploads it:
// IWordConverter converter, IWordToImagesService previews — injected
var input = new WordTemplateInput
{
Template = templateBytes.ToMemoryFile(),
GlobalParameters = new Dictionary<string, object> { ["CustomerName"] = "Alice" }
};
IMemoryFile pdf = await converter.Convert(input, FileFormat.Pdf);
IEnumerable<IImageFile> pages = await previews.ToImages(input);