Sunday, 31 January 2016

HTML to WordML

Introduction

The code provided creates a new docx document based on a previously created template.
The templates have bookmarks in the document body, header and footer. Their content is set dynamically.
It also supports the insertion of HTML formatted content in the document body.

Background

This solution is based on this article by Praveen Bonakurthi. I made his code a bit more user friendly and added the HTML functionality.

Getting Started

First, you need to create a docx template. Just open Word and create the file as you please.
In the areas where you want to insert plain text, just select the area and go to the ribbon toolbar, insert>bookmark, give it a unique name. You can apply Word formatting to the text that will be inserted later.

Setting HTML Content Locations

For HTML content, it's a bit more tricky. So just finish up adding all bookmarks for the plain text before you do this step.
Change the docx extension to zip. Open it and open Word/document.xml with any editor you like (I just use Notepad).
Place <w:altChunk r:id="IdForTheHtmlContent" /> nodes under the <w:body> node.
Replace "IdForTheHtmlContent" with whatever unique id you want.
Put them where you want the HTML to appear.
Save the file back when you're done. Change the extension back to .docx.
Now you got your template ready to be used!

Using the Code

There are just 2 methods to be used:
public static string CreateWordDocument(string templatePath, 
	Dictionary<string, string> Bookmarks, Dictionary<string, string> 
	BookmarksHeaderFooter, Dictionary<string, string> HtmlChunks) 
Defined in the class MyWordMLHTMLClasses.WordMl, this method is responsible for the creation of the document.
The method...
private void ReturnStream(string filepath, bool DeleteFileAfter) 
... returns the generated file in the HTTP Response stream and may or not delete it later.
This is how you use it:
// get values ready for insert in the docx file
Dictionary<string, string> bookmarks = new Dictionary<string, string>();
Dictionary<string, string> bookmarksHeaderFooter = new Dictionary<string, string>();
Dictionary<string, string> htmlChunks = new Dictionary<string, string>();
// HTML chuncks in the document area
htmlChunks.Add("S_Teste", "<b>Text HTML</b>" + 
"<br />simple html text after br<br /> " + 
"<table style=\"width:250px;\"><tr>" + 
"<td>html table cell 1</td>" + 
"<td>html table cell 2</td></tr><tr>" + 
"<td>html table cell 3</td>" + 
"<td>html table cell 4</td>" + 
"</tr></table>");
// bookmarks in the document area
bookmarks.Add("S_ADDRESS_V1", "Adress line 1");
bookmarks.Add("S_ADDRESS_V2", "Adress line 2");
// bookmarks in Header/Footer
bookmarksHeaderFooter.Add("FOOTER_1_1", "Inserted Footer Text");
bookmarksHeaderFooter.Add("FOOTER_1_2", "123");
bookmarksHeaderFooter.Add("HEADER5", "Inserted Header Text");

// generate docx file from template docx
string fileName = WordML.CreateWordDocument(
    Server.MapPath(@"~\_Documents\MyTemplate.docx"), // template docx path
    bookmarks, // bookmarks and Values
    bookmarksHeaderFooter, // header/footer bookmarks and Values
    htmlChunks // HTML chunks to be inserted 
    );

// returns file in stream, deletes it afterwards 
//(if option is selected as in this case)
ReturnStream(fileName, true);

Points of Interest

I did some extensive searching to find any HTML to Word ML snippet. Got nothing close to a finished snippet, so this may be useful.
If too many people find it hard to understand, I'll edit and post a better explanation on how to use the stuff.
Download the code, it will probably be simple to understand after watching it in action.

How To Use It On Your Projects?

  1. Download the code.
  2. Copy the WordML.cs to your project folder and add it to your project in Visual Studio.
  3. Add a reference to windowsbase.dll.
  4. Use it as shown above.

No comments:

Post a Comment