ComponentOne Word for WPF
Working with Word for WPF / Advanced Level Working / Inserting Table
In This Topic
    Inserting Table
    In This Topic

    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: