How Do I Bring a Microsoft Word Table into a DataGridView?

WordTableToDataGridView.jpg

Figure 1 - Word Table Brought into a DataGridView

Introduction

This Article was written in response to the question:  "How do I bring a Word Table into a DataGridView?".   Again, we turn to Office Interoperability to take us from the contents of  a Word Document to a table in a Windows Form.  Luckily, with the aid of VSTO (Visual Studio Tools for Office), we can use C# (instead of painstaking VBA)  to bring our Table out of the Word COM model, into an interactive grid control in a Windows Form. 

Steps to Setting up a Programmable Word Document

By going through the .NET Project Wizard, we can set up a Microsoft Word Project which will hook us directly into the VSTO framework inside a Word Document.  Just choose Office under the Visual C# Project, and pick a Word Document.  This will create a project which will already provide us with the Word Document start up event handler.  This gives us a good spot to place our table export code.

WordTableProject.jpg

Figure 2 - Opening a Word Document Project

Getting a Table Out of Word

We want to start by extracting the Word Table in Figure 1 into a structure we can pass back to our DataGridView.  Luckily, the COM Object Model in Word has a Tables Collection of all Tables contained inside our Word Document.  For this example, we just want to export the first table.  Listing 1 shows us out to obtain a reference to the first table in a Word Document.  Note that all collections in Word start at index 1 rather than index 0.  Admittedly this does take some getting used to.  It's easier to adapt to base indexes starting at 1 if you think of COM in the back of your mind as a completely different animal than the .NET framework. (One can only hope that someday the COM animal will hobble away, but alas, it is so prevalent in office that it continues to live on).

Listing 1 - Getting the First Table From Word

// get the first table of the Word Document
// (collections in Office COM models start at 1)


Word.
Table firstTable = this.Tables[1];

Once we have our word table, we can loop through all the rows and save the data inside the row in a string collection.  The contents of each value in the row is contained in a Cell, and inside the cell we have a Range object containing our Text.  Ranges are another concept throughout Office that takes some getting used to.  Everytime I see it, I can't help singing to myself, "Home, Home, on the Range", but that is just my mind trying to blot out the confusion I'm having trying to get a handle on Ranges.  It would be nice if you could get the value inside the cell from the Cell object directly. 

After we get the contents of each cell from the Range,  we'll send the row values to our DataGridView. The first row of the Word table is our header text and all the other rows are the body of the table.  We'll use the AddHeader method that we created in our form to add the header to the DataGridView and we'll use the AddWordTableRow method to add each data row.

Listing 2 - Extracting Row Information from a Word Table

// loop through the rows in the table and send the contents of the row
// to the DataGridView

int count = 0;
foreach (Word.Row row in firstTable.Rows)
 {
  
List<string> cellValues = new List<string>();
  
foreach (Word.Cell cell in row.Cells)
    {
      
string cellContents = cell.Range.Text;

// add the cell contents to the array, but remove the strange termination character on the end of the data
       cellValues.Add(cellContents.Remove(cellContents.Length - 1));
    }

    // the first row is the column header
     if (count == 0)
     {
        form.AddHeader(cellValues);
     }
  
else
    {
       form.AddWordTableRow(cellValues);
    }

    count++;
}

Importing the Row Data into the DataGridView

Now that we have gotten that COM strangeness out of our system, we can bring the data into our easy-to-use and sensibly architected DataGridView.  To create the Header from our Word string array, we just need to set the header text of each column object in the DataGridView as shown in listing 3. 

Listing 3 - Exporting the Word Table Header to the DataGridView Header

internal void AddHeader(List<string> cellValues)
{
  NameColumn.HeaderText = cellValues[0];
  AddressColumn.HeaderText = cellValues[1];
  PhoneColumn.HeaderText = cellValues[2];
  EmailColumn.HeaderText = cellValues[3];
}

We can also quickly add the data from a row in the Word Table directly into a row of the DataGridView using the Add method in the Rows collection of the DataGridView.

Listing 4 - Exporting the Word Table Data to the DataGridView

public void AddWordTableRow(string name, string address, string phone, string email)
{
    dataGridView1.Rows.Add(
new string[]{name, address, phone, email});
}

public void AddWordTableRow(List<string> cellValues)
 {
   
DataGridViewRow dr = new DataGridViewRow();
    AddWordTableRow(cellValues[0], cellValues[1], cellValues[2], cellValues[3]);
 }

Running

Running the application brings up an instance of Microsoft Word showing our Word table from figure 1 followed immediately by the matching DataGridView.  The one good thing about COM is that as long as the COM model is consistent across versions, this code should work for 2003 as well as 2007 Word (It may even work with Office 2000 with some slight adjustments), so you can give this solution a try with your existing Word Application.

Conclusion

Exporting Tables in Word requires us to visit the Word COM Model.  Although it takes a bit of getting acquainted,  the Word COM model provides us with the tools we need to pull out Column or Row information in order to export into any .NET control or structure we wish.  The DataGridView is a reasonable choice because it gives us a lot of flexibility in manipulating the data once we've populated the table.  Anyway, hope you find this article useful to help you  a-range  your word tables with the added assistance of C# and .NET.

Up Next
    Ebook Download
    View all
    Learn
    View all