C# 向 Word 文档中的现有表格添加一行(打开 XML)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15622489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 17:24:07  来源:igfitidea点击:

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

c#ms-wordopenxml

提问by Nicole

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

我需要使用现有表格(例如,3 列)打开现有 Word 文档 (.docx) 并向该表格添加新行。有没有办法做到这一点?我正在使用 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;

采纳答案by jn1kk

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.

使用 LINQ 获取正确的表。

EDIT:

编辑:

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

假设您想要获得具有 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"))))));
}

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

假设您想要获取包含单词“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"))))));
}

回答by merger

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

这是一个更详细的示例,其中向现有表添加 5 行。

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.

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

回答by sreejith dinesan

here am adding rows to an existing table from dataset

这是从数据集中向现有表添加行

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

        }

    }