Open-XML-SDK 如何实现更新Word中域的值

  • 创建一个Word模板,插入域
  • 新建VS项目,添加Open-XML-SDK包
  • 功能代码

创建一个Word模板,插入域

插入>文档部件->域->DocVariable->输入名称

Alt + F9 切换域显示

新建VS项目,添加Open-XML-SDK包

Nuget搜索Open-XML-SDK并添加到你的项目当中去

Open-XML-SDK文档

查看文档我们可以看到,Field域由以下几部分组成:

他以<w:fldChar w:fldCharType=“begin” /> 开始,

以<w:fldChar w:fldCharType=“end” /> 结束

<w:fldChar w:fldCharType=“separate” /> 是分隔符

分隔符之前的 <w:instrText>AUTHOR</w:instrText> 是域的描述信息

<w:t>Rex Jaeschke</w:t> 就是域的值

了解了他的结构我们就可以动手实现更新域值了

功能代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;namespace ST.tools.OpenXML
{public class WorldProcess{/// <summary>/// 显示Word文档XML内容/// </summary>public static void Test_FieldOption_Show(string fname){// string fname = Path.Combine(AppDomain .CurrentDomain.BaseDirectory, "Test.docx");using (WordprocessingDocument wordprocessing = WordprocessingDocument.Open(fname, true)){MainDocumentPart documentPart = wordprocessing.MainDocumentPart;var document = documentPart.Document;Console.WriteLine(document.InnerXml);}}public static void Test_FieldOption_Set(string fname){// string fname = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test.docx");byte[] buffer = File.ReadAllBytes(fname);using (MemoryStream ms = new MemoryStream()){ms.Write(buffer, 0, buffer.Length);using (WordprocessingDocument wordprocessing = WordprocessingDocument.Open(ms, true)){MainDocumentPart documentPart = wordprocessing.MainDocumentPart;var document = documentPart.Document;//File.WriteAllText(@"C:\Users\XiQin\Desktop\origin.xml", document.OuterXml);IDictionary<string, string> dic = new Dictionary<string, string>{{"projectName","珠穆朗玛峰-安装电梯" },{"projectType","旅游建设" },{"projectDate", DateTime.Now.ToString("MM-dd HH:mm") },{"projectLevel","甲级" },{"sign","耗子" }};IDictionary<string, string> dic2 = new Dictionary<string, string>{{"projectName","大连-烟台跨海大桥" },{"projectType","工程建设" },{"projectDate", DateTime.Now.ToString("MM-dd HH:mm") },{"projectLevel","甲+级" },{"sign","贱贱" }};//foreach (var item in dic)//{//    SetField(document, item.Key, item.Value);//}//File.WriteAllText(@"C:\Users\XiQin\Desktop\result.xml", document.OuterXml);//wordprocessing.Save();SetField(document, dic);//wordprocessing.SaveAs($@"C:\Users\XiQin\Desktop\{DateTime.Now.ToFileTime()}.docx");//wordprocessing.Close();}ms.Seek(0, SeekOrigin.Begin);File.WriteAllBytes($@"C:\Users\XiQin\Desktop\{DateTime.Now.ToFileTime()}.docx", ms.ToArray());}}/// <summary>/// 设置文档域 字段的值/// </summary>/// <param name="document"></param>/// <param name="key"></param>/// <param name="value"></param>/// <param name="prefix">前缀</param>/// <returns></returns>public static bool SetField(Document document, string key, string value, string prefix = "DOCVARIABLE"){bool isOk = false;try{// 查找所有域字段var fieldChars = document.Descendants<FieldChar>().Where(f => f.FieldCharType == FieldCharValues.Begin);if (fieldChars.Count() <= 0)return isOk;foreach (var field in fieldChars){FieldCode instrText = GetTheFieldName(field);FieldChar end = FindTheEndFeildElement(field);if (end == null)throw new Exception("Cannt find the end field!!");if (instrText == null)continue;string instrText_text = instrText.Text.Trim();string[] arr = instrText_text.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries);if (!string.IsNullOrEmpty(prefix)){if (arr[0] != prefix.Trim())continue;if (arr[1] != key.Trim())continue;}else{if (arr[0] != key.Trim())continue;}// 是否合并样式bool IS_MERGEFORMAT = false;if (arr.Contains("\\* MERGEFORMAT"))IS_MERGEFORMAT = true;var separate = FindFieldSeparate(field);var text = GetTheFieldValue(field);if (text != null){text.Text = value;}else{if (separate == null){separate = InserFieldSeparate(end, IS_MERGEFORMAT);}InserFieldValue(separate, value, IS_MERGEFORMAT);isOk = true;}}}catch (Exception ex){Console.WriteLine(ex.Message);}return isOk;}/// <summary>/// 设置文档域 字段的值/// </summary>/// <param name="document"></param>/// <param name="dic"></param>/// <param name="prefix">前缀</param>/// <returns></returns>public static bool SetField(Document document, IDictionary<string, string> dic, string prefix = "DOCVARIABLE"){bool isOk = false;try{// 查找所有域字段var fieldChars = document.Descendants<FieldChar>().Where(f => f.FieldCharType == FieldCharValues.Begin);if (fieldChars.Count() <= 0)return isOk;foreach (var field in fieldChars){FieldCode instrText = GetTheFieldName(field);FieldChar end = FindTheEndFeildElement(field);if (end == null)throw new Exception("Cannt find the end field!!");if (instrText == null)continue;string instrText_text = instrText.Text.Trim();string[] arr = instrText_text.Split(new string[] { "  " }, StringSplitOptions.RemoveEmptyEntries);string key = String.Empty;if (!string.IsNullOrEmpty(prefix)){if (arr[0] != prefix.Trim())continue;key = arr[1];}else{if (arr[0] != key.Trim())continue;key = arr[0];}var items = dic.Where(x => x.Key.Trim() == key.Trim());if (items.Count() <= 0)continue;var item = items.First();// 是否合并样式bool IS_MERGEFORMAT = false;if (arr.Contains("\\* MERGEFORMAT"))IS_MERGEFORMAT = true;var separate = FindFieldSeparate(field);var text = GetTheFieldValue(field);if (text != null){text.Text = item.Value;}else{if (separate == null){separate = InserFieldSeparate(end, IS_MERGEFORMAT);}InserFieldValue(separate, item.Value, IS_MERGEFORMAT);isOk = true;}}}catch (Exception ex){Console.WriteLine(ex.Message);}return isOk;}/// <summary>/// 查找域的结束标签元素/// </summary>/// <param name="start"></param>/// <returns></returns>private static FieldChar FindTheEndFeildElement(FieldChar start){FieldChar end = null;Run run = start.Parent.NextSibling<Run>();while (run != null){FieldChar field = run.ChildElements.First<FieldChar>();if (field != null && field.FieldCharType == FieldCharValues.End){end = field;break;}run = run.NextSibling<Run>();}return end;}/// <summary>/// 获取域的变量名/// </summary>/// <param name="start"></param>/// <returns></returns>private static FieldCode GetTheFieldName(FieldChar start){FieldCode name = null;Run run = start.Parent.NextSibling<Run>();while (run != null){FieldCode fieldcode = run.ChildElements.First<FieldCode>();if (fieldcode != null && !string.IsNullOrWhiteSpace(fieldcode.Text)){name = fieldcode;break;}// 查找到结束节点直接返回FieldChar fieldend = run.ChildElements.First<FieldChar>();if (fieldend != null && fieldend.FieldCharType == FieldCharValues.End)break;run = run.NextSibling<Run>();}return name;}/// <summary>/// 获取域的变量值/// </summary>/// <param name="start"></param>/// <returns></returns>private static Text GetTheFieldValue(FieldChar start){Text value = null;Run run = start.Parent.NextSibling<Run>();while (run != null){Text text = run.ChildElements.First<Text>();if (text != null){value = text;break;}// 查找到结束节点直接返回FieldChar fieldend = run.ChildElements.First<FieldChar>();if (fieldend != null && fieldend.FieldCharType == FieldCharValues.End)break;run = run.NextSibling<Run>();}return value;}/// <summary>/// 查找域的分隔符/// </summary>/// <param name="start"></param>/// <returns></returns>private static FieldChar FindFieldSeparate(FieldChar start){FieldChar separate = null;Run run = start.Parent.NextSibling<Run>();while (run != null){FieldChar field = run.ChildElements.First<FieldChar>();if (field != null && field.FieldCharType == FieldCharValues.Separate){separate = field;break;}// 查找到结束节点直接返回FieldChar fieldend = run.ChildElements.First<FieldChar>();if (fieldend != null && fieldend.FieldCharType == FieldCharValues.End)break;run = run.NextSibling<Run>();}return separate;}/// <summary>/// 在end之前插入separate/// </summary>/// <param name="end"></param>/// <param name="IS_MERGEFORMAT">是否合并样式</param>private static FieldChar InserFieldSeparate(FieldChar end, bool IS_MERGEFORMAT){Run run = end.Parent as Run;Run run_before = new Run();if (IS_MERGEFORMAT){var rPr = run.ChildElements.First<RunProperties>();if (rPr != null){RunProperties rPr_copy = rPr.CloneNode(true) as RunProperties;run_before.AppendChild(rPr_copy);}}FieldChar fieldChar = new FieldChar(){FieldCharType = FieldCharValues.Separate};run_before.AppendChild(fieldChar);run.InsertBeforeSelf(run_before);return fieldChar;}/// <summary>/// 插入Field 值/// </summary>/// <param name="separate"></param>/// <param name="value"></param>private static Text InserFieldValue(FieldChar separate, string value, bool IS_MERGEFORMAT){Run run = separate.Parent as Run;Run run_next = new Run();if (IS_MERGEFORMAT){var rPr = run.ChildElements.First<RunProperties>();if (rPr != null){RunProperties rPr_copy = rPr.CloneNode(true) as RunProperties;run_next.AppendChild(rPr_copy);}}Text text = new Text(value);run_next.AppendChild(text);run.InsertAfterSelf(run_next);return text;}}
}

Open-XML-SDK 如何实现更新Word中域的值相关推荐

  1. 操作系统 | Mac如何更新word中的域

    Windows系统更新域 按F9自动更新域 右键选择:更新域 Mac系统更新域 选中要更新的文本,右键,点击,更新域 直接Command + A,右键,更新全部内容就好 PS: 如果有其他容易的方法, ...

  2. oracle一个表更新另一个表多列,oracle sql更新表中多列值,值是从其它表中查询(select)得出...

    案例描述:sql 将表vehicle中列pay_money_remain的值分为2/3,1/3再更新到表vehicle的pay_money_remain,disinfectionbal_remains ...

  3. python中update什么意思_如何在Python中更新字典中键的值?

    我有一本代表书店的字典.键表示书名,值表示当前书籍的份数.从商店出售书时,书的份数必须减少. 我已经写了一个代码来减少已售出图书的拷贝数,但在更新后打印词典时,我得到的是初始词典,而不是更新后的词典. ...

  4. word中endnotes更新文献,word崩溃闪退解决方案

    word中endnotes更新文献,word崩溃闪退解决方案 word中endnotes更新文献,word崩溃闪退解决方案 1. 取消word中自动校对 2. 取消自动formating 3. 删除w ...

  5. Word中题注按章节不同编号

    关注公众号及时获取文章更新 Word中分章节题注 在写报告时,通常章节较多,所以在对图片和表格进行编号时,需要按章节进行编号,例如图1-1.图1-2.图2-1等,为了快捷生成这些题注,提供方法如下:

  6. 利用word中的域进行多位数字自动编号

    一. 应用场景: 在撰写专利说明书或其它应用场景下,需要用到大量如下图所示的多位数字编号,word2019工具栏中的定义新编号不能进行四位或更高位数字的自动编号,而域功能可以解决这个问题. 二.域代码 ...

  7. 从Word中批量提取数据到Excel中,Word导出到Excel的利器

    从Word文件中取值并导出到Excel中,有现成的工具可实现. 不过要通过工具来批量取值,Word文件中的目标字符必须有规律才行,例如都处于表格中,或者都有下划线,只要目标符合指定的规则就可以批量提取 ...

  8. c++中判断某个值在字典的value中_Python核心知识系列:字典

    1 定义 字典是一种映射对象类型,由键值对构成的一个可变容器.字典中的每个键值对内用冒号 ( : ) 分隔,键值对间用逗号 ( , ) 分隔,所有键值对包括在{}中.字典的键必须是唯一的,只有可散列的 ...

  9. TensorFlow中的Nan值的陷阱

    北京站 | NVIDIA DLI深度学习培训 2018年1月26日 NVIDIA 深度学习学院 带你快速进入火热的DL领域 阅读全文                           正文共1583 ...

最新文章

  1. Java改知能机_Java 面试突击之 Java 并发知识基础 进阶考点全解析
  2. 单细胞RNA降维之UMAP
  3. 学习笔记Hive(八)—— 查询优化
  4. Angular应用的依赖注入调试
  5. 博客园开始对X++语言语法高亮的支持
  6. byte[]、sbyte[]、int[]以及Array的故事
  7. apache 配置虚拟目录
  8. ANDROID开发java.lang.NoClassDefFoundError: com.baidu.location.LocationClient的解决办法
  9. python条件语句练习题_[python](1)---条件语句练习题
  10. 长安链技术架构与共识模块介绍
  11. 1970年代宇航员在月球上生活,如何实现电力供应
  12. 关于sizeof(struct student)的问题
  13. Phoenix Tips (8) 多租户
  14. 为什么重复率高的字段不适合作为索引
  15. C语言中各种格式字符说明
  16. ELK日志平台---老男孩教育笔记
  17. 千万并发,阿里淘宝的 14 次架构演进之路!
  18. 重磅!腾讯优图29篇论文入选顶会ECCV 2022
  19. 小熊派gd32f303学习之旅(4)—使用DMA实现串口打印
  20. 腾讯-腾讯云citybase产品白皮书

热门文章

  1. Adobe Acrobat Reader DC
  2. 怎样轻松将SD卡照片数据恢复
  3. win7开机进系统黑屏,只有鼠标解决方法
  4. 年终总结:2009年管理软件市场盘点(上)
  5. 如何使用GHO镜像安装器安装系统
  6. win32Dasm使用方法
  7. Foxmail宏设置
  8. EVE-NG 添加win7 镜像
  9. 电路方案分析(十六)带有C2000微控制器且精度为 ±0.1° 的分立式旋转变压器前端参考设计
  10. MSF模拟渗透测试之一句话木马拿shell