首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用OpenXMl填充MergeField

使用OpenXMl填充MergeField
EN

Stack Overflow用户
提问于 2016-05-30 13:24:32
回答 2查看 3.1K关注 0票数 1

我正在尝试使用OpenXML用我的数据替换word文件中的合并字段。

我认为代码中没有问题,因为有时它在一些模板中工作得很好,有时合并字段没有被替换。

在word模板中插入Mergefield有问题吗?我不知道问题出在哪里。

下面是我使用的代码:

代码语言:javascript
复制
 public void Fill_Document_Fields(Dictionary<string, string> Fields, string FilePath)
    {
        try
        {
            using (WordprocessingDocument Doc = WordprocessingDocument.Open(FilePath, true))
            {
                foreach (FieldCode field in Doc.MainDocumentPart.RootElement.Descendants<FieldCode>())
                {
                    string FieldName =string.Empty;
                    try
                    {
                        FieldName = field.Text.Trim().Split(' ')[2];
                    }
                    catch
                    {
                        FieldName = field.Text.Trim();
                    }


                    foreach (Run run in Doc.MainDocumentPart.Document.Descendants<Run>())
                    {
                        foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + FieldName + "»"))
                        {
                            string itemValue;
                            if (Fields.TryGetValue(txtFromRun.Text, out itemValue))
                            {
                                txtFromRun.Text = itemValue;
                            }
                        }
                    }

                }
            }
        }
        catch 
        {
        }
    }
EN

回答 2

Stack Overflow用户

发布于 2017-05-29 04:30:10

您的代码只能与“SimpleField”一起使用,实际上您的代码根本不正确,因为用您的自定义值替换«FieldName»,您要替换的值也将是一个合并字段。

如果您查看文档背后的xml,您可以看到类似于以下内容:

代码语言:javascript
复制
<w:fldSimple w:instr=" MERGEFIELD  TestFoo  \* MERGEFORMAT ">
  <w:r w:rsidR="00C44AC1">
      <w:rPr>
           <w:noProof />
      </w:rPr>
      <w:t>«TestFoo»</w:t>
   </w:r>
</w:fldSimple>

此时,您将元素'w:t‘(«TestFoo»)替换为您的值(Foo),结果如下:

代码语言:javascript
复制
<w:fldSimple w:instr=" MERGEFIELD  TestFoo  \* MERGEFORMAT ">
  <w:r w:rsidR="00C44AC1">
      <w:rPr>
           <w:noProof />
      </w:rPr>
      <w:t>Foo</w:t>
   </w:r>
</w:fldSimple>

如您所见,您的值仍然在mergefield元素中。

在本例中(SimpleField),您需要找到'fldSimple‘元素并读取instr属性,可能使用正则表达式来提取合并字段的值。当你想用你的值替换mergefield时,你必须用run元素中的文本元素替换fldSimple元素。

mergefield的第二个实现是FieldChar。

代码语言:javascript
复制
<w:r>
  <w:fldChar w:fldCharType="begin" />
</w:r>
<w:r>
  <w:instrText xml:space="preserve"> MERGEFIELD  TestFoo  \* MERGEFORMAT </w:instrText>
</w:r>
<w:r>
  <w:fldChar w:fldCharType="separate" />
</w:r>
<w:r w:rsidR="00FA6E12">
  <w:rPr>
    <w:noProof />
  </w:rPr>
  <w:t>«TestFoo»</w:t>
</w:r>
<w:r>
  <w:rPr>
    <w:noProof />
  </w:rPr>
  <w:fldChar w:fldCharType="end" />
</w:r>

在这种情况下,您需要找到fldCharType attr等于begin的fldChar元素,您必须迭代所有节点,直到找到fldCharType attr等于end。

在'begin‘和'end’值之间,您需要在instrText元素中查找和读取值。

当你想要替换你的值时,你必须用run元素中的文本元素替换在'begin‘和'end’值之间找到的所有元素。

我认为使用docx合并字段被写成FieldChar,而使用dotx被写成SimpleField。

现在我不会写示例代码了,希望对大家有所帮助。

对不起,我的英语,再见

票数 4
EN

Stack Overflow用户

发布于 2020-04-07 04:34:00

您应该在编辑word文档后将其保存,因此在停止使用WordprocessingDocument.Open之前,只需关闭该文档(请参阅下面的示例)。

您可以在这里找到GetMergeFields()的一个很好的实现:https://github.com/frankfajardo/OpenXmlWordHelper

我是这样做的:

代码语言:javascript
复制
// get a memory stream for the bytes
using MemoryStream templateFileStream = this.GetMemoryStream(templateFileBytes);

// open template file from Memory Stream
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(templateFileStream, true))
{
    var mergeFields = wordDoc.GetMergeFields().ToList();

    foreach (var mergeField in mergeFields)
    {
        mergeField.ReplaceWithText(*replacementText*);
    }

    // This is required to save and flush the merged word document to the memory stream
    wordDoc.Close();

    // get the new merged document stream before it is closed and disposed
    mergedDocumentBytes = templateFileStream.ToArray();
}                
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37518114

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档