c# - 使用 openxml dll 以编程方式在 word 文档中放置自定义表格

标签 c# openxml

我正在使用 OpenXML dll 创建邮件合并文档。我有一个需求,需要在word文档中添加一个动态表格。目前我已经能够在文档末尾添加表格,但我需要将它添加到页面中间的某个位置。 我在word文档中有4页,这个表格必须添加到第3页的开头。我已经能够拿到 table 了。我唯一的问题是在此处添加表格。 以下是代码:

void createTemplate(string newFileName,string folderName,ArrayList mailMergeList,DataTable observations) 
    {
        FileInfo newFile = new FileInfo(newFileName);
        if (!IsFileLocked(newFile))
        {
            //declare and open a Word document object                
            WordprocessingDocument objWordDocx = WordprocessingDocument.Open(newFileName, true);
            //get the main document section of the document
            OpenXmlElement objMainDoc = objWordDocx.MainDocumentPart.Document;

            //var wordDoc = new Microsoft.Office.Interop.Word.Document();

            //Loop through merge fields
            string FieldDelimiter = " MERGEFIELD ";

            foreach (FieldCode field in objWordDocx.MainDocumentPart.RootElement.Descendants<FieldCode>())
            {
                var fieldNameStart = field.Text.LastIndexOf(FieldDelimiter, System.StringComparison.Ordinal);                    
                String fieldname = field.Text.Substring(fieldNameStart + FieldDelimiter.Length).Trim();
                fieldname = fieldname.Substring(0, fieldname.IndexOf(' '));                    
                //  fieldname
                var fieldValue = "";

                fieldValue = GetMergeValue(fieldname, mailMergeList);

                // Go through all of the Run elements and replace the Text Elements Text Property
                foreach (Run run in objWordDocx.MainDocumentPart.Document.Descendants<Run>())
                {
                    foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldname + "»"))
                    {
                        if (fieldname.Equals("ObservationsTable"))
                        {
                            //observations
                            if (observations.Rows.Count > 0) //only if there is data in the Resi Obs NOI sheet we need to create a table
                            {
                                txtFromRun.Text = CreateTable(objWordDocx, newFileName, observations).ToString();
                            }
                        }
                        else
                        {
                            txtFromRun.Text = GetMergeValue(fieldname, mailMergeList);
                        }
                    }
                }
            }
            //save this part
            objWordDocx.MainDocumentPart.Document.Save();
            //save and close the document
            objWordDocx.Close();
        }
    }

我在下面得到了一个解决方案,但它对我来说不可行,因为我没有使用 Word.Interop dll。

请指导。

最佳答案

这是一个打开的 xml 示例。我创建了一个虚拟表:

var tab = new Table();

for (var z = 0; z < 2; z++)
{
    var tr = new TableRow();

    for (var j = 0; j < 2; j++)
    {
       var tc = new TableCell();
       tc.Append(new Paragraph(new Run(new Text("i: " + z + " j:" + j))));
       tr.Append(tc);
    }

    tab.Append(tr);
}

在我的 word.docx 中我有:

一些文字 “ table ” 一些其他的文字

并遍历合并字段:

WordprocessingDocument objWordDocx = WordprocessingDocument.Open(newFileName, true);
OpenXmlElement objMainDoc = objWordDocx.MainDocumentPart.Document;

foreach (var field in objMainDoc.Descendants<SimpleField>())
{
    if (field.Instruction.Value.Trim().EndsWith("Table"))
    {
        var tabRun = new Run(tab);
        field.Parent.ReplaceChild<SimpleField>(tabRun, field);
    }
}

objWordDocx.MainDocumentPart.Document.Save();
objWordDocx.Close();

编辑: 带有 FieldCode 的版本:

foreach (var field in objMainDoc.Descendants<FieldCode>())                
{
    if (field.InnerText.Trim().EndsWith("Table"))
    {
        var tabRun = new Run(tab);
        var anc = field.Ancestors<Paragraph>().FirstOrDefault();
        anc.RemoveAllChildren();
        anc.Append(tabRun);
    }
}

注意:这对我有用,因为我的段落中唯一的东西就是域代码。如果您的段落中有不应删除的内容,请修改代码。

关于c# - 使用 openxml dll 以编程方式在 word 文档中放置自定义表格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32607961/

相关文章:

C# 两个具有相互引用的静态成员的类

c# - 多个应用程序的通用 app.config

.net - 正则表达式组字符串,其中分隔符可以使用两次(.net 正则表达式)

c# - 如何使用 C# 隐藏 OpenXML 电子表格中的列?

c# - 使用 OpenXml 和 C# 删除 word 中的水印会损坏文档

linq - 使用 OpenXML 和 LINQ 读取 Excel 工作表的第一行

c# - 当我在组合框中选择一个项目时如何防止 TextChanged 事件?

c# - 如何在表单应用程序中获取参数?

pdf-generation - 从 OpenXml 生成 PDF

c# - child 不跟随 parent