Добавить строку в существующую таблицу в Word Document (открыть XML)

Мне нужно открыть существующий документ Word (.docx) с существующей таблицей (например, с тремя столбцами) и добавить новую строку в эту таблицу. Есть ли способ сделать это? Я использую Open XML

Я создаю таблицу следующим образом (в первый раз):

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;

Ответ 1

Ну вот,

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"))))));
}

Используйте LINQ для получения правильной таблицы.

РЕДАКТИРОВАТЬ:

Предположим, вы хотите получить таблицу с 4 столбцами.

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"))))));
}

Скажем, вы хотите получить таблицу, содержащую слово "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"))))));
}

Ответ 2

Ниже приведен более подробный пример добавления 5 строк в существующую таблицу.

Это предполагает, что таблица является первой в документе. Если нет, вам нужно найти свой стол.

Код получает последнюю строку таблицы и копирует ее. После этого вам просто нужно заполнить свои данные в ячейках.

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.

GetRunPropertiesFromTableCell - это моя попытка быстрого взлома с использованием того же формата текста, что и существующие строки.

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;
}

Ответ 3

здесь я добавляю строки в существующую таблицу из набора данных

   DataTable dt = new DataTable();
    dt.Columns.Add("Gender");
    dt.Columns.Add("Passport");
    dt.Columns.Add("Name");
    foreach (RepeaterItem item in rptemplist.Items)
    {
        TextBox txtGender = (TextBox)item.FindControl("txtGender");
        TextBox txtPassport = (TextBox)item.FindControl("txtPassport");
        TextBox txtName = (TextBox)item.FindControl("txtName");
        dt.Rows.Add(new object[] { txtGender.Text, txtPassport.Text, txtName.Text });
    }

    using (WordprocessingDocument wordDoc2 = WordprocessingDocument.Open(file, true))
    {
        var doc = wordDoc2.MainDocumentPart.Document;
        DocumentFormat.OpenXml.Wordprocessing.Table table = doc.MainDocumentPart.Document.Body.Elements<DocumentFormat.OpenXml.Wordprocessing.Table>().FirstOrDefault();

        int icounterfortableservice;
        for (icounterfortableservice = 0; icounterfortableservice < dt.Rows.Count; icounterfortableservice++)
        {
            DocumentFormat.OpenXml.Wordprocessing.TableRow tr = new DocumentFormat.OpenXml.Wordprocessing.TableRow();
            DocumentFormat.OpenXml.Wordprocessing.TableCell tablecellService1 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(dt.Rows[icounterfortableservice]["Gender"].ToString()))));
            DocumentFormat.OpenXml.Wordprocessing.TableCell tablecellService2 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(dt.Rows[icounterfortableservice]["Passport"].ToString()))));
            DocumentFormat.OpenXml.Wordprocessing.TableCell tablecellService3 = new DocumentFormat.OpenXml.Wordprocessing.TableCell(new DocumentFormat.OpenXml.Wordprocessing.Paragraph(new DocumentFormat.OpenXml.Wordprocessing.Run(new DocumentFormat.OpenXml.Wordprocessing.Text(dt.Rows[icounterfortableservice]["Name"].ToString()))));
            tr.Append(tablecellService1, tablecellService2, tablecellService3);
            table.AppendChild(tr);

        }

    }