C++操作Word学习笔记

http://blog.sina.com.cn/s/blog_945492f401012nnn.html


C++操作Word学习笔记(五)

  (2012-09-21 12:59:08)

由于学习C++操作word文档是临时需要,所以有些东西也只是知其然不知其所以然,有些代码也是抄了人家的,拿来应需。

C++操作word听说有两种方法,一种是COM、一种是ATL,这里用的是COM。有些函数不知道参数是什么意思时,可以找到函数原型帮助理解。Word的预定义枚举类型都是Wd开头,如WdSeekView::wdSeekMainDocument表示文字视图,WdSeekView::wdSeekCurrentPageHeader表示页眉视图,使用这些枚举类型,可以帮助参数的设置。

这里给出了两个昨天写的例子,能运行的。环境是VS2008和Office2003。第一个例子介绍了创建新文档、插入表格、输入文字、字体设置、设置表格边框、合并单元格、设置页眉页脚、插入图片、保存文件等功能的方法。第二个例子生成了一个完整的报告,包括页边距、段落对齐等。

具体步骤:

1.新建MFC工程,project - add class,选择file。找到Office安装目录下的MSWORD.OLB文件,如C:\\Program Files\\Microsoft Office\\OFFICE11\\MSWORD.OLB

2.加入需要的接口,下面例子中,C开头的类都是此处加入的接口

3.VS2008会为工程添加相应头文件,此时需要把头文件里的

#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\MSWORD.OLB" no_namespace

改成

#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\MSWORD.OLB" no_namespace raw_interfaces_only \
 rename("FindText","_FindText") \
 rename("Rectangle","_Rectangle") \
 rename("ExitWindows","_ExitWindows")

注意,“\”字符后面不能加空格

3.#include // 为了方便操作 VARIANT 类型变量,使用 CComVariant 模板类

4.好了,可以编程了

//例子1

