我实际上是使用库“ DocX ”从.Net生成Word文档(2007+)。好处是它可以使用“docx”模板来重新创建或更新文档。
问题:当我“ AddCustomProperty(...)”时,它不会更新word文档。我实际上需要打开它,然后选择所有并按F9。我想知道是否有办法使用DocX库自动更新“自定义属性”。
要重现我的问题,您可以执行以下步骤:
如果有人有解决方案,我很乐意听听。
(注意:我不希望MS Word互操作)
项目和样本位于:http://docx.codeplex.com/
答案 0 :(得分:3)
问题是当我们使用MS Word(我使用2010版本)然后我们修改模板并保存它。它会更改文档包含的内容。
以下是我们首次使用DocX生成模板时所拥有的内容:
<w:fldSimple w:instr="DOCPROPERTY company_name \* MERGEFORMAT" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:r>
<w:t>
<w:rPr>
<w:b />
<w:sz w:val="24" />
<w:szCs w:val="24" />
<w:color w:val="1F497D" />
</w:rPr>Company Name</w:t>
</w:r>
</w:fldSimple>
当我们用Word编辑(添加一个断行或一些文本)并保存它时,它会将fldSimple重写为:
<w:p w:rsidR="006D64DE" w:rsidRDefault="006B25B1">
<w:r>
<w:fldChar w:fldCharType="begin" />
</w:r>
<w:r>
<w:instrText>DOCPROPERTY company_name \* MERGEFORMAT</w:instrText>
</w:r>
<w:r>
<w:fldChar w:fldCharType="separate" />
</w:r>
<w:r>
<w:rPr>
<w:b />
<w:color w:val="1F497D" />
<w:sz w:val="24" />
<w:szCs w:val="24" />
</w:rPr>
<w:t>Company Name</w:t>
</w:r>
...
<w:r>
<w:rPr>
<w:b />
<w:color w:val="1F497D" />
<w:sz w:val="24" />
<w:szCs w:val="24" />
</w:rPr>
<w:fldChar w:fldCharType="end" />
</w:r>
</w:p>
我没有等待某人解决问题,而是试图做一个初步的实施草案。我实际上修改了方法UpdateCustomPropertyValue(...)。我实际上添加了第一个 foreach 的代码。第二个 foreach 已经存在,它适用于从 DocX 创建的文档。
internal static void UpdateCustomPropertyValue(DocX document, string customPropertyName, string customPropertyValue)
{
foreach (XElement e in document.mainDoc.Descendants(XName.Get("instrText", w.NamespaceName)))
{
string attr_value = e.Value.Replace(" ", string.Empty).Trim();
string match_value = string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", customPropertyName).Replace(" ", string.Empty);
if (attr_value.Equals(match_value, StringComparison.CurrentCultureIgnoreCase))
{
XNode node = e.Parent.NextNode;
bool found = false;
while (true)
{
if (node.NodeType == XmlNodeType.Element)
{
var ele = node as XElement;
var match = ele.Descendants(XName.Get("t", w.NamespaceName));
if (match.Count() > 0)
{
if (!found)
{
match.First().Value = customPropertyValue;
found = true;
}
else
{
ele.RemoveNodes();
}
}
else
{
match = ele.Descendants(XName.Get("fldChar", w.NamespaceName));
if (match.Count() > 0)
{
var endMatch = match.First().Attribute(XName.Get("fldCharType", w.NamespaceName));
if (endMatch != null && endMatch.Value == "end")
{
break;
}
}
}
}
node = node.NextNode;
}
}
}
foreach (XElement e in document.mainDoc.Descendants(XName.Get("fldSimple", w.NamespaceName)))
{
string attr_value = e.Attribute(XName.Get("instr", w.NamespaceName)).Value.Replace(" ", string.Empty).Trim();
string match_value = string.Format(@"DOCPROPERTY {0} \* MERGEFORMAT", customPropertyName).Replace(" ", string.Empty);
if (attr_value.Equals(match_value, StringComparison.CurrentCultureIgnoreCase))
{
XElement firstRun = e.Element(w + "r");
XElement firstText = firstRun.Element(w + "t");
XElement rPr = firstText.Element(w + "rPr");
// Delete everything and insert updated text value
e.RemoveNodes();
XElement t = new XElement(w + "t", rPr, customPropertyValue);
Novacode.Text.PreserveSpace(t);
e.Add(new XElement(firstRun.Name, firstRun.Attributes(), firstRun.Element(XName.Get("rPr", w.NamespaceName)), t));
}
}
}