为了实现办公的自动化,需要实现文档的自动流转。开发出的WORD和WPS插件的功能包括显示批注、隐藏批注、引入文件、附加对象、保存文档、退出应用。
1 Word插件开发 1.1 插件开发方法 1.1.1 开发语言开发语言的选择,可以选择C++和C#。
1.1.2 Visual studio开发说明Visual Studio 2010提供了各个版本Office的插件开发,新建工程-按照的模板-Visual C#-Office-2010,运行程序时其会调用本地安装的Office;文件-选项-加载项-COM加载项,在此可以选择COM加载项。
(1) Word开发引用的文件有Microsoft.Office.Interop.Word及Office
(2) 使用的命名空间
using Word = Microsoft.Office.Interop.Word;
using Office = Microsoft.Office.Core;
using Microsoft.Office.Tools.Word;
1.1.3 Visual studio的SamplesVisual Studio提供了本地WORD插件开发的示例,所在路径
Visual Studio2010-Help-Samples-local Samples folder。
1.2 三种访问word的方法1.2.0.1 官方API
根据官方提供的API,可以实现对word的操作。
1.2.0.2 调用对话框(属于API范畴)
通过word提供的对话框方法调用Word.WdWordDialog.wdDialogInsertObject,打开“附加对象“对话框。
this.Application.Dialogs[Word.WdWordDialog.wdDialogInsertObject].Execute();
1.2.0.3 word控件
获取其控件,然后执行Excute,打开“附加对象”对话框
this.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[16].Execute();
1.3 对WORD文档的操作 1.3.1 打开文档
Word.Application app = new Word.Application(); Word.Document dd = app.Documents.Open("C:\\hi12.docx");
1.3.2 word2010控件的操作方法微软在word使用了Ribbon Interface,通过该接口可以获取所有的菜单和工具栏的命令。具体见:
http://office.microsoft.com/en-us/outlook-help/learn-where-menu-and-toolbar-commands-are-in-office-2010-and-related-products-HA101794130.aspx#_Toc268688374
1.3.2.1 两层节点访问方式
word一般是通过CommandBar/CommandBars和Control/Controls访问控件。只有两层的访问方式:第一层,直接访问CommandBar/CommandBars,通过CommandBar/CommandBars访问其下的Control/Controls。
如:
获取Show Markup命令条下几个Controls:
Globals.IRHelperBar.Application.ActiveDocument.CommandBars["Show Markup"].Controls.Count;
执行Show Markup命令条下的第7个Controls的实体的方法:
Globals.IRHelperBar.Application.ActiveDocument.CommandBars["Show Markup"].Controls[7].Excute();
1.3.2.2 多层节点的访问方式
1)子节点访问方式
如果Control下面还有子节点,查看其CommandBar下的Name;通过此名获访问其下的Controls。类似多叉树的访问方式。
Globals.IRHelperBar.Application.ActiveDocument.CommandBars["Reviewers"].Controls[1];
2)三层节点的访问方式
正常只是提供两级的访问结构CommandBars-Controls;如果有第三级并且需要访问,那么把Control提升为Command,创新构造两级结构Command-Control,从而实现第三层的访问。
This.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[16].Execute();
1.3.3 Word的部分功能1.3.3.1 显示/隐藏标注
1)隐藏标注
调用API方式
wdApp.ActiveWindow.View.ShowRevisionsAndComments = False
控件方式
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Reviewing"].Controls[1]).Control.ListIndex = 2;
2)显示标注
调用API方式
wdApp.ActiveWindow.View.ShowRevisionsAndComments = True
控件方式
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Reviewing"].Controls[1]).Control.ListIndex = 1;
3)切换显示/隐藏标注
Globals.ThisAddIn.Application.Application.ActiveDocument.CommandBars["Show Markup"].Controls[3].Execute();
1.3.3.2 隐藏/显示审阅窗格
执行下面的语句,可以开始打开/关闭审阅窗格
doc.CommandBars["Reviewing"].Controls["Reviewing Pane"].Execute();
1.3.3.3 引入文件
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[16].Execute();
1.3.3.4 附加对象
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[4]).CommandBar.Controls[17].Execute();
1.3.3.5 保存文件
Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Standard"].Controls[3].Execute();
1.3.3.6 退出应用
((dynamic)Globals.ThisAddIn.Application.ActiveDocument.CommandBars["Menu Bar"].Controls[1]).CommandBar.Controls[21].Execute();
1.4 遍历Word2010的一级和二级控件//Create Word Application
Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();
//Create a new txt file to record controls' list
StreamWriter sw = System.IO.File.CreateText(@"C:\Word Command Bar Control List.txt");
//loop through wordApp.CommandBars to get all CommandBars
foreach (Office.CommandBar cb in wordApp.CommandBars)
{
sw.WriteLine(cb.Name);
//loop through each CommandBar's Controls collection to get all controls
foreach (Office.CommandBarControl cbc in cb.Controls)
{
sw.WriteLine("\t" + cbc.Caption);
}
}
1.5 Word文档的窗体事件http://support.microsoft.com/kb/302817
最小化word窗口时,关闭
Form1 fm;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
fm = new Form1();
fm.Show();
// fm.TopMost=false;
// this.Application.ActiveDocument.Windows.Count;
object aa = this.Application.ActiveDocument.CommandBars["Show Markup"].Controls[3].OnAction;
this.Application.WindowSize+=new Word.ApplicationEvents4_WindowSizeEventHandler(Application_WindowSize);
}
private void Application_WindowSize(Word.Document Doc, Word.Window Wn)
{
if (this.Application.WindowState == Word.WdWindowState.wdWindowStateMinimize)
{
fm.Hide();
}
else
{
fm.Show();
}
}
2 WPS插件开发WPS插件开发可以在WPS二次开发论坛http://bbs.wps.cn/forum-wpsercikaifa-1.html找到开发的资料。
开发语言
WPS可以使用C++、VB6/VAB、.net三种语言
本人实现了C++、VB6/VAB两种语言的开发。
2.1 三种访问WPS的方式2.2 使用C++向导实现插件开发(V9.1.0.4468)
目前该种方法只在版本号为V9.1.0.4468中调试成功。
下载该向导:
http://bbs.wps.cn/forum.php?mod=viewthread&tid=22410767&extra=page%3D1%26filter%3Dtypeid%26typeid%3D151%26typeid%3D151
然后解压缩该文档,按照setup_vs2008.js,显示安装成功及代表插件开发向导按照成功。
打开vs2008-新建工程,即可以看到WPS Office插件开发模板。
在OnConnection函数中添加插件功能。
2.2.1 关键代码功能实现部分,test.h文件。
#pragma once
class __declspec(uuid("{D31D0AB3-B6A5-4FA7-A0C0-179DB9FBFF72}")) test;
_declspec(selectany) _ATL_FUNC_INFO OnClickButtonInfo =
{
CC_STDCALL,
VT_EMPTY,
2,
{ VT_DISPATCH, VT_BYREF | VT_BOOL }
};
using namespace AddInDesignerObjects;
class test :
public CComObjectRootEx,
public CComCoClass,
public IDispatchImpl,
public IDispEventSimpleImpl,
public IDispEventSimpleImpl,
public IDispEventSimpleImpl,
public IDispEventSimpleImpl,
public IDispEventSimpleImpl,
public IDispEventSimpleImpl,
public IDispEventSimpleImpl
{
private:
WPS::_ApplicationPtr m_spWPSApp;
_CommandBarButtonPtr m_spButton1;
_CommandBarButtonPtr m_spButton2;
_CommandBarButtonPtr m_spButton3;
_CommandBarButtonPtr m_spButton4;
_CommandBarButtonPtr m_spButton5;
_CommandBarButtonPtr m_spButton6;
_CommandBarButtonPtr m_spButton7;
public:
DECLARE_REGISTRY_RESOURCEID(IDR_WPSCOMADDONS)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(test)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(_IDTExtensibility2)
END_COM_MAP()
BEGIN_SINK_MAP(test)
SINK_ENTRY_INFO(1, DIID__CommandBarButtonEvents, 0x01, OnClickButton1, &OnClickButtonInfo)
SINK_ENTRY_INFO(2, DIID__CommandBarButtonEvents, 0x01, OnClickButton2, &OnClickButtonInfo)
SINK_ENTRY_INFO(3, DIID__CommandBarButtonEvents, 0x01, OnClickButton3, &OnClickButtonInfo)
SINK_ENTRY_INFO(4, DIID__CommandBarButtonEvents, 0x01, OnClickButton4, &OnClickButtonInfo)
SINK_ENTRY_INFO(5, DIID__CommandBarButtonEvents, 0x01, OnClickButton5, &OnClickButtonInfo)
SINK_ENTRY_INFO(6, DIID__CommandBarButtonEvents, 0x01, OnClickButton6, &OnClickButtonInfo)
SINK_ENTRY_INFO(7, DIID__CommandBarButtonEvents, 0x01, OnClickButton7, &OnClickButtonInfo)
//SINK_ENTRY_INFO(3, __uuidof(ET::_ApplicationEvents),0x113005, SheetActivate, &SheetActivateInfo)
END_SINK_MAP()
typedef IDispEventSimpleImpl CommandBarButtonEvents1;
typedef IDispEventSimpleImpl CommandBarButtonEvents2;
typedef IDispEventSimpleImpl CommandBarButtonEvents3;
typedef IDispEventSimpleImpl CommandBarButtonEvents4;
typedef IDispEventSimpleImpl CommandBarButtonEvents5;
typedef IDispEventSimpleImpl CommandBarButtonEvents6;
typedef IDispEventSimpleImpl CommandBarButtonEvents7;
test()
{
}
~test()
{
}
public:
STDMETHOD(OnConnection)(IDispatch * Application,
ext_ConnectMode ConnectMode, IDispatch * AddInInst, SAFEARRAY * * custom)
{
try
{
m_spWPSApp = Application;
_CommandBarsPtr spCommandBars = m_spWPSApp->CommandBars;
CommandBarPtr spCommandBar = spCommandBars->Add("MOKA工具条",1 ,"",TRUE);
CommandBarControlsPtr ETCtrls =spCommandBar ->Controls;
KSO::CommandBarControlPtr popupButton1=ETCtrls->Add(1,"","",TRUE);
popupButton1->Caption = _bstr_t(L"显示标注");
KSO::CommandBarControlPtr popupButton2=ETCtrls->Add(1,"","",TRUE);
popupButton2->Caption = _bstr_t(L"隐藏标注");
KSO::CommandBarControlPtr popupButton3=ETCtrls->Add(1,"","",TRUE);
popupButton3->Caption = _bstr_t(L"打开文件");
KSO::CommandBarControlPtr popupButton4=ETCtrls->Add(1,"","",TRUE);
popupButton4->Caption = _bstr_t(L"附件对象");
KSO::CommandBarControlPtr popupButton5=ETCtrls->Add(1,"","",TRUE);
popupButton5->Caption = _bstr_t(L"保存文件");
KSO::CommandBarControlPtr popupButton6=ETCtrls->Add(1,"","",TRUE);
popupButton6->Caption = _bstr_t(L"退出应用");
//KSO::CommandBarControlPtr popupButton7=ETCtrls->Add(1,"","",TRUE);
//popupButton7->Caption = _bstr_t(L"文档模板");
CommandBarButtonEvents1::DispEventAdvise(popupButton1);
CommandBarButtonEvents2::DispEventAdvise(popupButton2);
CommandBarButtonEvents3::DispEventAdvise(popupButton3);
CommandBarButtonEvents4::DispEventAdvise(popupButton4);
CommandBarButtonEvents5::DispEventAdvise(popupButton5);
CommandBarButtonEvents6::DispEventAdvise(popupButton6);
//CommandBarButtonEvents7::DispEventAdvise(popupButton7);
}
catch(const _com_error&)
{
}
return S_OK;
}
STDMETHOD(OnDisconnection)(ext_DisconnectMode RemoveMode, SAFEARRAY * * custom)
{
return S_OK;
}
STDMETHOD(OnAddInsUpdate)(SAFEARRAY * * custom)
{
return S_OK;
}
STDMETHOD(OnStartupComplete)(SAFEARRAY * * custom)
{
return S_OK;
}
STDMETHOD(OnBeginShutdown)(SAFEARRAY * * custom)
{
return S_OK;
}
//隐藏标注
void __stdcall OnClickButton1(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
m_spWPSApp->ActiveWindow->View->ShowRevisionsAndComments = true;
}
catch (const _com_error& )
{
}
return;
}
//
void __stdcall OnClickButton2(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
m_spWPSApp->ActiveWindow->View->ShowRevisionsAndComments = false;
}
catch (const _com_error& )
{
}
return;
}
//打开文件
void __stdcall OnClickButton3(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
//m_spWPSApp->Selection->InsertFile("D:/win.txt",&vtMissing,&vtMissing,&vtMissing,&vtMissing);
// 引入文件
// WPS::WpsDialog aa = WPS::WpsDialog::wpsDialogInsertFile;
WPS::WpsDialog aa = WPS::WpsDialog::wpsDialogOpenFile;
m_spWPSApp->Dialogs->Item(aa)->Show();
}
catch (const _com_error& )
{
}
return;
}
//附加对象
void __stdcall OnClickButton4(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
// WPS::ShapeNodePtr pp = m_spWPSApp->ActiveDocument->Shapes->AddShape(ksoShapeActionButtonMovie, 100, 100, 200, 200,&vtMissing);
//m_spWPSApp->ActiveDocument->InlineShapes->AddOLEControl();
WPS::WpsDialog aa = WPS::WpsDialog::wpsDialogInsertOLEObject;
m_spWPSApp->Dialogs->Item(aa)->Execute();
}
catch (const _com_error& )
{
}
return;
}
//保存所有的文档
void __stdcall OnClickButton5(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
// m_spWPSApp->ActiveDocument->Save();
m_spWPSApp->CommandBars->Item[L"TabMenu Popup Menu"]->Controls->Item[L"保存所有文档(&E)"]->Execute();
}
catch (const _com_error& )
{
}
return;
}
//退出所有的文档并且一一询问是否需要保存修改过的文档,最后关闭应用
void __stdcall OnClickButton6(
IDispatch* pCtrl,
VARIANT_BOOL* pbCancelDefault)
{
try
{
// m_spWPSApp->Documents->Close();
_variant_t tt=WPS::wpsPromptToSaveChanges;
m_spWPSApp->Quit(&tt,&vtMissing,&vtMissing);
}
catch (const _com_error& )
{
}
return;
}
};
程序运行后会直接调用本地安装WPS2013(V9.1.0.4468),该插件在开发工具-COM加载项中显示,并可以勾选决定是否加载该插件。
2.2.2 C++获取WPS的一级和二级控件ofstream outfile("d://b.txt");
if(!outfile){
cout Count;
CString strSql = (LPCSTR)bstr;
int b=_ttoi(strSql);
int a=0;
for(int a=1;a
CommandBars->Item[a]->Name;outfile
Caption;outfile
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?