How to find the name of a table

Hello,

i’m currently trying to use aspose.words to modify some existing .odt document (openoffice text documents).

i have to fill a table in the doc with variable rows of variable contents, but i cannot find out how to get the name of the table i wish to add row (the doc have many tables).

table’s name is needed to identify the table i have to modify, so if there is another way to do this without the name is also ok.

thanks for your help
Giovanni

Hello Giovanni,

I believe that you have to refer to Word document tables in code by their (zero based) index. You can download a .NET project from Aspose called Document Explorer that will help you see the structure in your document and find the index for a given table.

I would love to be wrong about this, but I’ve never found a way to refer to tables by name. Hopefully the Aspose guys will have a better solution.

Good luck,

Randy

Hello Giovanni,

Thanks for your requests.

Randy, thank you for sharing your experience.

But I think in this case it would be better to use bookmarks. You can try inserting a Bookmark in a table, which you would like to find. Then you can use the following code to find the table:

Document doc = new Document("in.doc");

// Get bookmark
Bookmark bk = doc.Range.Bookmarks["bookmark"];
if (bk != null)
{
    // Get table, where bookmark is located.
    Node table = bk.BookmarkStart.GetAncestor(NodeType.Table);
    if (table != null)
    {
        // Work with table.
    }
}

Hope this helps.

Best regards,

Hi,

This is a good solution.

I had thought about bookmarks also but since the question was about finding tables by name I didn’t go there.

Is it correct then that tables cannot be accessed in code by a table name?

Thanks,

Randy

Hi

Thanks for your inquiry. Tables in MS Word do not have names. So there is no way to find tables using names.

Best regards,

Hi,

thank to all for your so fast reply.
Yes bookmark will solve the issue, but it will be a pain to put a bookmark in every one of many docs containing many tables…
Didnt know that ms do not have table names, but since i work only with opendocument format this do not touch me :wink:

i was wondering, at last solution, if there is a way to get the xml table-name property of the docs.
i create an empty doc, with only a table, named TableFindMe, in the content.xml there is this:
<table:table table:name="TableFindMe" table:style-name="TableFindMe">

is there a way to get this and then get the table in aspose.words?

thank again
Giovanni

Hi

Thank you for additional information. Unfortunately, there is no way to get name of tables specified in ODT document. I think as a workaround, you can find index of table with the specified name by parsing content.xml, and then get the appropriate table by index using Aspose.Words.

Best regards,

parsing the file, find the table index by name and use it is ok!

would you kindly post a sample code for how to do this?

thank you very much for your support!

Hi

Thanks for your inquiry. Could you please attach your sample document here? I will investigate it and try to provide you a sample code.

Best regards,

i really appreciate your help!

informativa.odt is a simple one, here i have 3 tables
newdps.odt is a more complex one, nearly every table in the doc must be replaced with compiled-copyes from other docs, containing only the actual table.

thank you
Giovanni

Hi

Thank you for additional information. We will use SharpZipLib to extract content.xml from ODT package. You can download the most recent version of SharpZipLib from here:

http://www.sharpziplib.com/

Then we should build map where key is table name and value is table index. Here is sample code how to achieve this:

[Test]
public void Test001()
{
    Hashtable nameIndexMap = GetNameindexMap(@"Test001\in.odt");

    // Open document using Aspose.Words.
    Document doc = new Document(@"Test001\in.odt");
    // Get all tables.
    Node[] tables = doc.GetChildNodes(NodeType.Table, true).ToArray();
    // For example wee need to get table with name "tabAcq".
    Table tabAcq = (Table)tables[(int)nameIndexMap["tabAcq"]];
    // Lets set background of this table.
    foreach (Row row in tabAcq.Rows)
    {
        foreach (Cell cell in row.Cells)
            cell.CellFormat.Shading.BackgroundPatternColor = Color.Red;
    }
    // Save output.
    doc.Save(@"Test001\out.doc");
}

