一、写在开头

最近研究word文档的解析技术,我本身是VC的忠实用户,看到C#里面操作WORD这么舒服,同时也看到单位有一些需求,就想尝试一下,结果没想到里面的技术点真不少,同时网络上的共享资料很多,但是很多就是起了一个头没有完整的资料,因此在此记录一下,首先感谢怪兽哥哥(开源了了IOCP一整套开源库的家伙还有很多隐藏技能大家可以关注他)、骨头哥(不少好资料)、savageII哥(大牛)这些网友他们很有共享精神。废话不说了开始正题。

二、环境搭建

我用的VC2010,其实在VC6.0以上的版本设置都差不多,这里我用一下网友的资料我就不写了

1、  创建MFC工程,非Unicode。

2、  添加类型库,类向导->

在这个页面中选择要使用的WORD的类,这里用到了COM技术,本人能力有限就不介绍COM的原理了,添加完毕后,在需要用的到地方#include就可以了,这个地方有个注意点 需要注释到每个类的最前面的

#import "C:\\Program Files\\Microsoft Office\\Office12\\MSWORD.OLB" no_namespace这一句话因为有的安装目录可能不在这里,会提示错误。‘

三、类介绍

这里还是用网友的资料,Microsoft Office Word 2003 对象是按层次顺序排列的,层次结构顶端的两个主类是 Application 类和 Document 类。这两个类非常重要,因为在大部分时间里,您要么是在使用 Word 应用程序本身,要么是以某种方式处理 Word 文档。Word 对象模型严格遵循用户界面。Application 对象提供整个应用程序的包装,每个 Document 对象表示单个 Word 文档。这些对象各自都有很多方法和属性,您可以使用这些方法和属性操作对象或与对象交互。
   
Application
对象。Application 对象表示 Word 应用程序,是其他所有对象的父级。它的所有成员通常作为一个整体应用于 Word。可以使用该对象的属性和方法来控制 Word 环境。
   
Document
对象。Document 对象是 Word 编程的中枢。当您打开文档或创建新文档时,就创建了新的 Document 对象,该对象被添加到 Word 的 Documents 集合中。焦点所在的文档叫做活动文档,由 Application 对象的 ActiveDocument 属性表示。
Selection 对象。Selection 对象表示当前选择的区域,Selection 对象只存在一个。在 Word 用户界面中执行某项操作(例如,对文本进行加粗)时,应首先选择或突出显示文本,然后应用格式设置。Selection 对象始终存在于文档中。如果未选中任何对象,它表示插入点。此外,该对象还可以表示多个不连续的文本块。

View对象。该对象包含窗口或窗格的视图属性(如全部显示、域底纹、表格虚线等等)。

Pane对象。代表一个窗格。
    Range 对象。Range 对象表示文档中的一个连续的区域,由一个起始字符位置和一个结束字符位置定义。Range 对象的数量并不局限于一个。您可以在同一文档中定义多个 Range 对象。
    Bookmark
对象。Bookmark 对象与 Range 对象类似,它也表示文档中的一个连续区域,并具有一个起始位置和一个结束位置。书签用于在文档中标记一个位置,或者用作文档中的文本容器。Bookmark 对象可以小到只有一个插入点,也可以大到整篇文档。您还可以在文档中定义多个书签。
    Selection对象。这个对象就相当于光标,很多操作跟他相关,选中,移动等都需要这个对象,它在我们的编程中占有很重要的地位。

Shape 对象。代表一个图形层对象,例如自选图形、任意多边形、OLE 对象、ActiveX 控件、图片等。Shape 对象是
Shapes
集合的一个成员,该集合包含了一篇文档正文部分的所有图形,或文档页眉和页脚部分中的所有图形。

此外还有CParagraph、Font、Table、Cell、Shape等对象具体的作用可以查看MSDN。

四、具体使用

  1. Word文档的启动

在APP文件的InitInstance函数中需要添加如下代码,这个地方就是COM的初始化,如果存在就不需要添加了

if ( !AfxOleInit() )

{

AfxMessageBox(_T("无法初始化COM的动态链接库!"));

return FALSE;

}

CApplication0
WordApp ;

CDocuments
Docs ;

CDocument0
Doc ;

// 首先建立一个word实例对象

if (!WordApp.CreateDispatch(TEXT("Word.Application"))
)

{

AfxMessageBox("创建WORD服务失败!");

return
false;  // 一定要返回,否则程序崩溃

}

// 显示此对象文件 ,您也可以不调用此句,不显示对象文件

WordApp.put_Visible(false);

// 创建文档

Docs = WordApp.get_Documents();

// 打开一个新文档,将e:\\BuildJobEdit.rtf文件的内容添加到新文档中

CComVariant
tpl(strFile), NewTemplate(false), DocType(0), Visble;

Doc = Docs.Add(&tpl,&NewTemplate,&DocType,&Visble);

各种处理代码在此

// 释放各种对象

Docs.ReleaseDispatch();

Doc.ReleaseDispatch();

CComVariant
SaveChanges(false),
OriginalFormat, RouteDocument;

WordApp.Quit(&SaveChanges,&OriginalFormat,&RouteDocument
);

WordApp.ReleaseDispatch();

  1. Selection对象的应用,

获得当前word文档的光标。上面我们已经打开一个word文档了,CSelection Sel = WordApp.get_Selection();
这行代码就是获得光标了。

光标的移动。这就要看光标的移动函数了,CSelection的移动函数很多,主要有Move、MoveLeft、MoveRight等,具体的用法有很多大家可以自行查看MSDN帮助文档。

获得内容。我这里要提的有一个关键函数get_Text(),这个函数有一个作用,如果不是选中一段文字的情况下,它获得是光标旁边的那个字符的内容,也就是光标右边的那个字符。正因为有了这个功能我们就可以进行word文档的解析了。

do

{

CString strChar=Sel.get_Text();

}

while(Sel.Move(&_variant_t(1),&_variant_t(1))>0);

通过上面这段代码我们就可以一个字一个字的遍历word文档了strChar就代表光标右边的文字了。

很多人说你这种办法太笨了,这样的效率太慢了,别着急我这种做是有原因的,如果我们要针对word文档做其他操作的话,这种方式的优点就很明显了,我们如果想在当前光标点做插入和更改文字内容的操作就很方便了,我称这种方式为入微级的操作,如果只是想单单获得word的内容的话下面我还有其他的办法,请耐心的看下去。

添加内容,Selection还有InsertBefore和InsertAfter等操作,可以在当前光标点插入文字了。

选中文字,Selection的setRang函数可以帮助我们选中文字Sel.SetRange(iBeg,iEnd); 他的两个参数告诉我们的选中的起始点。选中文字后我们就可以对选中的文字设置字体颜色等操作了。

小技巧:

  • Sel.Move(&_variant_t(1),&_variant_t(1))是向前移动一个字符,如果在文档的结尾处会返回0
  • 选中一段文字后Sel.Move(&_variant_t(1),&_variant_t(1))会将光标定位到这段文字的末尾,而不是移动一个字符。
  • 用Selection的设置Font时必须选中一段文字才能设置,否则会提示异常。
  • StartOf和endof函数可以控制光标移动到某些内容的开头和结尾。
  • InsertBefore和InsertAfter添加文字后会选中添加的文字。
  • 这种方式针对复杂表格可能会导致死循环,我的方式是遇到表格直接不操作跳过去,等最后用表格类操作表格内容。
  1. 3.    
    页眉页脚的操作

尽管有HeaderFooter等类,如果是只是想获得内容,并且更新全部内容,而不进行入微级的操作的话可以使用这个类结合Sections会有很好的效果,这种方式很强大但是存在一定的问题,例如页眉页脚不一样的如何操作呢,我不是很喜欢,我要掌控所有,我需要的是入微级的操作。这种方式我贴一段VB宏的代码,给大家点启发

