[]
Table is used in word documents to present data in a well formatted form with the help of rows and columns.
Note that two classes named WordUtils and DataAccess are used in the code given below. These classes are available in the product sample located at the following location on your system:
Documents\ComponentOne Samples\WPF\WordCreator
You can use these classes in your application from the mentioned location.
Word for WPF enables you to add structure to a word document using the following code:
' get the data
Dim ds = DataAccess.GetDataSet()
' calculate page rect (discounting margins)
Dim rcPage As Rect = WordUtils.PageRectangle(word)
Dim rc As Rect = rcPage
' add title
Dim titleFont As New Font("Tahoma", 24, RtfFontStyle.Bold)
rc = WordUtils.RenderParagraph(word, word.Info.Title, titleFont, rcPage, rc, False)
' render some tables
RenderTable(word, rc, rcPage, ds.Tables("Customers"), New String() {"CompanyName", "ContactName", "Country", "Address", "Phone"})
// get the data
var ds = DataAccess.GetDataSet();
// calculate page rect (discounting margins)
Rect rcPage = WordUtils.PageRectangle(word);
Rect rc = rcPage;
// add title
Font titleFont = new Font("Tahoma", 24, RtfFontStyle.Bold);
rc = WordUtils.RenderParagraph(word, word.Info.Title, titleFont, rcPage, rc, false);
// render some tables
RenderTable(word, rc, rcPage, ds.Tables["Customers"], new string[]
{ "CompanyName", "ContactName", "Country", "Address", "Phone" });
The following code can be used to select the font for the content of the table and build the table:
' select fonts
Dim hdrFont As New Font("Tahoma", 10, RtfFontStyle.Bold)
Dim txtFont As New Font("Tahoma", 8)
' build table
'word.AddBookmark(table.TableName, 0, rc.Y);
rc = WordUtils.RenderParagraph(word, "NorthWind " + table.TableName, hdrFont, rcPage, rc, False)
' build table
rc = RenderTableHeader(word, hdrFont, rc, fields)
For Each dr As DataRow In table.Rows
rc = RenderTableRow(word, txtFont, hdrFont, rcPage, rc, fields, _
dr)
Next
' done
Return rc
// select fonts
Font hdrFont = new Font("Tahoma", 10, RtfFontStyle.Bold);
Font txtFont = new Font("Tahoma", 8);
// build table
//word.AddBookmark(table.TableName, 0, rc.Y);
rc = WordUtils.RenderParagraph(word, "NorthWind " + table.TableName, hdrFont, rcPage, rc, false);
// build table
rc = RenderTableHeader(word, hdrFont, rc, fields);
foreach (DataRow dr in table.Rows)
{
rc = RenderTableRow(word, txtFont, hdrFont, rcPage, rc, fields, dr);
}
// done
return rc;
After building the table, you need to cell height and width of the table headers and rows, and then render them using the following code:
Private Shared Function RenderTableHeader(word As C1WordDocument, font As Font, rc As Rect, fields As String()) As Rect
' calculate cell width (same for all columns)
Dim rcCell As Rect = rc
rcCell.Width = rc.Width / fields.Length
rcCell.Height = 0
' calculate cell height (max of all columns)
For Each field As String In fields
Dim height = word.MeasureString(field, font, rcCell.Width).Height
rcCell.Height = Math.Max(rcCell.Height, height)
Next
rcCell.Height += 6
' add 6 point margin
' render header cells
Dim fmt = New StringFormat()
fmt.LineAlignment = VerticalAlignment.Center
For Each field As String In fields
word.FillRectangle(Colors.Black, rcCell)
word.DrawString(field, font, Colors.White, rcCell, fmt)
rcCell = WordUtils.Offset(rcCell, rcCell.Width, 0)
Next
' update rectangle and return it
Return WordUtils.Offset(rc, 0, rcCell.Height)
End Function
Private Shared Function RenderTableRow(word As C1WordDocument, font As Font, hdrFont As Font, rcPage As Rect, rc As Rect, fields As String(), _
dr As DataRow) As Rect
' calculate cell width (same for all columns)
Dim rcCell As Rect = rc
rcCell.Width = rc.Width / fields.Length
rcCell.Height = 0
' calculate cell height (max of all columns)
rcCell = WordUtils.Inflate(rcCell, -4, 0)
For Each field As String In fields
Dim text As String = dr(field).ToString()
Dim height = word.MeasureString(text, font, rcCell.Width).Height
rcCell.Height = Math.Max(rcCell.Height, height)
Next
rcCell = WordUtils.Inflate(rcCell, 4, 0)
' add 4 point margin
rcCell.Height += 2
' break page if we have to
If rcCell.Bottom > rcPage.Bottom Then
word.PageBreak()
rc = RenderTableHeader(word, hdrFont, rcPage, fields)
rcCell.Y = rc.Y
End If
' center vertically just to show how
Dim fmt As New StringFormat()
fmt.LineAlignment = VerticalAlignment.Center
' render data cells
For Each field As String In fields
' get content
Dim text As String = dr(field).ToString()
' set horizontal alignment
Dim d As Double
fmt.Alignment = If((Double.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, d)), HorizontalAlignment.Right, HorizontalAlignment.Left)
' render cell
word.DrawRectangle(Colors.LightGray, rcCell)
rcCell = WordUtils.Inflate(rcCell, -4, 0)
word.DrawString(text, font, Colors.Black, rcCell, fmt)
rcCell = WordUtils.Inflate(rcCell, 4, 0)
rcCell = WordUtils.Offset(rcCell, rcCell.Width, 0)
Next
' update rectangle and return it
Return WordUtils.Offset(rc, 0, rcCell.Height)
End Function
static Rect RenderTableHeader(C1WordDocument word, Font font, Rect rc, string[] fields)
{
// calculate cell width (same for all columns)
Rect rcCell = rc;
rcCell.Width = rc.Width / fields.Length;
rcCell.Height = 0;
// calculate cell height (max of all columns)
foreach (string field in fields)
{
var height = word.MeasureString(field, font, rcCell.Width).Height;
rcCell.Height = Math.Max(rcCell.Height, height);
}
rcCell.Height += 6; // add 6 point margin
// render header cells
var fmt = new StringFormat();
fmt.LineAlignment = VerticalAlignment.Center;
foreach (string field in fields)
{
word.FillRectangle(Colors.Black, rcCell);
word.DrawString(field, font, Colors.White, rcCell, fmt);
rcCell = WordUtils.Offset(rcCell, rcCell.Width, 0);
}
// update rectangle and return it
return WordUtils.Offset(rc, 0, rcCell.Height);
}
static Rect RenderTableRow(C1WordDocument word, Font font, Font hdrFont, Rect rcPage, Rect rc, string[] fields, DataRow dr)
{
// calculate cell width (same for all columns)
Rect rcCell = rc;
rcCell.Width = rc.Width / fields.Length;
rcCell.Height = 0;
// calculate cell height (max of all columns)
rcCell = WordUtils.Inflate(rcCell, -4, 0);
foreach (string field in fields)
{
string text = dr[field].ToString();
var height = word.MeasureString(text, font, rcCell.Width).Height;
rcCell.Height = Math.Max(rcCell.Height, height);
}
rcCell = WordUtils.Inflate(rcCell, 4, 0); // add 4 point margin
rcCell.Height += 2;
// break page if we have to
if (rcCell.Bottom > rcPage.Bottom)
{
word.PageBreak();
rc = RenderTableHeader(word, hdrFont, rcPage, fields);
rcCell.Y = rc.Y;
}
// center vertically just to show how
StringFormat fmt = new StringFormat();
fmt.LineAlignment = VerticalAlignment.Center;
// render data cells
foreach (string field in fields)
{
// get content
string text = dr[field].ToString();
// set horizontal alignment
double d;
fmt.Alignment = (double.TryParse(text, NumberStyles.Any, CultureInfo.CurrentCulture, out d))
? HorizontalAlignment.Right
: HorizontalAlignment.Left;
// render cell
word.DrawRectangle(Colors.LightGray, rcCell);
rcCell = WordUtils.Inflate(rcCell, -4, 0);
word.DrawString(text, font, Colors.Black, rcCell, fmt);
rcCell = WordUtils.Inflate(rcCell, 4, 0);
rcCell = WordUtils.Offset(rcCell, rcCell.Width, 0);
}
// update rectangle and return it
return WordUtils.Offset(rc, 0, rcCell.Height);
}
The above code creates a table from the information taken from the Nwind database with proper indentation and alignment in a word document.
The output of the above code will look similar to the image given below: