C#操作Word修改word的高级属性中的自定义属性
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
C#操作Word修改word的高级属性中的自定义属性
word的类库使用的是word2007版本的类库,类库信息见下面图片,折腾了半天,终于找到入口,网上很多说的添加或者修改word 的高级属性中的自定义属性都是错误的,感觉都是在copy网上的代码,自己终于摸索成功了,Mark下。
直接上代码,代码如下:
[csharp]view plaincopy
ing System;
ing System.Collections.Generic;
ing System.Linq;
ing System.Text;
ing System.IO;
ing System.Collections;
ing Microsoft.Office.Interop.Word;
ing Microsoft.Office.Core;
ing System.Reflection;
10.
space TestWord
12.{
13./// <summary>
14./// 从传入的word文档中替换掉指定书签的内容,主要是为了解决封面中的内容
15./// 抽取命令:
16./// xx.exe -p D:/temp/test.doc D:/result/mappting.txt
17.///
18./// mappting.txt 文件是替换test.doc文档中标签的匹配文件,比如哪个标签的内容需要替换为其他的值
19./// </summary>
20.class PageExtractor : IExtractor
21.{
22.
23.private object oMissing = System.Reflection.Missing.V alue;
24.
25.//标准页眉要替换的值在mapping.txt文件中存储的key
26.private String TB_YEMEI_GJB = "TB_YEMEI_GJB";
27.
28.//写入word的高级属性中的内容,需要设置为整形的高级属性名
29.private String[] m_oIntegerAdvPropertyNames = new String[]{ "密级","稿件"};
30.
31.//写入word的高级属性中的内容,需要设置为boolean
32.private String[] m_oBoolAdvPropertyNames = new Stri ng[] { "TRS" };
33.
34./// <summary>
35./// 从指定word中抽取出word正文
36./// </summary>
37./// <param name="_sSourceWordPath"></param>
38./// <returns></returns>
39.public bool execute(string[] args)
40.{
41._Application oWord = WordProcessHelper.getInstance ().getApplication();
42._Document oDoc = null;
43.String _sWordPath = "";
44.LogServer currLogServer = LogServer.getInstance();
45.
46.try
47.{
48.//1.参数需要长度为3,第一个是“-p”,第二个是“要抽取的word路径”,第三个是“匹配的书签替换文件”
49.if (args.Length < 3)
50.{
51.throw new Exception("替换封面时传入的参数个数至少为3个,第一个是‘-p’,第二个是‘要抽取的word路径’,第三个是标签‘匹配的UTF-8编码的txt文件内容’,第四个是文档的高级属性内容");
52.}
53.
54._sWordPath = args[1];//获取要抽取的原word路径
55.if (!File.Exists(_sWordPath))
56.{
57.throw new Exception("Word文件[" + _sWordPath + "]不存在!");
58.}
59.
60.String sMappingFilePath = args[2];
61.if (CMyString.isEmpty(sMappingFilePath))
62.{
63.throw new Exception("没有传入替换doc文件内容的匹配文件路径!");
64.}
65.
66.//1.读取需要替换的文件内容
67.Properties mappingProperties = new Properties(sMap pingFilePath);
68.if (mappingProperties.size() <= 0)
69.{
70.currLogServer.writeLogLine("文件[" + sMappingFilePath + "]中要替换的内容为空!");
71.return true;
72.}
73.
74.//2.读取word中标签
75.DateTime beginDateTime = new DateTime();
76.object oDocFilePath = _sWordPath;
77.object oReadOnly = false;
78.object oAddToRecentFiles = false;
79.oDoc = oWord.Documents.Open(ref oDocFilePath, ref oMissing, ref oReadOnly, ref oAddT oRecentFiles, ref oMissing, re f oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing , ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMiss ing, ref oMissing);
80.
81.//3.获取标签名与对应的Range对象的对应关系
82.Hashtable oBookIdToRangeMap = getBookIdToRange (oDoc, mappingProperties);
83.if (oBookIdToRangeMap == null || (oBookIdT oRangeM ap.Count == 0))
84.{
85.return true;
86.}
87.
88.//4.替换Range对象的内容为mapping文件中的属性值
89.replaceMappingContent(oDoc, oBookIdToRangeMap, mappingProperties);
90.
91.//5.替换页眉
92.Range allRange = oDoc.Range(ref oMissing, ref oMissi ng);
93.Sections allSections = allRange.Sections;
94.currLogServer.writeLogLine("开始替换[" + _sWordPath + "]页眉.");
96.if (allSections != null && (allSections.Count > 0))
97.{
98.String sTBYeMeiGJB = mappingProperties.getProperty AsString(TB_YEMEI_GJB, false);
99.currLogServer.writeLogLine("[" + _sWordPath + "]页眉要替换的值为:" + sTBYeMeiGJB);
100.sTBYeMeiGJB = CMyString.showEmpty(sTBYeMeiGJB);
101.for (int i = 1; i <= allSections.Count; i++)
102.{
103.Section aSection = allSections[i];
104.if (aSection == null)
105.{
106.continue;
107.}
108.
109.//设置奇数页和偶数页的页眉
110.aSection.Headers[WdHeaderFooterIndex.wdHeaderFo oterPrimary].Range.Text = sTBYeMeiGJB;
111.aSection.Headers[WdHeaderFooterIndex.wdHeaderFo oterEvenPages].Range.Text = sTBYeMeiGJB;
112.}
113.}
114.
115.DateTime endDateTime = new DateTime();
116.String sTimeDuration = DateTimeHelper.dateDiff(begi nDateTime, endDateTime);
117.currLogServer.writeLogLine("[" + _sWordPath + "]页眉替换完成,用时:" + sTimeDuration);
119.//TDO:写入国军标的一些标准属性
120.//读取需要写入到文档高级属性的
121.if (args.Length < 4) {
122.return true;
123.}
124.
125.String sAdvancePropertyFilePath=args[3];
126.if (CMyString.isEmpty(sAdvancePropertyFilePath)) { 127.return true;
128.}
129.Properties advanceProperties = new Properties(sAdva ncePropertyFilePath);
130.if (advanceProperties.size() <= 0)
131.{
132.currLogServer.writeLogLine("文件[" + sAdvancePropertyFilePath + "]中要写入的高级属性内容为空!");
133.return true;
134.}
135.
136.//写入属性
137.currLogServer.writeLogLine("[" + _sWordPath + "]开始写入高级属性.");
138.writeDocAdvanceProperty(oDoc, advanceProperties);
139.currLogServer.writeLogLine("[" + _sWordPath + "]高级属性写入完成.");
140.
141.//TODO:返回成功标记
142.return true;
144.}
145.catch (Exception ex)
146.{
147.currLogServer.writeLogLine("页眉替换从文件[" + _sWordPath + "]时发生错误:"+ex.Message);
148.throw new Exception("页眉替换从文件[" + _sWordPath + "]时发生错误", ex);
149.}
150.finally
151.{
152.//关闭当前文档
153.object saveOption = WdSaveOptions.wdSaveChanges;
154.if (oDoc != null)
155.{
156.oDoc.Close(ref saveOption, ref oMissing, ref oMissing) ;
157.//System.Runtime.InteropServices.Marshal.ReleaseCo mObject(oDoc);
158.}
159.
160.}
161.}
162.
163./// <summary>
164./// 把指定的高级属性的Properties中的内容写入到文档的高级属性中
165./// </summary>
166./// <param name="oDoc"></param>
167./// <param name="advanceProperties"></param> 168.private void writeDocAdvanceProperty(_Document oD oc, Properties advanceProperties) {
169.if (oDoc == null || (advanceProperties == null) || (adva nceProperties.size()<=0))
170.{
171.return;
172.}
173.
174.//遍历Properties属性
175.Hashtable allAdvanceProperties=advanceProperties.g etProperties();
176.if (allAdvanceProperties == null || (allAdvanceProperti es.Count <= 0)) {
177.return;
178.}
179.
180.//获取高级属性对象
181.object oDocCustomProps = oDoc.CustomDocumentPr operties;
182.Type typeDocCustomProps = oDocCustomProps.GetT ype();
183.
184.//遍历集合
185.foreach (String sPropName in allAdvanceProperties.Ke ys)
186.{
187.String sValue = (String)allAdvanceProperties[sPropNa me];
188.sValue = CMyString.showEmpty(sValue);
189.
190.//获取属性名的类型
191.Object oPropItemObj = getPropertyObjByName(oDoc CustomProps, typeDocCustomProps, sPropName);
192.if (oPropItemObj == null)
193.{
194.//不存在,则添加
195.MsoDocProperties oPropertType = getPropertyTypeB yName(sPropName);
196.object[] oArgs = {sPropName,false,
197.oPropertType,
198.sValue};
199.typeDocCustomProps.InvokeMember("Add", BindingFl ags.Default |
200.BindingFlags.InvokeMethod, null,
201.oDocCustomProps, oArgs);
202.}
203.else {
204.//已经存在,则覆盖属性
205.Type typeItemProp = oPropItemObj.GetType();
206.typeItemProp.InvokeMember("Value",
207.BindingFlags.Default | BindingFlags.SetProperty,
208.null, oPropItemObj,
209.new object[] { sValue });
210.}
211.}
212.
213.}
214.
215./// <summary>
216./// 从指定的自定义高级属性中查找指定名称的Item对象,如果没有找到,则返回null
217./// </summary>
218./// <param name="oDocCustomProps"></param> 219./// <param name="typeDocCustomProps"></param>
220./// <param name="_sPropertyName"></param>
221./// <returns></returns>
222.private object getPropertyObjByName(object oDocCu stomProps,Type typeDocCustomProps, String _sPropertyName)
223.{
224.if (CMyString.isEmpty(_sPropertyName)) {
225.return null;
226.}
227.if (oDocCustomProps == null || typeDocCustomProps == null) {
228.return null;
229.}
230.
231.//通过反射去查找对象
232.//获取值
233.object oPropItem = null;
234.try
235.{
236.oPropItem = typeDocCustomProps.InvokeMember("It em",
237.BindingFlags.Default |
238.BindingFlags.GetProperty,
239.null, oDocCustomProps,
240.new object[] { _sPropertyName });
241.}
242.catch (Exception ex) {
243.//TODO:由于没有找到判断是否存在属性的接口,所以这里通过Item来判断,如果属性不存在,则会报错,这里粗鲁的忽略掉异常
244.oPropItem = null;
245.}
246.
247.//返回结果
248.return oPropItem;
249.}
250.
251./// <summary>
252./// 根据属性名获取该属性对应的类型
253./// </summary>
254./// <param name="sPropName"></param>
255./// <returns></returns>
256.private MsoDocProperties getPropertyTypeByName(St ring sPropName)
257.{
258.if (CMyString.isEmpty(sPropName)) {
259.return MsoDocProperties.msoPropertyTypeString;
260.}
261.//判断是否是整形
262.bool bInStrArray = CMyList.isInStrArray(sPropName, m_oIntegerAdvPropertyNames, true);
263.if (bInStrArray) {
264.return MsoDocProperties.msoPropertyTypeNumber;
265.}
266.//判断是否是bool型
267.bInStrArray = CMyList.isInStrArray(sPropName, m_oBo olAdvPropertyNames, true);
268.if (bInStrArray) {
269.return MsoDocProperties.msoPropertyTypeBoolean;
270.}
271.
272.//默认返回字符串
273.return MsoDocProperties.msoPropertyTypeString;
274.}
275.
276./// <summary>
277./// 返回指定文档中需要替换属性的书签名称与Range对象HashTable对象
278./// </summary>
279./// <param name="oDoc"></param>
280./// <param name="mappingProperties"></param> 281./// <returns></returns>
282.private Hashtable getBookIdT oRange(_Document oDo c, Properties mappingProperties) {
283.//1.参数校验
284.Hashtable oBookIdToRangeMap = new Hashtable();
285.if (oDoc == null || (mappingProperties == null)) {
286.return oBookIdToRangeMap;
287.}
288.
289.//获取标签内容
290.Bookmarks allBookMars = oDoc.Bookmarks;
291.for (int i = 1; i <= allBookMars.Count; i++)
292.{
293.object oIndex = i;
294.Bookmark aBookMark = allBookMars.get_Item(ref oIn dex);
295.if (aBookMark == null)
296.{
297.continue;
298.}
299.String sBookName = ;
300.if (CMyString.isEmpty(sBookName)) {
301.continue;
302.}
303.
304.//是否包含在要替换的属性集合中
305.if (!mappingProperties.contains(sBookName,true)) { 306.continue;
307.}
308.
309.//压入书签名称与Range对象集合中
310.oBookIdToRangeMap.Add(sBookName.Trim().T oUpper (), aBookMark.Range);
311.}
312.
313.//返回集合中
314.return oBookIdToRangeMap;
315.}
316.
317./// <summary>
318./// 根据 mappingProperties中的属性值替换 oBookIdToRangeMap 指定Range对象的内容,并设置Range对象的书签名称
319./// </summary>
320./// <param name="oDoc"></param>
321./// <param name="oBookIdToRangeMap"></param>
322./// <param name="mappingProperties"></param> 323.private void replaceMappingContent(_Document oDo c,Hashtable oBookIdToRangeMap, Properties mappingPropertie s)
324.{
325.//1.参数校验
326.if (oDoc == null || (oBookIdToRangeMap == null) || (m appingProperties == null)) {
327.return;
328.}
329.
330.//2.遍历Map对象
331.foreach (String sBookIdKey in oBookIdToRangeMap.K eys)
332.{
333.Range currBookRange = (Range)oBookIdT oRangeMap [sBookIdKey];
334.if (currBookRange == null) {
335.continue;
336.}
337.
338.//获取替换的值
339.String sReplaceValue = mappingProperties.getPropert yAsString(sBookIdKey,true);
340.sReplaceValue = CMyString.showEmpty(sReplaceValue );
341.currBookRange.Text = sReplaceValue;
342.
343.//重新设置书签
344.if (!oDoc.Bookmarks.Exists(sBookIdKey))
345.{
346.object oTempBookRange = currBookRange;
347.oDoc.Bookmarks.Add(sBookIdKey, ref oTempBookRan ge);
348.}
349.}
350.}
351.
352.
353.}
354.}。