/// <summary>
/// Returns tables name/index map.
/// </summary>
private Hashtable GetNameindexMap(string fileName)
{
    XmlDocument contentXml = GetContentXml(fileName);
    //Create an XmlNamespaceManager for resolving namespaces.
    XmlNamespaceManager nsmgr = new XmlNamespaceManager(contentXml.NameTable);
    nsmgr.AddNamespace("table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0");
    // Get all tables from the content.xml.
    XmlNodeList tables = contentXml.SelectNodes("//table:table", nsmgr);
    // Create map where key is name of table and value is index of the table.
    Hashtable nameIndexMap = new Hashtable();
    for (int tableIndex = 0; tableIndex < tables.Count; tableIndex++)
    {
        string tableName = tables[tableIndex].Attributes["table:name"].Value;
        if (!string.IsNullOrEmpty(tableName))
            nameIndexMap[tableName] = tableIndex;
    }
    return nameIndexMap;
}

/// <summary>
/// Extracts content.xml from ODT file.
/// </summary>
private XmlDocument GetContentXml(string fileName)
{
    XmlDocument contentXml = new XmlDocument();

    using (FileStream odtFile = File.OpenRead(@"Test001\in.odt"))
    {
        // Read ODT package.
        ZipFile odtPackage = new ZipFile(odtFile);
        // Look for content.xml entry.
        foreach (ZipEntry zipEntry in odtPackage)
        {
            if (zipEntry.Name.ToLower() == "content.xml")
            {
                // Extract content.xml entry.
                byte[] buffer = new byte[4096];
                Stream zipStream = odtPackage.GetInputStream(zipEntry);
                using (MemoryStream contentStream = new MemoryStream())
                {
                    StreamUtils.Copy(zipStream, contentStream, buffer);
                    contentStream.Position = 0;
                    using (StreamReader contentReader = new StreamReader(contentStream))
                        contentXml.Load(contentReader);
                }
                break;
            }
        }
    }
    return contentXml;
}

Hope this could help you. Please let me know if you need more assistance, I will be glad to help you.

Best regards,

Hi

thank you very much for you help, i never found a support fast and kind like yours :slight_smile:

i have tryed the code you post, and it work perfectly with informative.odt… but when i tryed to apply it to another doc (same code you wrote but different file) i noticed that it do not get the right table… but the one before the right one.

i try with the attached doc (disciplinareint.odt), and the table named “tabinctr”
i also try with the newdps.odt that attach in prev post, and it seem to get some table well (tabfinal, tabbdati) and other not as well (tabrischi’s rows are putted in tadistr)

any idea why is not work with that?

thank you
Giovanni

Hi

Thanks for your inquiry. The problem occurs because there is one more table in the document header. And when you use the following code to select tables in the document, this table is included into the list:

Node[] tables = doc.GetChildNodes(NodeType.Table, true).ToArray();

To resolve the problem you should select tables only in body. Please see the following modified code:

[Test]
public void Test001()
{
    Hashtable nameIndexMap = GetNameindexMap(@"Test001\DisciplinareInt.odt");

    // Open document using Aspose.Words.
    Document doc = new Document(@"Test001\DisciplinareInt.odt");
    // Get all tables.
    Node[] tables = doc.SelectNodes("//Body//Table").ToArray();
    Console.WriteLine(tables.Length);
    // For example wee need to get table with name "tabAcq".
    Table tabAcq = (Table)tables[(int)nameIndexMap["tabinctr"]];
    // Lets set background of this table.
    foreach (Row row in tabAcq.Rows)
    {
        foreach (Cell cell in row.Cells)
            cell.CellFormat.Shading.BackgroundPatternColor = Color.Red;
    }
    // Save output.
    doc.Save(@"Test001\out.doc");
}

Hope this helps.

Best regards,

yeah man, that did the job!

again, i want to express my gratitude for the help you give me.

have a nice day
Giovanni