word的类库使用的是word2007版本的类库,类库信息见下面图片,折腾了半天,终于找到入口,网上 很多说的添加或者修改word的高级属性中的自定义属性都是错误的,感觉都是在copy网上的代码,自己终于摸索成功了,Mark下。

直接上代码,代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using Microsoft.Office.Interop.Word;
using Microsoft.Office.Core;
using System.Reflection; namespace TestWord
{
/// <summary>
/// 从传入的word文档中替换掉指定书签的内容,主要是为了解决封面中的内容
/// 抽取命令:
/// xx.exe -p D:/temp/test.doc D:/result/mappting.txt
///
/// mappting.txt 文件是替换test.doc文档中标签的匹配文件,比如哪个标签的内容需要替换为其他的值
/// </summary>
class PageExtractor : IExtractor
{ private object oMissing = System.Reflection.Missing.Value; //标准页眉要替换的值在mapping.txt文件中存储的key
private String TB_YEMEI_GJB = "TB_YEMEI_GJB"; //写入word的高级属性中的内容,需要设置为整形的高级属性名
private String[] m_oIntegerAdvPropertyNames = new String[]{ "密级","稿件"}; //写入word的高级属性中的内容,需要设置为boolean
private String[] m_oBoolAdvPropertyNames = new String[] { "TRS" }; /// <summary>
/// 从指定word中抽取出word正文
/// </summary>
/// <param name="_sSourceWordPath"></param>
/// <returns></returns>
public bool execute(string[] args)
{
_Application oWord = WordProcessHelper.getInstance().getApplication();
_Document oDoc = null;
String _sWordPath = "";
LogServer currLogServer = LogServer.getInstance(); try
{
//1.参数需要长度为3,第一个是“-p”,第二个是“要抽取的word路径”,第三个是“匹配的书签替换文件”
if (args.Length < 3)
{
throw new Exception("替换封面时传入的参数个数至少为3个,第一个是‘-p’,第二个是‘要抽取的word路径’,第三个是标签‘匹配的UTF-8编码的txt文件内容’,第四个是文档的高级属性内容");
} _sWordPath = args[1];//获取要抽取的原word路径
if (!File.Exists(_sWordPath))
{
throw new Exception("Word文件[" + _sWordPath + "]不存在!");
} String sMappingFilePath = args[2];
if (CMyString.isEmpty(sMappingFilePath))
{
throw new Exception("没有传入替换doc文件内容的匹配文件路径!");
} //1.读取需要替换的文件内容
Properties mappingProperties = new Properties(sMappingFilePath);
if (mappingProperties.size() <= 0)
{
currLogServer.writeLogLine("文件[" + sMappingFilePath + "]中要替换的内容为空!");
return true;
} //2.读取word中标签
DateTime beginDateTime = new DateTime();
object oDocFilePath = _sWordPath;
object oReadOnly = false;
object oAddToRecentFiles = false;
oDoc = oWord.Documents.Open(ref oDocFilePath, ref oMissing, ref oReadOnly, ref oAddToRecentFiles, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing); //3.获取标签名与对应的Range对象的对应关系
Hashtable oBookIdToRangeMap = getBookIdToRange(oDoc, mappingProperties);
if (oBookIdToRangeMap == null || (oBookIdToRangeMap.Count == 0))
{
return true;
} //4.替换Range对象的内容为mapping文件中的属性值
replaceMappingContent(oDoc, oBookIdToRangeMap, mappingProperties); //5.替换页眉
Range allRange = oDoc.Range(ref oMissing, ref oMissing);
Sections allSections = allRange.Sections;
currLogServer.writeLogLine("开始替换[" + _sWordPath + "]页眉."); if (allSections != null && (allSections.Count > 0))
{
String sTBYeMeiGJB = mappingProperties.getPropertyAsString(TB_YEMEI_GJB, false);
currLogServer.writeLogLine("[" + _sWordPath + "]页眉要替换的值为:" + sTBYeMeiGJB);
sTBYeMeiGJB = CMyString.showEmpty(sTBYeMeiGJB);
for (int i = 1; i <= allSections.Count; i++)
{
Section aSection = allSections[i];
if (aSection == null)
{
continue;
} //设置奇数页和偶数页的页眉
aSection.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].Range.Text = sTBYeMeiGJB;
aSection.Headers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].Range.Text = sTBYeMeiGJB;
}
} DateTime endDateTime = new DateTime();
String sTimeDuration = DateTimeHelper.dateDiff(beginDateTime, endDateTime);
currLogServer.writeLogLine("[" + _sWordPath + "]页眉替换完成,用时:" + sTimeDuration); //TDO:写入国军标的一些标准属性
//读取需要写入到文档高级属性的
if (args.Length < 4) {
return true;
} String sAdvancePropertyFilePath=args[3];
if (CMyString.isEmpty(sAdvancePropertyFilePath)) {
return true;
}
Properties advanceProperties = new Properties(sAdvancePropertyFilePath);
if (advanceProperties.size() <= 0)
{
currLogServer.writeLogLine("文件[" + sAdvancePropertyFilePath + "]中要写入的高级属性内容为空!");
return true;
} //写入属性
currLogServer.writeLogLine("[" + _sWordPath + "]开始写入高级属性.");
writeDocAdvanceProperty(oDoc, advanceProperties);
currLogServer.writeLogLine("[" + _sWordPath + "]高级属性写入完成."); //TODO:返回成功标记
return true; }
catch (Exception ex)
{
currLogServer.writeLogLine("页眉替换从文件[" + _sWordPath + "]时发生错误:"+ex.Message);
throw new Exception("页眉替换从文件[" + _sWordPath + "]时发生错误", ex);
}
finally
{
//关闭当前文档
object saveOption = WdSaveOptions.wdSaveChanges;
if (oDoc != null)
{
oDoc.Close(ref saveOption, ref oMissing, ref oMissing);
//System.Runtime.InteropServices.Marshal.ReleaseComObject(oDoc);
} }
} /// <summary>
/// 把指定的高级属性的Properties中的内容写入到文档的高级属性中
/// </summary>
/// <param name="oDoc"></param>
/// <param name="advanceProperties"></param>
private void writeDocAdvanceProperty(_Document oDoc, Properties advanceProperties) {
if (oDoc == null || (advanceProperties == null) || (advanceProperties.size()<=0))
{
return;
} //遍历Properties属性
Hashtable allAdvanceProperties=advanceProperties.getProperties();
if (allAdvanceProperties == null || (allAdvanceProperties.Count <= 0)) {
return;
} //获取高级属性对象
object oDocCustomProps = oDoc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType(); //遍历集合
foreach (String sPropName in allAdvanceProperties.Keys)
{
String sValue = (String)allAdvanceProperties[sPropName];
sValue = CMyString.showEmpty(sValue); //获取属性名的类型
Object oPropItemObj = getPropertyObjByName(oDocCustomProps, typeDocCustomProps, sPropName);
if (oPropItemObj == null)
{
//不存在,则添加
MsoDocProperties oPropertType = getPropertyTypeByName(sPropName);
object[] oArgs = {sPropName,false,
oPropertType,
sValue};
typeDocCustomProps.InvokeMember("Add", BindingFlags.Default |
BindingFlags.InvokeMethod, null,
oDocCustomProps, oArgs);
}
else {
//已经存在,则覆盖属性
Type typeItemProp = oPropItemObj.GetType();
typeItemProp.InvokeMember("Value",
BindingFlags.Default | BindingFlags.SetProperty,
null, oPropItemObj,
new object[] { sValue });
}
} } /// <summary>
/// 从指定的自定义高级属性中查找指定名称的Item对象,如果没有找到,则返回null
/// </summary>
/// <param name="oDocCustomProps"></param>
/// <param name="typeDocCustomProps"></param>
/// <param name="_sPropertyName"></param>
/// <returns></returns>
private object getPropertyObjByName(object oDocCustomProps,Type typeDocCustomProps, String _sPropertyName)
{
if (CMyString.isEmpty(_sPropertyName)) {
return null;
}
if (oDocCustomProps == null || typeDocCustomProps == null) {
return null;
} //通过反射去查找对象
//获取值
object oPropItem = null;
try
{
oPropItem = typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null, oDocCustomProps,
new object[] { _sPropertyName });
}
catch (Exception ex) {
//TODO:由于没有找到判断是否存在属性的接口,所以这里通过Item来判断,如果属性不存在,则会报错,这里粗鲁的忽略掉异常
oPropItem = null;
} //返回结果
return oPropItem;
} /// <summary>
/// 根据属性名获取该属性对应的类型
/// </summary>
/// <param name="sPropName"></param>
/// <returns></returns>
private MsoDocProperties getPropertyTypeByName(String sPropName)
{
if (CMyString.isEmpty(sPropName)) {
return MsoDocProperties.msoPropertyTypeString;
}
//判断是否是整形
bool bInStrArray = CMyList.isInStrArray(sPropName, m_oIntegerAdvPropertyNames, true);
if (bInStrArray) {
return MsoDocProperties.msoPropertyTypeNumber;
}
//判断是否是bool型
bInStrArray = CMyList.isInStrArray(sPropName, m_oBoolAdvPropertyNames, true);
if (bInStrArray) {
return MsoDocProperties.msoPropertyTypeBoolean;
} //默认返回字符串
return MsoDocProperties.msoPropertyTypeString;
} /// <summary>
/// 返回指定文档中需要替换属性的书签名称与Range对象HashTable对象
/// </summary>
/// <param name="oDoc"></param>
/// <param name="mappingProperties"></param>
/// <returns></returns>
private Hashtable getBookIdToRange(_Document oDoc, Properties mappingProperties) {
//1.参数校验
Hashtable oBookIdToRangeMap = new Hashtable();
if (oDoc == null || (mappingProperties == null)) {
return oBookIdToRangeMap;
} //获取标签内容
Bookmarks allBookMars = oDoc.Bookmarks;
for (int i = 1; i <= allBookMars.Count; i++)
{
object oIndex = i;
Bookmark aBookMark = allBookMars.get_Item(ref oIndex);
if (aBookMark == null)
{
continue;
}
String sBookName = aBookMark.Name;
if (CMyString.isEmpty(sBookName)) {
continue;
} //是否包含在要替换的属性集合中
if (!mappingProperties.contains(sBookName,true)) {
continue;
} //压入书签名称与Range对象集合中
oBookIdToRangeMap.Add(sBookName.Trim().ToUpper(), aBookMark.Range);
} //返回集合中
return oBookIdToRangeMap;
} /// <summary>
/// 根据 mappingProperties中的属性值替换 oBookIdToRangeMap 指定Range对象的内容,并设置Range对象的书签名称
/// </summary>
/// <param name="oDoc"></param>
/// <param name="oBookIdToRangeMap"></param>
/// <param name="mappingProperties"></param>
private void replaceMappingContent(_Document oDoc,Hashtable oBookIdToRangeMap, Properties mappingProperties)
{
//1.参数校验
if (oDoc == null || (oBookIdToRangeMap == null) || (mappingProperties == null)) {
return;
} //2.遍历Map对象
foreach (String sBookIdKey in oBookIdToRangeMap.Keys)
{
Range currBookRange = (Range)oBookIdToRangeMap[sBookIdKey];
if (currBookRange == null) {
continue;
} //获取替换的值
String sReplaceValue = mappingProperties.getPropertyAsString(sBookIdKey,true);
sReplaceValue = CMyString.showEmpty(sReplaceValue);
currBookRange.Text = sReplaceValue; //重新设置书签
if (!oDoc.Bookmarks.Exists(sBookIdKey))
{
object oTempBookRange = currBookRange;
oDoc.Bookmarks.Add(sBookIdKey, ref oTempBookRange);
}
}
} }
}

