When it comes to BUSINESS, Microsoft Office file formats reign supreme, and if you’re a software developer, you’ll inevitably be asked to convert data into one of the Office formats; it’s a law (look it up). Luckily for all of us, you aren’t the first, or the last, to be asked to perform such a task, which means there are open-source libraries to help you perform your duty as a business developer. Go business!

As luck would find it, I was scanning the Chinese .NET OSS scene when I came across the MiniWord project. MiniWord is a library that uses the OpenXML nature of .docx files to support a mail merge-like experience for developers. In this post, we’ll look at MiniWord and how you can use it to empower your business stakeholders to take your existing dataset and turn it into glorious Word documents.

What is MiniWord?

MiniWord uses Microsoft Word’s OpenXML format to provide a cross-platform library for completing document templates. The library lets you take any dataset and generate a new Word document for each entry. This seems straightforward, but MiniWord provides powerful templating features that make it worth checking out.

The process of creating a template starts with a tag. Tags use the {{ }} syntax to create placeholders in existing Word documents rather than the mail merge placeholders. Once tags are placed in a word document, you can give the library a dictionary where keys match the tags within the document.

var value = new Dictionary<string, object>()
{
    ["Name"] = "Jack",
    ["Department"] = "IT Department",
    ["Purpose"] = "Shanghai site needs a new system to control HR system.",
    ["StartDate"] = DateTime.Parse("2022-09-07 08:30:00"),
    ["EndDate"] = DateTime.Parse("2022-09-15 15:30:00"),
    ["Approved"] = true,
    ["Total_Amount"] = 123456,
};
MiniWord.SaveAsByTemplate(path, templatePath, value);

You can fill a seemingly generic Word document with information with just a few lines of C# code.

MinWord transforming a Microsoft Office word template to a complete document

You’re also not limited to text values. MiniWord supports adding text, images, lists, tables, colored text, and hyperlinks. That’s a lot of options for dynamic data.

Generated documents can be saved to disk, or results can be written to a Stream instance, which can be sent to a remote client using ASP.NET Core or a messaging library. You can see the supported methods provided by MiniWord below.

SaveAsByTemplate(string path, string templatePath, Dictionary<string, object> value)
SaveAsByTemplate(string path, byte[] templateBytes, Dictionary<string, object> value)
SaveAsByTemplate(this Stream stream, string templatePath, Dictionary<string, object> value)
SaveAsByTemplate(this Stream stream, byte[] templateBytes, Dictionary<string, object> value)

The provided methods make integrating MiniWord with a local filesystem to a distributed cloud solution straightforward. That’s pretty awesome!

Let’s get to a working sample.

Working with MiniWord

You’ll need to start with an existing .NET application, and for this post, I’ve created a console application. The first step is to install the MiniWord package. You can use your IDE’s NuGet tool, edit the project file, or run the following command.

dotnet add package MiniWord

Next, you’ll need a .docx, and in my case, I’m trying to get the word out about JetBrains Rider. You can paste the following into a Word document. If you’re on macOS (like I am), you can open Pages and export the file to a Word document.


Hello, {{FirstName}} {{LastName}}, 

We hear you like programming in .NET. May I suggest you check out JetBrains Rider at https://jetbrains.com/rider?

JetBrains Rider’s support is world-class for {{Framework}}, and it’s all powered by ReSharper.

Cheers,
  
Khalid Abuhakmeh
JetBrains .NET Advocate

You’ll need to place the newly created .docx file in your project with a Copy to output directory option of Copy if newer. You can also choose to hardcode the path in the following code.

using MiniSoftware;  
  
var recipients = new[]  
{  
    new { FirstName = "Maarten", LastName = "Balliauw", Framework = "Razor Pages" },  
    new { FirstName = "Rachel", LastName = "Appel", Framework = "Blazor" },  
    new { FirstName = "Matt", LastName = "Ellis", Framework = "Unity" },  
    new { FirstName = "Matthias", LastName = "Koch", Framework = "Nuke" }  
};  
  
var template = File.ReadAllBytes("Advocacy.docx");  
  
foreach (var recipient in recipients)  
{  
    var values = ConvertToDictionary(recipient);  
    MiniWord.SaveAsByTemplate(  
        $"{recipient.FirstName}-{recipient.LastName}-advocacy.docx".ToLower(),  
        template,        values    );}  
  
// Generated in part by JetBrains AI Assistant  
// Prompt: I need a method that takes an anonymous  
//         C# object and converts it to a dictionary.  
static Dictionary<string, object> ConvertToDictionary<T>(T target)  
{  
    return typeof(T).GetProperties().ToDictionary(  
        prop => prop.Name,  
        prop => prop.GetValue(target, null)  
    )!;  
}

Running the code, you’ll get a new Word document for each instance in the recipients collection. The newly created assets would be under /bin/Debug/netX.0 unless you chose a different directory.

Opening any of the generated files, you’ll see the expected result.

Hello, Maarten Balliauw,

We hear you like programming in .NET. May I suggest you check out JetBrains Rider at https://jetbrains.com/rider?

JetBrains Rider’s support is world-class for Razor Pages, and it’s all powered by ReSharper.

Cheers,
 
Khalid Abuhakmeh
JetBrains .NET Advocate

Very cool. Now I can tell Maarten Balliauw how awesome JetBrains Rider and ReSharper are for becoming a productive .NET developer, all thanks to MiniWord!

Conclusion

MiniWord uses the OpenXML format, so it works cross-platform on Windows, macOS, and Linux without installing a copy of Microsoft Office on the local environment. The implementation can be critical in cloud-hosted scenarios. It also helps that the library’s author has provided implementations that support many scenarios. The support for various tag options also makes this more than just a search and replace tool, as you can build highly complex documents. If you’re looking for a library to empower your business stakeholders, check out MiniWord and give the author a star on their GitHub repository.

Thanks for reading and sharing this post with friends and colleagues.