HTMLWriter

Sometimes you might need to use a technology in a way it wasn’t intended because it has some features that you find useful. Displaying html in a web browser control inside a Winforms application can be useful because it provides built-in support things like printing and exporting data.

There are multiple ways to generate html source code – some ways are not recommended like concatenating strings or even hard-coding text inside the application. A few years ago I came across a library to write RTF (Rich Text Format) that gave me an idea how to write a small little utility class to create html fragments or even documents.

The main goal of the library is to make it easy to create html fragments without much code from the calling application but allow it to be flexible enough to be extended if needed. Internally it use a StringBuilder so it creates a mutable string that makes it much more efficient in handling larger fragments of text/html.

The heart of the library/class is one method:

private void AppendInternal(string value)
{

if (!string.IsNullOrEmpty(value))

{

sbHtmlContent.Append(value);

}

}

Then the rest of the methods follow the pattern – call the AppendInternal in various ways to generate the final html e.g.

public HTMLWriter AppendRAW(string tagName)
{

this.AppendInternal(tagName);
return this;

}

One additional thing you might notice is that the method returns a reference to the containing class. This is a useful  trick so you can queue up methods to group them together if they all contribute to one common goal.

Then you have to remember that html (like xml and other markup languages) require (most) elements/tags to have corresponding closing tags. To make it easier to ‘remember’ what html tag needs to be closed there is a stack object that stores the appended tags that get ‘pop’ of the stack when the AppendTagEnd() method gets called.

There is also a CustomAttribute helper class to help add custom attributes for some html tag that requires it. Think about the href attribute for the anchor (<a >) tag or colspan/rowspan attributes for the td tag.

To illustrate these points look at the following methods:

public HTMLWriter AppendTagStart(string tagName, string className, params CustomAttribute[] customAttributes)
{

this.AppendInternal(string.Format(“<{0}”, tagName));
if (className.Length > 0)

this.AppendInternal(string.Format(” class=\”{0}\””, className));

foreach (CustomAttribute customAttribute in customAttributes)
{

this.AppendInternal(” ” + customAttribute.ToString());

}
this.AppendInternal(“>”);
tags.Push(tagName);
return this;

}

public HTMLWriter AppendTagEnd()
{

if (tags.Count > 0)
{

string tagName = tags.Pop();
this.AppendInternal(“</” + tagName + “>”);

}
return this;

}

Now using these methods to create – say the anchor tag, would look like this:

public HTMLWriter AppendAnchorStart(string url, string className, string title)
{

return AppendTagStart(“a”, className,
new CustomAttribute(“href”, url),
new CustomAttribute(“title”, title);

}

If you want to create full html documents it also provides support for stylesheets. This is handled similarly, but separately with a StringBuilder class that is combined when you call the final ToString() method to retrieve the whole html document.

As a final example look at the following piece of code to create a table:

HTMLWriter h = new HTMLWriter(“Test”);

h.AppendTableStart(“main”, new CustomAttribute(“border”, “0”))
.AppendTableRowStart()
.AppendTableHeaderCellStart()
.AppendRAW(“Name”)
.AppendTagEnd()
.AppendTableHeaderCellStart()
.AppendRAW(“Surname”)
.AppendTagEnd()
.AppendTagEnd()
.AppendTableRowStart()
.AppendTableCellStart(“”, new CustomAttribute(“colspan”, “2”))
.AppendRAW(“test2”)
.AppendTagEnd()
.AppendTagEnd()
.AppendTagEnd();

The output looks like this:

<table class=”main” border=”0″><tr><th>Name</th><th>Surname</th></tr><tr><td colspan=”2″>test2</td></tr></table>

Finally (for now) there is an extension to the class (since it is a partial class) that can handle DataTable objects (like in DataSets). It makes it possible to simply pass a DataTable object to the library and it generates a complete html table with column names, rows and even alternating background colors for rows.

If you like you can download and try the library (at your own risk 😉 ). Find it here.

Update: using this library you can reference only the Framework Client Profile oppose to the full .Net framework. This can help to reduce the total download/install size.

Update: if you need to Normalize html nicely you can use another library you can find at http://systemhtml.codeplex.com.

  1. HTMLWriter 1.1 | Rudolf's mind - pingback on 2011/05/03 at 20:32

Leave a Reply

Trackbacks and Pingbacks:

%d bloggers like this: