作者:陈希章 发表于2017年7月13日

Talk is cheap, show me the code”,我们就用代码来说话吧。这一篇将给大家介绍如何开始Office Add-in的奇妙开发之旅。

上一篇文章已经提到过了,要进行Office Add-in的开发,你可以选择自己最喜欢的Web开发平台和工具。限于经验和精力,我这里展示的是用微软提供的Visual Studio系列工具进行开发。

Visual Studio这个宇宙第一的IDE伴随着我从对编程一无所知到靠编写代码为生,从入门到一直没有放弃。与此同时,Visual Studio 2005开始提供了对Office Add-in开发的内置支持。

当时的技术叫做VSTO——Visual Studio Tools for Office,其内在的机制是用托管代码封装了Office 的COM对象模型,我们在Visual Studio中编写C#或者VB.NET的代码,最终会编译成一个dll,打包成一个vsto的文件,部署到计算机的特定目录后,相应的Office客户端在启动的时候,就会加载这些vsto文件中定义好的add-in,并且执行其中的代码,或是自动执行某些功能(或者监听某个事件进行响应),或是在Ribbon中添加一些按钮,等待用户点击后执行某些操作。

每一代的Visual Studio都有对应的Office Add-in开发的更新。在最近的几个版本中,除了继续支持VSTO外,也一直提供了对于新一代Web Add-in的支持。

使用Visual Studio开发Office Add-in非常高效,因为有标准的项目模板,有向导式的工具,并且直接就支持一键式进行调试。我们下面就来体验一下吧。


由于不同的Office 客户端对于Add-in支持的功能会略有差异,所以基于你所选择的项目模板,你看到的向导界面可能也会略有不同

点击“Finish”按钮后,你应该会看到一个类似下面的项目结构

最左边的是manifest文件,中间是Web应用程序的首页 —— home.html,这两个部分是通过在manifest文件中的如下内容来是进行关联的

<DefaultSettings>
<SourceLocation DefaultValue="~remoteAppUrl/Home.html" />
</DefaultSettings>

你一定会对~remoteAppUrl感到好奇,这是一个什么地址呢?这只是一个占位符,后续真正在调试或者部署的时候会替换成真正的地址。

关于manifest文件的具体规范,以及Web应用程序开发的细节,我还会在后续专门来写。现在就让我们不做任何的修改,直接运行起来看看效果吧。对,就是按F5键。

这个Add-in会在“Home”这个Tab里面增加一个Add-in Command—— “Show TaskPane”,点击这个按钮后,会在工作表的右侧出现一个任务面板,并且与此同时已经插入了一些范例数据到工作表上面。如果我们选中这些数据,同时在任务面板中点击“Highlight”的话,它会把这些数字中的最大值找出来,并且用颜色进行高亮显示。

那么到底发生了什么呢?以上面这个范例项目为例,在你按下F5键的时候,Visual Studio其实做了如下一系列的事情

  1. 编译和生成 ExcelWebAddin4Web这个项目,并且在本地用IIS Express将其运行起来,在我的电脑上,它会在下面的地址运行 https://localhost:44379/,这是在项目属性中指定的。

  1. 编译和生成 ExcelWebAddin4这个项目,并且用上面这个地址,替换到manifest文件中 ~remoteAppUrl。

与此同时,它会生成一个Book1.xlsx的文件用来做测试

  1. Visual Studio启动Excel,加载Book1.xlsx,并且用开发模式,加载上面这个manifest文件,进而言之就是加载我们这个Web Addin

为什么我们会在“Home”这个Tab中看到那个自定义的按钮,是因为在Manifest文件中定义了如下的信息

