Tuesday, June 23, 2009

Ruby & Word: Inserting Tables

Microsoft Word is great for text documents. Microsoft Excel is great for tables of data. But, sometimes, you need to get your chocolate in your peanut butter. In other words, you may occasionally need to include a table in a Word document. Let's walk through how to do that.

Setting the Stage

To borrow an example from my upcoming book, let's say that you want to insert a table that contains a list of all movies starring Spencer Tracy and Katharine Hepburn, including the year each movie was released, the title, and the director. Your 2-dimensional films array might look like this:


films = []
films << ["1942", "Woman of the Year", "George Stevens"]
films << ["1942", "Keeper of the Flame", "George Cukor"]
films << ["1945", "Without Love", "Harold S. Bucquet"]
films << ["1947", "The Sea of Grass", "Elia Kazan"]
films << ["1948", "State of the Union", "Frank Capra"]
films << ["1949", "Adam's Rib", "George Cukor"]
films << ["1952", "Pat and Mike", "George Cukor"]
films << ["1957", "Desk Set", "Walter Lang"]
films << ["1967", "Guess Who's Coming to Dinner", "Stanley Kramer"]

Let's connect to a running instance of Word and use the currently selected document:

require 'win32ole'
word = WIN32OLE.connect('Word.Application')
doc = word.ActiveDocument

Moving to the End of the Document

First, let's move to the end of the document, where we'll add our new table. We do this by calling the Selection.EndKey() method, which moves the selection to the end of a word, line, or document. We'll pass this method a value of 6, which specifies that we want to move to the end of the document:

word.Selection.EndKey(6)

Adding a New Table

The Tables collection in Word's object model represents all the Table objects in a selection, range, or document. To add a new Table to a document, call the Document object's Tables.Add() method and pass it three parameters:

* The range object representing where the table is to be inserted
* The number of rows for the new table
* The number of columns for the new table

Now let's add a new table with one row and three columns (we'll add more rows later):

table = doc.Tables.Add(word.Selection.Range, 1, 3)

The Tables.Add() method returns a reference to the newly created table, which we have assigned to the cleverly named variable table.

Inserting Text into Table Cells

You can reference a single cell in a table by calling the Cell() method and passing it the row and column numbers (NOTE: the first row or column is represented by 1, not 0). Once you have your cell, you can set the text via its Range.Text property; so we add the header text as follows:

table.Cell(1, 1).Range.Text = 'Year'
table.Cell(1, 2).Range.Text = 'Film Title'
table.Cell(1, 3).Range.Text = 'Director'

Adding Rows

To add a row to your table, simply call the Table object's Rows.Add() method. Now that we've added the header text, let's iterate over our films array and add a new row to the table for each film and insert the text:

films.each_with_index do |film, r|
table.Rows.Add()
film.each_with_index do |field, c|
table.Cell(r + 2, c + 1).Range.Text = field
end
end

There you have it. Thanks for stopping by!

10 comments:

Anonymous said...

David,

These tips on Word and Excel are great value. They've saved me many an hour of experimentation. Thank you.

Ian.

David Mullet said...

Thank you very much, Ian!

David

shevy said...

Cool

I love those weekly hints :D

Anonymous said...

Looks Good.
I wanna know how to adddborder to the table??

Ashish

Anonymous said...

Does anyone know how to delete a table again? e.g the first table in the document.

Nadine

David Mullet said...

@Nadine:

Call the Delete() method on the table object. So, for example, where doc is your Document object, to delete the first table:

doc.Tables(1).Delete()

Note that the Tables collection has a 1-based (not zero-based) index.

-David

Erock said...

How do you add another table to the same document?

David Mullet said...

Erock:

To add a second table at the end of the document...

# Insert a paragraph break at end of document:
doc.Range.InsertParagraphAfter

# Move to the new endpoint of the document:
word.Selection.EndKey(6)

# Add your new table, using the Tables.Add() method, as before:
table2 = doc.Tables.Add(word.Selection.Range, 1, 3)

Unknown said...

I got to know, how to create a table.Can you please let me know hoe to prints contents of table present in a word file.

Unknown said...

Is there a way to merge cells in a column?