2017-06-04
Dynamically Resize Signature Field in Word Template (Like a Web Developer)
blogentry, programming, c, interop
blogentry, programming, c, interop
Suppose that you were working on merging client data with a Microsoft Word template and everything went well. And then boom, a week later, you are notified from a user that there was an issue with the generated Word file.
The template file contains a signature field, in which you merge a client's names. The issue is that some clients' names are so long, the signature field overflows into next line. This causes the rest of documents to create another page, thus wasting the formatting of the document as well as a paper unnecessarily.
If you are a Front-end/Web developer, you will understand the solution that I came up with.
I used C# and Word Interop. But the concept applies to any language.
If you have used CSS, the solution is quite simple; You right align a container (like a div) and left align the content in the container and the table size increases automatically. So here are the steps of resolution.
That's basically all the prep work required for the dynamically resizing table in Word template. All that's left is to calculate the signature field width and increase the table width with that of signature width if it's longer.
Now let's see the Word template.
It's a simple Word file with two bookmarks (two signature fields for comparisons).
There are two table properties that need to be changed/checked first.
Now let's dig into the code (At work, I used a library called Aspose Word for .NET to do the job, but since it's not free, I used Word Interop references in this demo).
Here is what the code does.
And the Main function looks as follows.
1public static void Main(string[] args)2{3 Application word = null;4 Document document = null;5
6 try7 {8 // Open Document9 word = new Application();10
11 var templatePath = Path.Combine(Directory.GetCurrentDirectory(), "BookmarkTest.docx");12 document = word.Documents.Open(templatePath);13
14 // Populate bookmarks.15 const string signer = "Anna Bertha Cecilia Diana Emily Fanny Gertrude Hypatia Inez Jane ";16 SetSignerBookmarks(word, document.Bookmarks, signer);17
18 // Find table and get table width (in Word, table collection is 1-based)19 var table = document.Tables[1];20 double tableWidth = GetTableWidth(table);21
22 // calculate text width23 var textWidth = CalculateTextWidth(signer);24
25 // increase the table size26 if (textWidth > tableWidth)27 UpdateTableWidth(table, textWidth);28 }29 finally30 {31 document?.Close();32 word?.Quit(WdSaveOptions.wdSaveChanges, WdOriginalFormat.wdOriginalDocumentFormat);33 }34}
Now the moment of truth. The output Word file looks like the following.
You can see that the 2nd signature line moved to the left to make a room for the long signature while the first one overflowed into next line.
The table border was left around to show you how it worked so remove the table border when you implement it.
The full source (the template file is included in the source as part of the solution) on GitHub.
The Word template hack was no difference from the Front-End solution. If you ever have a trouble dealing with Word templates, put your front-end knowledge into work.
The steps involved for this seems a bit cumbersome so I'd appreciate it if anyone can suggest me a lazier way to do this.