OpenXml 域变量更新

用过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的域更新问题,也希望有这方面经验的大侠指点!

posted @ 2013-02-04 15:57  真有意思  阅读(1652)  评论(2编辑  收藏  举报