<ExtensionPoint xsi:type="PrimaryCommandSurface">
<!-- Use OfficeTab to extend an existing Tab. Use CustomTab to create a new tab. -->
<OfficeTab id="TabHome">
<!-- Ensure you provide a unique id for the group. Recommendation for any IDs is to namespace using your company name. -->
<Group id="Contoso.Group1">
<!-- Label for your group. resid must point to a ShortString resource. -->
<Label resid="Contoso.Group1Label" />
<!-- Icons. Required sizes 16,32,80, optional 20, 24, 40, 48, 64. Strongly recommended to provide all sizes for great UX. -->
<!-- Use PNG icons. All URLs on the resources section must use HTTPS. -->
<Icon>
<bt:Image size="16" resid="Contoso.tpicon_16x16" />
<bt:Image size="32" resid="Contoso.tpicon_32x32" />
<bt:Image size="80" resid="Contoso.tpicon_80x80" />
</Icon> <!-- Control. It can be of type "Button" or "Menu". -->
<Control xsi:type="Button" id="Contoso.TaskpaneButton">
<Label resid="Contoso.TaskpaneButton.Label" />
<Supertip>
<!-- ToolTip title. resid must point to a ShortString resource. -->
<Title resid="Contoso.TaskpaneButton.Label" />
<!-- ToolTip description. resid must point to a LongString resource. -->
<Description resid="Contoso.TaskpaneButton.Tooltip" />
</Supertip>
<Icon>
<bt:Image size="16" resid="Contoso.tpicon_16x16" />
<bt:Image size="32" resid="Contoso.tpicon_32x32" />
<bt:Image size="80" resid="Contoso.tpicon_80x80" />
</Icon> <!-- This is what happens when the command is triggered (E.g. click on the Ribbon). Supported actions are ExecuteFunction or ShowTaskpane. -->
<Action xsi:type="ShowTaskpane">
<TaskpaneId>ButtonId1</TaskpaneId>
<!-- Provide a URL resource id for the location that will be displayed on the task pane. -->
<SourceLocation resid="Contoso.Taskpane.Url" />
</Action>
</Control>
</Group>
</OfficeTab>
</ExtensionPoint>

事实上,点击按钮就是显示出来那个TaskPane(任务面板)而已,唯一做了设置的就是指定了这个面板默认打开的Url地址. 这是通过在Resources中设定的。

<Resources>
<bt:Images>
<bt:Image id="Contoso.tpicon_16x16" DefaultValue="~remoteAppUrl/Images/Button16x16.png" />
<bt:Image id="Contoso.tpicon_32x32" DefaultValue="~remoteAppUrl/Images/Button32x32.png" />
<bt:Image id="Contoso.tpicon_80x80" DefaultValue="~remoteAppUrl/Images/Button80x80.png" />
</bt:Images>
<bt:Urls>
<bt:Url id="Contoso.DesktopFunctionFile.Url" DefaultValue="~remoteAppUrl/Functions/FunctionFile.html" />
<bt:Url id="Contoso.Taskpane.Url" DefaultValue="~remoteAppUrl/Home.html" />
<bt:Url id="Contoso.GetStarted.LearnMoreUrl" DefaultValue="https://go.microsoft.com/fwlink/?LinkId=276812" />
</bt:Urls>
<!-- ShortStrings max characters==125. -->
<bt:ShortStrings>
<bt:String id="Contoso.TaskpaneButton.Label" DefaultValue="Show Taskpane" />
<bt:String id="Contoso.Group1Label" DefaultValue="Commands Group" />
<bt:String id="Contoso.GetStarted.Title" DefaultValue="Get started with your sample add-in!" />
</bt:ShortStrings>
<!-- LongStrings max characters==250. -->
<bt:LongStrings>
<bt:String id="Contoso.TaskpaneButton.Tooltip" DefaultValue="Click to Show a Taskpane" />
<bt:String id="Contoso.GetStarted.Description" DefaultValue="Your sample add-in loaded succesfully. Go to the HOME tab and click the 'Show Taskpane' button to get started." />
</bt:LongStrings>
</Resources>

也就是说,任务面板会默认加载Web应用程序的Home.html页面,而如果你打开这个文件,你会发现除了一些简单的布局设计之外,其核心部分的逻辑是写在了一个Home.js文件中的。这个js文件的核心代码是下面这一段,它做了一些基本的判断,然后加载了范例数据(loadSampleData),并且为页面上的一个编号为highlight-button的按钮绑定了一个事件(highlightHighestValue)。

Office.initialize = function (reason) {
$(document).ready(function () {
// Initialize the FabricUI notification mechanism and hide it
var element = document.querySelector('.ms-MessageBanner');
messageBanner = new fabric.MessageBanner(element);
messageBanner.hideBanner(); // If not using Excel 2016, use fallback logic.
if (!Office.context.requirements.isSetSupported('ExcelApi', '1.1')) {
$("#template-description").text("This sample will display the value of the cells that you have selected in the spreadsheet.");
$('#button-text').text("Display!");
$('#button-desc').text("Display the selection"); $('#highlight-button').click(displaySelectedCells);
return;
} $("#template-description").text("This sample highlights the highest value from the cells you have selected in the spreadsheet.");
$('#button-text').text("Highlight!");
$('#button-desc').text("Highlights the largest number."); loadSampleData(); // Add a click event handler for the highlight button.
$('#highlight-button').click(hightlightHighestValue);
});
};

在Visual Studio 中开发Office Add-in的更多相关文章

  1. Visual Studio 中的 Office 和 SharePoint 开发

    MSDN Library 开发工具和语言  Visual Studio 中的 Office 和 SharePoint 开发 https://msdn.microsoft.com/zh-cn/libra ...

  2. Visual Studio中开发

    如何在Visual Studio中开发自己的代码生成器插件    Visual Studio是美国微软公司开发的一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代 ...

  3. 使用Xamarin在Visual Studio中开发Android应用

    原文:使用Xamarin在Visual Studio中开发Android应用 本文使用的环境是Windows 8 Visual Studio 2012.2 1.下载Xamarin http://xam ...

  4. 如何在Visual Studio中开发自己的代码生成器插件

     Visual Studio是美国微软公司开发的一个基本完整的开发工具集,它包括了整个软件生命周期中所需要的大部分工具,如UML工具.代码管控工具.集成开发环境(IDE)等等,且所写的目标代码适用于微 ...

  5. CMake结合Visual Studio中开发Qt应用程序注意事项

    Qt工程管理 个人比较偏爱于使用CMake来管理C++工程,因为只要编写一个CMakeLists.txt文件,就可以在Windows和Mac上生成各自的IDE工程.在Windows上, CMake自然 ...

  6. 在Visual Studio中开发Matlab mex文件,生成mexw64/mexw32

    csunking贡献,2015-9-22 1712 1.   概述 通过使用C/C++与Matlab混合编程,既可以享受到C代码快速执行的速度,又可以方便的使用Matlab众多的库函数和强大的绘图功能 ...

  7. 在Visual Studio中开发一个C语言程序

    →新建一个项目→选择"其他语言","Visual C++",并选择"win32控制台应用程序",并给控制台应用程序起名.→点击"下 ...

  8. 在Visual Studio 中开发自定义脚手架 Scaffolder

    1.官方简单教程 http://blogs.msdn.com/b/webdev/archive/2014/04/03/creating-a-custom-scaffolder-for-visual-s ...

  9. 在Visual Studio Code中开发Office Add-in

    作者:陈希章 发表于 2017年7月13日 上一篇 我介绍了如何在Visual Studio中开发Office Add-in,因为有标准的项目模板,一系列配套的工具,尤其是自带的一键调试功能,可以让开 ...

随机推荐

  1. Django总结

    Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,通过减少重复的代码,Django 使你能够专注于 web 应用上有 趣的关键性的东西.为了达到这个目标,Django 提供了通用W ...

  2. 关于 innodb_stats_on_metadata 的设置问题

    [问题背景] 线上使用osc进行表修改的时候出现SQL执行过长被kill的问题

  3. 程序、计算机程序、java初论

    一.程序? 程序一词来自生活,通常指完成某些事情的一种既定方式和过程,可以将程序看成对一系列动作的执行过程的描述. 例如:个人去银行取钱 1.带上存折/银行卡去银行 2.取号排队 3.将存折或储蓄卡递 ...

  4. set 利用lower_bound实现key索引

    set中数据类型为结构体T,T中有两个成员key和val定义如下: struct T{ int key,val; T(int k,int v):key(k),val(v){} bool operato ...

  5. Chapter 8: Exceptional Control Flow

    概述: 我们可以用一种“流”的概念来理解处理器的工作流程,PC(Program Counter)依次为a0,a1,a2,...,an-1,这个序列可以称作control flow.当然我们并不总是按顺 ...

  6. python学习笔记 loop&&raw_input 7&& if

    1.首先要说range(x) 其返回的是一个list:[0,1,2,....x-1] >>> range(5) [0,1,2,3,4] 2.Loop 共有两种形式,一种for x i ...

  7. HTML基础下

    知识点一: HTML5的标准结构: <!DOCTYPE html> <html lang='en'> <head> <meat charset='utf-8' ...

  8. 运行java web项目时报错:Several ports (8005, 8080, 8009) required

    运行java web项目时报错:Several ports (8005, 8080, 8009) required 如下图 之所以报上面的错误是因为安装Tomcat的时候,已经把端口8005,8080 ...

  9. ip地址与整数相互转换

    一.将ip地址转成long数值 将IP地址转化成整数的方法如下: 1.通过String的split方法按.分隔得到4个长度的数组 2.通过左移位操作(<<)给每一段的数字加权,第一段的权为 ...

  10. ES 入门之一 安装ElasticSearcha

    安装ElasticSearcha 学习ES也有快一个月了,但是学习的时候一直没有总结.以前没有总结是因为感觉不会的很多,现在对ES有一点了解了.索性就从头从安装到使用ES做一个详细的总结,也分享给其他 ...