Add a row to an existing table in a Word Document (open XML)

38,762

Solution 1

Here you go,

Body bod = doc.MainDocumentPart.Document.Body;
foreach (Table t in bod.Descendants<Table>())
{
    t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}

Use LINQ to get the proper table.

EDIT:

Say you want to get the table that has 4 columns.

Body bod = doc.MainDocumentPart.Document.Body;
foreach (Table t in bod.Descendants<Table>().Where(tbl => tbl.GetFirstChild<TableRow>().Descendants<TableCell>().Count() == 4))
{
    t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}

Say you want to get the table that contains the word "mytable".

Body bod = doc.MainDocumentPart.Document.Body;
foreach (Table t in bod.Descendants<Table>().Where(tbl => tbl.InnerText.Contains("myTable")))
{
    t.Append(new TableRow(new TableCell(new Paragraph(new Run(new Text("test"))))));
}

Solution 2

Here is a more detailed example where you add 5 rows to a existing table.

This assumes that the table is the first one in the document. If not you have to find your table.

The code gets the last row of the table and copies it. After that you just need to fill in your data in the cells.

Table myTable = doc.Body.Descendants<Table>().First();
TableRow theRow = myTable.Elements<TableRow>().Last();
for (int i = 0; i < 5; i++)
{
    TableRow rowCopy = (TableRow)theRow.CloneNode(true);

    var runProperties = GetRunPropertyFromTableCell(rowCopy, 0);
    var run = new Run(new Text(i.ToString() + " 1"));
    run.PrependChild<RunProperties>(runProperties);

    rowCopy.Descendants<TableCell>().ElementAt(0).RemoveAllChildren<Paragraph>();//removes that text of the copied cell
    rowCopy.Descendants<TableCell>().ElementAt(0).Append(new Paragraph(run));
    //I only get the the run properties from the first cell in this example, the rest of the cells get the document default style. 
    rowCopy.Descendants<TableCell>().ElementAt(1).RemoveAllChildren<Paragraph>();
    rowCopy.Descendants<TableCell>().ElementAt(1).Append(new Paragraph(new Run(new Text(i.ToString() + " 2"))));
    rowCopy.Descendants<TableCell>().ElementAt(2).RemoveAllChildren<Paragraph>();
    rowCopy.Descendants<TableCell>().ElementAt(2).Append(new Paragraph(new Run(new Text(i.ToString() + " 3"))));

    myTable.AppendChild(rowCopy);
}
myTable.RemoveChild(theRow); //you may want to remove this line. I have it because in my code i always have a empty row last in the table that i copy.

The GetRunPropertiesFromTableCell is my quick hack attempt of using the same format for the text as the existing rows already have.

private static RunProperties GetRunPropertyFromTableCell(TableRow rowCopy, int cellIndex)
{
    var runProperties = new RunProperties();
    var fontname = "Calibri";
    var fontSize = "18";
    try
    {
        fontname =
            rowCopy.Descendants<TableCell>()
               .ElementAt(cellIndex)
               .GetFirstChild<Paragraph>()
               .GetFirstChild<ParagraphProperties>()
               .GetFirstChild<ParagraphMarkRunProperties>()
               .GetFirstChild<RunFonts>()
               .Ascii;
    }
    catch
    {
    //swallow
    }
    try
    {
        fontSize =
               rowCopy.Descendants<TableCell>()
                  .ElementAt(cellIndex)
                  .GetFirstChild<Paragraph>()
                  .GetFirstChild<ParagraphProperties>()
                  .GetFirstChild<ParagraphMarkRunProperties>()
                  .GetFirstChild<FontSize>()
                  .Val;
    }
    catch 
    {
    //swallow
    }
    runProperties.AppendChild(new RunFonts() { Ascii = fontname });
    runProperties.AppendChild(new FontSize() { Val = fontSize });
    return runProperties;
}
Share:
38,762

Related videos on Youtube

Nicole
Author by

Nicole

Updated on September 21, 2020

Comments

  • Nicole
    Nicole over 3 years

    I need to open an existing Word document (.docx) with an existing table (with, for example, 3 columns) and add a new row to that table. Is there any way of doing this? I am using Open XML

    I am creating the table like this (for the first time):

    Table tbl = new Table();
    
    // Set the style and width for the table.
    TableProperties tableProp = new TableProperties();
    TableStyle tableStyle = new TableStyle() { Val = "TableGrid" };
    
    // Make the table width 100% of the page width.
    TableWidth tableWidth = new TableWidth() { Width = "5000", Type = TableWidthUnitValues.Pct };
    
    // Apply
    tableProp.Append(tableStyle, tableWidth);
    tbl.AppendChild(tableProp);
    
    // Add 3 columns to the table.
    TableGrid tg = new TableGrid(new GridColumn(), new GridColumn(), new GridColumn());
    tbl.AppendChild(tg);
    
    // Create 1 row to the table.
    TableRow tr1 = new TableRow();
    
    // Add a cell to each column in the row.
    TableCell tc1 = new TableCell(new Paragraph(new Run(new Text("1"))));
    TableCell tc2 = new TableCell(new Paragraph(new Run(new Text("2"))));
    TableCell tc3 = new TableCell(new Paragraph(new Run(new Text("3"))));
    tr1.Append(tc1, tc2, tc3);
    
    // Add row to the table.
    tbl.AppendChild(tr1);
    return tbl;
    
  • Nicole
    Nicole about 11 years
    thanks!! how do I recognize/differ the tables?? thank you again!!
  • jn1kk
    jn1kk about 11 years
    Well, it depends on what feature you want to use to differentiate between them. See my edit or provide the feature you want to use.
  • mlg
    mlg over 9 years
    For some reason this code is not working for me. I tweaked the code for my use. private static RunProperties GetRunPropertyFromTableCell(TableRow rowCopy, int cellIndex) { var runProperties = new RunProperties(); foreach (var T in rowCopy.Descendants<TableCell>().ElementAt(cellIndex).GetFir‌​stChild<Paragraph>()‌​.GetFirstChild<Run>(‌​).GetFirstChild<RunP‌​roperties>()) { runProperties.AppendChild(T.CloneNode(true)); } return runProperties; }
  • Jéf Bueno
    Jéf Bueno about 6 years
    @jn1kk I tried to do that and the document is not being opened anymore. Word says: "not speficied error. Local: Part: /word/document.xml, row: 0, column: 0". Do you have any idea of what's possibly going wrong?