C# 操作 Word 修改word的高级属性中的自定义属性2的更多相关文章

  1. C# 操作 Word 修改word的高级属性中的自定义属性

    为 Microsoft Word 创建自动化客户端 启动 Visual Studio .NET. 在文件菜单上,单击新建,然后单击项目.从 Visual C# 项目类型中选择 Windows 应用程序 ...

  2. jQuery操作标签--样式、文本、属性操作, 文档处理

    1.样式 2.文本 3.属性操作 全选,反选效果 4.文档处理 操作标签 一.样式操作 样式类: addClass(); // 添加指定的css类名 removeClass(); //移除指定的css ...

  3. 全面了解POI操作Microsoft Office(Word、Excel、PowerPoint)

    POI 与 Microsoft Office 1. POI 简介 POI 是 Apache 下的 Jakata 项目的一个子项目,主要用于提供 java 操作 Microsoft Office 办公套 ...

  4. 如何修改word的项目编号

    在操作word文档时,有时会遇到word文档中的项目编号不是自己需要的,并造成word项目编号的混乱,如何word中的两级项目编号不统一,为解决会word的项目编号混乱问题,小编将教大家如何修改wor ...

  5. C#学习笔记(33)——批量修改word标题

    说明(2017-12-22 11:20:44): 1. 因为数学脚本的主标题和副标题没有格式,目录导航里不显示,修改的时候不好定位,所以需要改成下图格式: 2. 问题的难点有两个,一个是word的操作 ...

  6. 教您如何在Word的mathtype加载项中修改章节号

    在MathType数学公式编辑器中,公式编号共有五部分内容:分别是章编号(Chapter Number).节编号(Section Number).公式编号(Equation Number).括号(En ...

  7. ASP.NET MVC深入浅出(被替换) 第一节: 结合EF的本地缓存属性来介绍【EF增删改操作】的几种形式 第三节: EF调用普通SQL语句的两类封装(ExecuteSqlCommand和SqlQuery ) 第四节: EF调用存储过程的通用写法和DBFirst模式子类调用的特有写法 第六节: EF高级属性(二) 之延迟加载、立即加载、显示加载(含导航属性) 第十节: EF的三种追踪

    ASP.NET MVC深入浅出(被替换)   一. 谈情怀-ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态 ...

  8. 利用python批量修改word文件名的方法示例

    利用python批量修改word文件名的方法示例 最近不小心把硬盘给格式化了,由于当时的文件没有备份,所以一下所有的文件都没有了,于是只能采取补救措施,用文件恢复软件恢复了一部分的数据出来,但是恢复完 ...

  9. 怎么批量修改Word表格的宽度

    怎么批量修改Word表格的宽度 怎么批量修改Word表格的宽度呢.Word表格可根据窗口自动调整表格宽度,使得所有的表格宽度和页面宽度一样.当页面设置了新的页边距后,所有的表格都需要调整新的宽度.或者 ...

随机推荐

  1. Poj 1006 / OpenJudge 2977 1006 Biorhythms/生理周期

    1.链接地址: http://poj.org/problem?id=1006 http://bailian.openjudge.cn/practice/2977 2.题目: Biorhythms Ti ...

  2. 正确理解javascript的this关键字

    javascript有this关键字,它和javascript的执行上下文有着密切的关系,就是说this具体指代什么要根据它的上下文来判断. 一.this和对象的关系    var Person={ ...

  3. React Native在虚拟运行app时,报错RCTRootView not found,怎么解决?

    报错: 解决方案:

  4. Python入门一:基本数据类型

    作为一个刚入门编程的大一狗,第一次写博客,希望能对自己学的知识进行巩固和提升,也希望记录自己成长的过程. 学习Python,一是因为暑假学的c++头疼,听说Python简单,那我就试试吧,二是因为Py ...

  5. Oracle表空间传输测试

    源数据库平台:window 7 64bit Oracle 11g 64bit目标数据库平台:RHEL6 64bit Oracle 11g 64bit 1.查看数据集 select * from nls ...

  6. 让WPF的Popup不总置顶的解决方案

    使用WPF的Popup的时候会发现有一个问题,它总是会置顶,只要Popup的StayOpen不设置为False,它就一直呆在最顶端,挡住其他的窗口. 解决方案是继承Popup重新定义控件PopupEx ...

  7. Cent OS 常用 命令

    1.开机自动联网操作 需要root权限 vim /etc/sysconfig/network-scripts/ifcfg-p4p1(p4p1 为网络链接名称)这个文件, 把ONBOOT="n ...

  8. HBase性能优化方法总结(转)

    本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法.有关HBase系统配置级别的优化,这里涉及的不多,这部分可以参考:淘宝Ken Wu同学的博客. 1. 表的设计 1.1 Pr ...

  9. 一步步学习NHibernate(6)——ISession的管理

    请注明转载地址:http://www.cnblogs.com/arhat 今天老魏那个汗啊,我的ThinkPad的电源线不通电了,擦啊.明天还得掏银子买一个!心疼啊,原装的啊.不过话说回来,已经用了将 ...

  10. CoreBluetooth - 中心模式

    BLE中心模式流程-coding BLE中心模式流程 - 1.建立中心角色 - 2.扫描外设(Discover Peripheral) - 3.连接外设(Connect Peripheral) - 4 ...