【问题标题】:Add a row to an existing table in a Word Document (open XML)向 Word 文档中的现有表添加一行(打开 XML)
【发布时间】:2013-03-25 18:51:22
【问题描述】:

我需要使用现有表格(例如,3 列)打开现有 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;

【问题讨论】:

    标签: c# ms-word openxml


    【解决方案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"))))));
    }
    

    【讨论】:

    • 谢谢!!我如何识别/区分表格?再次感谢您!
    • 嗯,这取决于您要使用什么功能来区分它们。查看我的编辑或提供您要使用的功能。
    • @jn1kk 我尝试这样做,但文档不再被打开。 Word 说:“未指定错误。本地:部分:/word/document.xml,行:0,列:0”。您知道可能出了什么问题吗?
    【解决方案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;
    }
    

    【讨论】:

    • 由于某种原因,这段代码对我不起作用。我调整了代码供我使用。 private static RunProperties GetRunPropertyFromTableCell(TableRow rowCopy, int cellIndex) { var runProperties = new RunProperties(); foreach (var T in rowCopy.Descendants&lt;TableCell&gt;().ElementAt(cellIndex).GetFirstChild&lt;Paragraph&gt;().GetFirstChild&lt;Run&gt;().GetFirstChild&lt;RunProperties&gt;()) { runProperties.AppendChild(T.CloneNode(true)); } 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);
    
            }
    
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多