With ActiveDocument.Sections(1)

.Headers(wdHeaderFooterPrimary).Range.Text = "Header text"

.Footers(wdHeaderFooterPrimary).Range.Text = "Footer text"

End With

下面介绍我的方法直接上代码了

CWindow0  window=WordApp.get_ActiveWindow();

CPane0   pane=window.get_ActivePane();

CView0   view=pane.get_View();

//处理页眉

view.put_SeekView(9);//进入页眉视图

view.put_SeekView(10); //进入页脚视图

view.put_SeekView(0);//进入正文视图

进入到这三种视图后我们就可以利用Selection对象对我们的页眉页脚随心所欲的进行我们的操作了,具体操作看你自己的需求了。

小技巧:进入到页眉视图后想进入到下一个页眉视图怎么办呢,利用view.NextHeaderFooter();就可以进入到下一个页眉视图了,页脚也是一样的操作。如果想从页眉页脚视图中出来就可以view.put_SeekView(0);

  1. 4.    
    文本框的操作

主要类是shape和shapes,这个操作很简单直接贴代码了

//文本框处理

CShapes shapes=Doc.get_Shapes();//获得所有图形的集合

long shapCount=shapes.get_Count();//图形的数量

for (int lc = 1 ; lc < shapCount+1 ;
lc++ )//遍历图形

{

CShape
shape=shapes.Item(&_variant_t(lc));

CTextFrame
text=shape.get_TextFrame();//对象包含指定图形的文字

if (text.get_HasText())//对象是否包含文字

{

shape.Select(&_variant_t(true));

Sel.StartOf(&_variant_t(6),&_variant_t(0));

//光标的入微级操作

}

}

注意:如果文本框中再嵌套文本框这种方法可能不好用,如果大牛知道怎么操作,请联系我谢谢。

  1. 5.    
    表格的操作

主要是类是CTables、CTable、Cells、Cell,代码如下

CTables0
tables=Doc.get_Tables();//获得当前文档所有表格的集合

int iTableCount=tables.get_Count();

for (int t=1;t<iTableCount+1;t++)//遍历表格

{

CTable0 table=tables.Item(t);//获得表格

table.Select();//选中表格

CCells cels=Sel.get_Cells();//获得表格单元格的集合

int iCelCount=cels.get_Count();

CCell cel=cels.Item(1);//获得第一个单元格

cel=cel.get_Next();//获得下一个单元格

}

获得了单元格我们就可以进行入微级的光标操作了

     注意点:这里用的是get_Next()函数进行单元格的集合的遍历主要是因为用循环的方式时报错了,具体原因不祥,如果知道的大牛请联系我。

五、写在最后

花了2个小时把这篇文章写完了,第一次写,啰嗦的东西不少,还有很多东西没总结出来,遗漏了不少,因为工作限制,业务逻辑的代码就没发出来,请大家见谅,本身我的水平也有限,没有太多高深的东西,先写这么多吧,后续在继续补充,本身QQ:158513320,欢迎大家交流拍砖,跪求大牛指点谢谢。

VC操作WORD文档总结的更多相关文章

  1. iText操作word文档总结

    操作word文档的工具有很多,除了iText之外还有POI,但是POI擅长的功能是操作excel,虽然也可以操作word,但是能力有限,而且还有很多的bug,技术并不成熟,下面就重点介绍一种操作wor ...

  2. C#操作Word文档(加密、解密、对应书签插入分页符)

    原文:C#操作Word文档(加密.解密.对应书签插入分页符) 最近做一个项目,客户要求对已经生成好的RTF文件中的内容进行分页显示,由于之前对这方面没有什么了解,后来在网上也找了相关的资料,并结合自己 ...

  3. 利用Python操作Word文档【图片】

    利用Python操作Word文档

  4. Java文件操作系列[3]——使用jacob操作word文档

    Java对word文档的操作需要通过第三方组件实现,例如jacob.iText.POI和java2word等.jacob组件的功能最强大,可以操作word,Excel等格式的文件.该组件调用的的是操作 ...

  5. QTP操作word文档

    QTP可以对word文档进行操作,这里最主要展示的是向word文档写入内容,并保存的功能. Option explicit Dim wordApp Set wordApp = createobject ...

  6. c#中操作word文档-四、对象模型

    转自:http://blog.csdn.net/ruby97/article/details/7406806 Word对象模型  (.Net Perspective) 本文主要针对在Visual St ...

  7. python 操作word文档

    因为工作需要操作一些word文档,记录一下学习思路 #-*- encoding: utf8 -*- import win32com from win32com.client import Dispat ...

  8. 2.QT中操作word文档

     Qt/Windows桌面版提供了ActiveQt框架,用以为Qt和ActiveX提供完美结合.ActiveQt由两个模块组成: A   QAxContainer模块允许我们使用COM对象并且可以 ...

  9. C# 操作Word 文档——添加Word页眉、页脚和页码

    在Word文档中,我们可以通过添加页眉.页脚的方式来丰富文档内容.添加页眉.页脚时,可以添加时间.日期.文档标题,文档引用信息.页码.内容解释.图片/LOGO等多种图文信息.同时也可根据需要调整文字或 ...

随机推荐

  1. jquery easyui 实战总结

    (2012-09-26 10:22:24) 转载▼ 标签: it 分类: Javascript 一.tree 1.根据node id查找对应的node,然后选择该节点:                 ...

  2. IReport制作报表——日期时间显示格式

    转自:https://blog.csdn.net/linglinglu/article/details/9022679?utm_source=blogxgwz2 IReport工具在制作报表的时候,会 ...

  3. java:calendar类及一些比较实用的utils(一)

    在java编程中经常会用到时间日期的计算.比较.格式化等等操作,刚开始接触Calendar类时,还是在初学习期间,小小白一枚,看着这个好复杂,懒惰心理作祟也就没有怎么去学习,后来在项目中经常用到,索性 ...

  4. 利用PDF.JS插件解决了本地pdf文件在线浏览问题(根据需要隐藏下载功能,只保留打印功能)

    我是在IE11和谷歌上做的测试,都可以显示,把做出的东西记录下来,方便大家还有自己学习! 可以在IIS7服务器上也可以下载Tomcat来做服务器 Tomcat下载地址   http://pan.bai ...

  5. web开发并部署到Tomcat上

    1. eclipse配置tomcat https://jingyan.baidu.com/article/e4d08ffdabb0710fd2f60de9.html https://blog.csdn ...

  6. 1.18-1.21 Oozie Coordinator调度

    一.时区问题 1.修改系统时区 ## [root@hadoop-senior hadoop-2.5.0-cdh5.3.6]# rm -rf /etc/localtime [root@hadoop-se ...

  7. 非侵入式JavaScript(Unobtrusive javaScript)理解

    转载自 https://my.oschina.net/leegq/blog/279750 在Web的早期阶段,也就是在jQuery出现以前,在同一个文件中混杂JavaScript代码和HTML标记是非 ...

  8. Winform禁止程序多开 &&禁止多开且第二次激活第一次窗口

    一.禁止多开问题,运用Mutex锁 在Program.cs中运用Mutex锁 bool createNew;using (System.Threading.Mutex mutex = new Syst ...

  9. 洛谷 - P1663 - 山 - 半平面交

    https://www.luogu.org/problemnew/show/P1663 给定山的性状,求一个最低点可以看见所有的地方. 就是半平面交. 粘贴全家福: #include<bits/ ...

  10. Tarjan找桥和割点与点连通分量与边连通分量【未成形】

    之前只学了个强连通Tarjan算法,然后又摸了缩点操作: 然后今天在lightoj摸了一道模板题,是求所有桥的题: 然后发现,要把:割点,割点集合,双连通,最小割边集合(桥),点连通分量,边连通分量都 ...