用过Office Com组建,Aspose.Word操作word,最近项目中也开始用,又原来的com转到aspose,在从aspose转到OpenXml。
大体上处理的方式都是一样的 。
下面介绍一下在OpenXml中更新域变量的内容,因为至今为发现有什么好的方法可以直接更新域。在其他的方式中更新域相对简单一些,可以直接通过Document.Range.UpdateFields();更新域信息。而在Openxml中我们发现无法找到直接更新域信息的内容。只有用最笨的方式操作了。
首先我们知道Word中的变量存储位置在Setting中。 我们首先获取变量信息。通过如下方法:
View Code
1 /// <summary> 2 /// 获取文档所有变量 3 /// </summary> 4 /// <param name="setting">设置变量内容Document</param> 5 /// <returns></returns> 6 private static Dictionary<string, string> GetAllVariables(OpenXmlElement setting) 7 { 8 var dic = new Dictionary<string, string>(); 9 var vard = setting.ChildElements.SingleOrDefault(p => p.LocalName.ToLower().Equals(ConstDocVars)); 10 if (vard == null || vard.ChildElements == null) return dic; 11 foreach (var docvar in vard.ChildElements) 12 { 13 var key = docvar.GetAttribute(ConstName, ConstNamespaceW); 14 var value = docvar.GetAttribute(ConstVal, ConstNamespaceW); 15 dic.Add(key.Value, value.Value); 16 } 17 return dic; 18 }
我们要更新域变量,所以我们要更新的是变量的内容。 这里我们通过xml分析得出,域信息格式为:如下图:
这样我们不难发现我们所要更新的域信息为W:t 通过如下代码即可完成更新域的操纵。
/// <summary> /// 更改域信息 /// </summary> /// <param name="body">文档内容</param> public static void UpdateField(Body body) { foreach (var par in body.ChildElements) //所有段落 { var runs = par.Descendants<Run>().ToList<Run>(); var flag = false; //一组域的标志 var count = 0; //域信息计数器 var value = string.Empty; //数据值 var dataType = string.Empty; //数据类型 var nowDataValueFlag = false; //获取当前数据值标志 foreach (var run in runs) { var fieldChar = run.OfType<FieldChar>().FirstOrDefault(p => p.FieldCharType == FieldCharValues.Begin); if (fieldChar != null) flag = true; //找到域头 if (flag) { count++; switch (count) { case 3: //找到域变量 var fieldValue = run.OfType<FieldCode>().FirstOrDefault(); if (fieldValue != null) { var dataInfo = fieldValue.InnerText.Trim().Replace("DOCVARIABLE ", "").Split(':'); dataType = dataInfo[0]; var info = dataInfo[1]; } break; case 6: //重新设置域 var updateFieldValue = run.OfType<Text>().FirstOrDefault(); if (updateFieldValue != null) { updateFieldValue.Text = value; } break; } } fieldChar = run.OfType<FieldChar>().FirstOrDefault(p => p.FieldCharType == FieldCharValues.End); if (fieldChar == null) continue; flag = false; //找到域尾 count = 0; value = string.Empty; dataType = string.Empty; } } }
通过上述操作即可完成OpenXML的域变量更新问题。
不才不清楚是否还有更好的方式处理OpenXml的域更新问题,也希望有这方面经验的大侠指点!