4

I have a document with multiple tables in it. I need to fill some of those tables. The problem im having is how do i locate them? I can interate through them

var doc = document.MainDocumentPart.Document;
var tables= doc.Body.Elements< Table >();

But how do i find a specific table? The table can change so i cant rely on the order. I was thinking of placing a bookmark ahead of the specific table and just locate the first table after the bookmark, but i have failed to find out how to do that...

So, how do one find a specific table in a document?

If there is a better way of doing it please let me know.

merger
  • 698
  • 1
  • 10
  • 28
  • Do your table elements have a unique attribute (id or name) that you can use to identify them? Can you show how you find the correct table by iteration then perhaps we can help find a more efficient method. – tonycoupland Mar 20 '13 at 10:16
  • That's the problem. I cant find a specific table. I can find all tables and iterate though them but i still don't know more about the tables than what order they come in. As far as i know i cant tag/name tables? – merger Mar 20 '13 at 11:27

4 Answers4

12

Give the tables captions.

First in Word, create the tables, and right click one of them, Table Properties, Alt Text, fill in the Title box, save, close.

Now in OpenXML, find the table with specific captions.

IEnumerable<TableProperties> tableProperties = bd.Descendants<TableProperties>().Where(tp => tp.TableCaption != null);
foreach(TableProperties tProp in tableProperties)
{
    if(tProp.TableCaption.Val.Equals("myCaption")) // see comment, this is actually StringValue
    {
        // do something for table with myCaption
        Table table = (Table) tProp.Parent;
    }
}
jn1kk
  • 5,012
  • 2
  • 45
  • 72
  • 1
    That worked really nice. But i had to change the Val.Equals("...") to Val == "...". Equals did not trigger on a string. Val is of the type StringValue....go figure :) – merger Mar 21 '13 at 09:41
  • @Merger, oh, forgot about that. Don't know why MSFT decided to use `StringValue` in OpenXML. – jn1kk Mar 21 '13 at 13:28
  • 1
    There is also one other thing that should be noted. You have to use Word 2010+ for Alt Text to work. – merger Mar 22 '13 at 09:20
  • 1
    Not the solution for the given question (not using bookmarks) but way more elegant (and you have to love good code) – Pedro Laguna Dec 17 '13 at 12:15
4

This article describes a neat solution using Content Controls:

http://msdn.microsoft.com/en-us/library/cc197932(v=office.12).aspx

John
  • 1,043
  • 15
  • 20
1

A bit more elegant solution to this, using bookmarkstart as a locator would be

BookmarkStart bookmark = YourBookMarkStart;
OpenXmlElement elem = bookmark.First().Parent;
//isolate tabel
while (!(elem is DocumentFormat.OpenXml.Wordprocessing.Table))
    elem = elem.Parent;
var table = elem; //found
Kaspar Kjeldsen
  • 936
  • 1
  • 13
  • 30
0

I found a solution. It's not the prettiest solution i have come up with but it seems to work. At least on the documents that i have tried.

I create my table. Insert a Bookmark anywhere in the table and then find the bookmark.

var bookmarkStart = doc.Body.Descendants<BookmarkStart>().Where(r => r.Name == "tableBookmark");
if (bookmarkStart != null)
{
    var test  = bookmarkStart.First().Parent.Parent.Parent.Parent;
    if (test.GetType() == typeof (DocumentFormat.OpenXml.Wordprocessing.Table))
        myTable = (Table)test;
}

Please feel free to give me a better solution!!! :) For instance I'm probably going to make a recursive method that finds the tables instead of using Parent.Parent.Parent.Parent

merger
  • 698
  • 1
  • 10
  • 28