void CMyWordDlg::OnBnClickedButton1()
{
 CoInitialize(NULL);//初始化COM,与最后一行CoUninitialize对应
//CPageSetup pagesetup=doc.get_PageSetup();//页面设置相关,没用到
 CApplication app;
 if(!app.CreateDispatch(_T("word.application"))) //启动WORD
 {
  AfxMessageBox(_T("居然你连OFFICE都没有安装吗?"));
  return;
 }

 AfxMessageBox(_T("WORD 已经运行启动啦,你可以用Ctrl+Alt+Del查看"));
 app.put_Visible(TRUE); //设置WORD可见。
 
 CDocuments docs = app.get_Documents();
 docs.Add(new CComVariant(_T("")),new CComVariant(FALSE),new CComVariant(0),new CComVariant());//创建新文档
 
 AfxMessageBox(_T("下面,程序要向WORD发送字符啦"));
 CSelection sel=app.get_Selection();//Selection表示输入点,即光标闪烁的那个地方
 CFont0 font =sel.get_Font();
 font.put_Name(_T("宋体"));//设置字体
 font.put_Size(14);
 font.put_Color(WdColor::wdColorGreen);
 font.put_Bold(1);
 sel.TypeText(_T("HELLO\r\n大家好呀"));//调用函数Selection::TypeText 向WORD发送字符
 font.ReleaseDispatch();//【注】【意】所有东西用完之后一定要ReleaseDispatch,否则报错;不过最好像例子2中,在最后集中ReleaseDispatch


 //插入表格
 CDocument0 doc = app.get_ActiveDocument();//活动文档

 CTables0 tables = doc.get_Tables();
 tables.Add(sel.get_Range(), 7,11,  new CComVariant(),new  CComVariant());//插入表

 CTable0 table=tables.Item(1);

 CBorders borders=table.get_Borders();//设置表格边框
 borders.put_InsideLineStyle(WdLineStyle::wdLineStyleSingle);
 borders.put_OutsideLineStyle(WdLineStyle::wdLineStyleDouble);
 //borders.put_OutsideLineWidth(WdLineWidth::wdLineWidth075pt);
 borders.ReleaseDispatch();

 sel.TypeText(_T("test1"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test2"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test3"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test4"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test5"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test6"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test7"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test8"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test9"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test10"));
 sel.MoveRight(COleVariant((short)1),COleVariant(short(1)),COleVariant(short(0)));
 sel.TypeText(_T("Test11"));
 int i=0,j=0;
 for(i=2;i<7;i+=2)
 {
  CCell c1=table.Cell(i,1);
  CCell c2=table.Cell(i+1,1);
  c1.Merge(c2);//合并单元格
  c1.ReleaseDispatch();
  c2.ReleaseDispatch();
 }
 CCell c;
 CString strName[3];
 strName[0] = "yingkou";
 strName[1] ="zyq654321";
 strName[2] ="iwaswzq";
 for(j=0,i=0;i<3;++i,j+=2)
 {
  c=table.Cell(j+2,1);
  c.Select();
  CCells cs=sel.get_Cells();
  cs.put_VerticalAlignment(WdVerticalAlignment::wdAlignVerticalCenter);
  sel.TypeText(strName[i]);
  sel.MoveDown(COleVariant((short)5),COleVariant(short(1)),COleVariant(short(0)));
  cs.ReleaseDispatch();
  c.ReleaseDispatch();
 }
 c=table.Cell(7, 2);
 c.Select();
 CString strData[6];
 strData[0]="111";
 strData[1]="222";
 strData[2]="333";
 for(i=0,j=0;i<6;++i,++j)
 {
  if(i%2==0)
   j=0;
  sel.TypeText(strData[j]);
  sel.MoveUp(COleVariant((short)5),COleVariant(short(1)),COleVariant(short(0)));
 }
 c.ReleaseDispatch();
 
 c=table.Cell(7, 2);
 c.Select();//选中最后一行
 sel.MoveDown(COleVariant((short)5),COleVariant(short(1)),COleVariant(short(0)));//下移,输入点到页末
 c.ReleaseDispatch();
 CComVariant pageBreak = CComVariant(WdBreakType::wdPageBreak);
 sel.InsertBreak(&pageBreak);//插入分页符
 
 sel.TypeText(_T("this is the 2nd page!\r\n"));

 

 //设置页眉页脚
 CWindow0 win = doc.get_ActiveWindow();//窗口Window对象
 CPane pane = win.get_ActivePane();//当前活动Pane窗格对象
 CView0 view = pane.get_View();//View视图对象
 view.put_Type(WdViewType::wdPrintView);//设置视图类型:打印、打印预览、阅读...
 view.put_SeekView(WdSeekView::wdSeekCurrentPageHeader);//页眉视图
 CHeaderFooter headerfooter = sel.get_HeaderFooter();
 //headerfooter.put_LinkToPrevious(FALSE);//取消“与上一节相同”
 sel.TypeText(_T("this is header"));
 
 view.put_SeekView(WdSeekView::wdSeekCurrentPageFooter);//页脚视图
 sel.TypeText(_T("this is footer\r\nand here is 2nd line"));
 
 sel.TypeText(_T("第 "));
 CRange range = sel.get_Range();
 CFields fields = range.get_Fields();
 CField field = fields.Add(range, COleVariant((short)WdFieldType::wdFieldPage),COleVariant(short(0)),COleVariant(short(0)));//页码
 sel.TypeText(_T("页 共 "));
 range = sel.get_Range();
 fields = range.get_Fields();
 field = fields.Add(range, COleVariant((short)WdFieldType::wdFieldNumPages),COleVariant(short(0)),COleVariant(short(0)));//页数
 sel.TypeText(_T(" 页"));
 //下面是设置页码格式
 
 view.put_SeekView(WdSeekView::wdSeekMainDocument);//返回文字视图
 
 //插入图片,先以嵌入型图像插入,再转成浮移图像,可以移动位置,也可不转

 //据说不先按嵌入型插入的话,都会插在第一页
 range = sel.get_Range();
 COleVariant vRange;
 vRange.vt=VT_DISPATCH;
 vRange.pdispVal = range.m_lpDispatch;
 vRange.pdispVal->AddRef();
 CnlineShapes inlineshapes = doc.get_InlineShapes();
 CnlineShape inlineshape = inlineshapes.AddPicture(_T("C:\\Documents and Settings\\Administrator\\桌面\\未命名.bmp"), COleVariant((long)0), COleVariant((long)1),&vRange);
 inlineshape.put_ScaleWidth(50);
 inlineshape.put_ScaleHeight(50);
 //CShape shape = inlineshape.ConvertToShape();
 //shape.put_Width(165);
 //shape.put_Height(165);
 //shape.put_Top(200);
 //shape.put_Left(100);
 //shape.ConvertToInlineShape();
 //shape.ReleaseDispatch();
 vRange.Detach();
 sel.TypeText(_T("oh, i see the image"));
 inlineshape.ReleaseDispatch();
 inlineshapes.ReleaseDispatch();
 

 //pagenumers.ReleaseDispatch();
 field.ReleaseDispatch();
 fields.ReleaseDispatch();
 range.ReleaseDispatch();
 headerfooter.ReleaseDispatch();
 view.ReleaseDispatch();
 pane.ReleaseDispatch();
 win.ReleaseDispatch();

 

 //保存文件
 CString FileName(_T("C:\\Documents and Settings\\Administrator\\桌面\\doc.doc")); //文件名
 COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
 COleVariant varZero((short)0); 
 COleVariant varTrue(short(1),VT_BOOL); 
 COleVariant varFalse(short(0),VT_BOOL); 
 doc.SaveAs(COleVariant(FileName), varZero, varFalse,
  COleVariant(_T("")), varTrue, COleVariant(_T("")),
  varFalse, varFalse, varFalse, varFalse, varFalse,
  covOptional,covOptional,covOptional,covOptional,
  covOptional);

 AfxMessageBox(_T("WORD准备要退出啦"));
 table.ReleaseDispatch();
 tables.ReleaseDispatch();
 doc.ReleaseDispatch();
 sel.ReleaseDispatch();
 docs.ReleaseDispatch(); 
 //调用Quit退出WORD应用程序。当然不调用也可以,那样的话WORD还在运行着那
 app.Quit(new CComVariant(FALSE),new CComVariant(),new CComVariant());
 app.ReleaseDispatch();   //释放对象指针。切记,必须调用
 AfxMessageBox(_T("Step1执行完成。接着请学习Setp2"));
 CoUninitialize();//对应CoInitialize

}

//【分割线】【分割线】【分割线】【分割线】【分割线】【分割线】【分割线】【分割线】

//【分割线】【分割线】【分割线】【分割线】【分割线】【分割线】【分割线】【分割线】

//例子2

void CReportDlg::OnBnClickedOk()
{
 CApplication app;
 CDocuments docs;
 CSelection sel;
 CFont0 font;
 CDocument0 doc;
 CTables0 tables;
 CTable0 table;
 CBorders borders;
 CColumns0 columns;
 CColumn column;
 CCell c;
 CWindow0 win;
 CPane pane;
 CView0 view;
 CHeaderFooter headerfooter;
 CRange range;
 CFields fields;
 CField field;
 CnlineShapes inlineshapes;
 CnlineShape inlineshape;
 CShading shading;//底纹
 CPageSetup pagesetup;//页面设置
 CParagraphs paragraphs;
 CParagraph paragraph;

 CoInitialize(NULL);//初始化COM
 if(!app.CreateDispatch(_T("word.application"))) //启动WORD
 {
  AfxMessageBox(_T("木有找到OFFICE。。。%>_


---------------------------------------------------------------------------------------------------------------------------------------------


注意:

1. 里面对象的所有索引都是从1开始,比如tables.Item(0)会出错,tables.Item(1)会得到首个表格

---------------------------------------------------------------------------------------------------------------------------------------------

例子:取得文档中表格中的单元格内容

// COM相关变量
COleVariant vTrue((short)TRUE);
COleVariant vFalse((short)FALSE);
COleVariant vOpt((long)DISP_E_PARAMNOTFOUND, VT_ERROR);


// Word相关变量
CApplication wordApp; // 在对象继承结构中是最顶层的对象,可以通过它的方法访问别的工作类型的对象(本例主要是word)
CDocuments docs; // 代表所有打开的文档对象
CDocument0 doc; // 单一文件
CSelection selection; // 选择区域
CRange rangeWord; // 文档区域
CTables0 tables; // 所有表格
CTable0 table; // 单一表格
CCell cell; // 单元格


// 启动Word程序
if (!wordApp.CreateDispatch(_T("word.application"))) // 启动Word
{
AfxMessageBox(_T("无法启动Word"));
return FALSE;
}


// 设置Word不可见
wordApp.put_Visible(FALSE);


// 打开指定Doc
docs = wordApp.get_Documents();
doc = docs.Open(COleVariant(strFileName), vFalse, vTrue, vFalse, vOpt, vOpt,
vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt, vOpt);
if (!doc) // 打开失败
{
AfxMessageBox(_T("无法打开文件"));
return FALSE;
}


// 获得选择焦点
selection = wordApp.get_Selection();


// 获得表格
tables = doc.get_Tables();
table = tables.Item(1); // 索引从1开始


// 获得首个单元格
cell = table.Cell(1, 1); // 索引从1开始
cell.Select(); // 选择首个单元格

// 顺序获得表格里每个单元格的内容
CString str = selection.get_Text();
while (cell = cell.get_Next())
{
cell.Select();
str = selection.get_Text();
}


// 关闭文档
doc.Close(vOpt, vOpt, vOpt);
// 退出Word
wordApp.Quit(vOpt, vOpt, vOpt);

你可能感兴趣的:(C++)