打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
专家帖丨开发一个全功能的 Word Add-in

▶ 作者简介



2016 年 10 月我参加了在北京举行的 DevDays Asia 2016 - Office 365 应用开发 “48 小时黑客马拉松 ”,我开发的一个 Word Add-in Demo —— WordTemplateHelper 获得了二等奖。在会场有幸结识了陈希章老师,在与陈老师的交流中受益良多,得知陈老师在准备一个 Office 解决方案系列后,我想把这个 Demo 的开发过程简要介绍给大家,以支持陈老师的无私奉献,也希望更多的开发者参与到 Office 365 的开发中来。


Office 相关开发主要可以参考这个地址:https://dev.office.com/getting-started


本篇文章主要介绍其中的 Office 加载项开发,即 Office Add-ins:https://msdn.microsoft.com/ZH-CN/library/office/jj220082.aspx


注意文中网址均不支持点击跳转,请单击文末 阅读原文 以更好地查看相关代码。



▶ 一、什么是 Office Add-ins


什么是 Office Add-ins 呢?在陈老师这两篇文章中:


Office 365 开发概述及生态环境介绍(一)

Office 365 开发概述及生态环境介绍(二)


已经对整个 Office 发展历史都进行了梳理。我个人的理解是,开发者可以在 Office 提供的平台上,对 Office 做出一定的扩展以实现各种功能,比如之前录制的宏,写的 VBS 的脚本,某种意义上都可以看做是 Office 的 Add-ins。当然这只是个人理解,不一定准确。目前的 Office Add-ins 只支持 Office 2013 以后的版本,开发方式也和以前的 VBS 有了很大的区别。


现在的 Office Add-ins 结构是这样的:



一个 Office Add-in 其实是一个 Web App,可以将其部署在任意位置,它可以在一个 Office 应用程序中运行。有一个 manifest.xml 清单文件用来指定该 Web App 如何来呈现,包括定义 Web App 的 URL。当 Office 加载这个 Add-in 时,实际上是提供了一个浏览器的环境,来运行指定的 Web App。也就是说,现在开发一个 Office Add-in,其实跟开发网页程序差不多,这对熟悉 html JavaScript css 的前端开发人员是非常容易上手的。微软提供了丰富的 JavaScript API 来对 Office 进行操作,能实现什么就取决于开发者的想象力了。


一个 Word Add-in 的实例:




▶ 二、Word Template Helper 需求分析


我在得知有这个活动时,并没有想好要做什么。一直到坐上赴京的高铁,才慢慢有了一个想法,这个想法也是来自平时的工作需要。在工作中经常要撰写大量的文档,如各种软件需求规格说明书、公函、文书、操作手册等,这些文档都有规定的格式。一般情况下我是将一些已经写好的 Word 文档保存在一个文件夹里当做模板,下次写这种文档的时候复制一份,删删减减的再改。为何不自己写个程序,将这些具有固定模式的文档作为 Word 模板呢?虽然 Word 也有自己的模板,但实际上是非常有限的,并不能完全满足我们的需要。如果这个功能做成一个模板商店,大家可以自由上传、分享各自的模板,也许会方便许多。


Word 自带的模板是这样的:



这些通用模板对专业性比较强的工作来说是远远不够的。Word Template Helper 的效果是这样的:



主意有了,那么就来看一下如何实现。我参加活动时的项目托管在码云上,为了写这篇文章我重新梳理了这个小 demo,在 Github 上建了一个项目,并尝试使用最新的. NET Core 来实现后台 API 部分。接下来就跟我一起动手吧。



▶ 三、项目架构


首先分析一下该项目的结构。文档的模板数据,如模板标题、属性等,需要保存在数据库里,还需要一个 Web API 项目提供数据,Office Add-in 为一个纯前端项目,使用 Angular2 框架,采用异步调用 Web API 的数据,实现搜索、加载模板等功能。插件的 UI 使用微软提供的 Fabric UI。整个项目的技术栈如下所示:



至于文档的实体 —— Word 文档,是以 Word 格式文件存储还是直接保存在数据库中呢?如果是正式项目的话,当然是保存在云存储中是最合适的,但对于一个 sample 来说,直接保存在数据库中也未尝不可。因为是参加开发马拉松,怎么快怎么来吧。包括 ORM 框架也是,只是为了快速实现采用的方式,不是最佳实践。


这个 Sample 的开发环境配置如下:


Windows 10 x64,

VS 2017(请确保安装了 Office 开发工具)

VS Code

Node.js v7.10.0

NPM v4.2.0

ASP.NET Core 1.1

 


▶ 四、Web API 开发


VS2017 已经正式发布了,我使用最新的. NET Core 来实现 Web API 层。


1. 新建项目


新建一个空白解决方案,命名为 WordTemplateHelpe,然后在其中添加一个 ASP.NET Core 项目:



选择 Web API:



2. 安装 EF Core


在 Nuget 管理器中搜索安装一下几个 Nuget 包:

Microsoft.EntityFrameworkCore.SqlServer:EF Core SQL Server

Microsoft.EntityFrameworkCore.Tools:EF 命令行工具

Microsoft.EntityFrameworkCore.Tools.DotNet:EF Core 命令行工具



3. 建立 Models


目前最新的 EF 都推荐使用 Code First 模式,即直接写 Model,EF 框架会自动创建所需的数据库。如果习惯 DB First 的话,也有一个很好的工具推荐:EntityFramework-Reverse-POCO-Code-First-Generator:https://visualstudiogallery.msdn.microsoft.com/ee4fcff9-0c4c-4179-afd9-7a2fb90f5838

 

可以直接在 VS 的扩展与更新里下载。这个工具可以很方便的根据数据库生成所需的实体类。


首先添加一个模板类型的枚举:




添加一个模板类:




因为还需要组织机构模板、用户收藏等几个表,这里就不写了,可参考 Github 上的示例。


4. 创建数据库上下文


有了 Model 后,需要指定哪些实体包含在数据模型中。添加一个 Data 文件夹,在其中创建一个名为 WordTemplateContext.cs 的文件:



这样就为每个实体创建了一个 DbSet,对应数据库中的表,实体对应表中的行。

 

5. 使用依赖注入注册上下文


ASP.NET Core 默认实现了依赖注入。要把刚才建立的 WordTemplateContext 注册成服务,需要在 Startup.cs 中添加以下代码:



注意要添加 using Microsoft.EntityFrameworkCore; 不然会找不到 UseSqlServer 方法。


数据库连接字符串在 appsettings.json 中配置:



这里使用了 LocalDb,用于测试。当需要正式部署时,这里需要更改为正式数据库服务器的地址及用户名密码。


6. 初始化数据库


下面使用命令行初始化数据库。在 Data 目录下新建一个 DbInitializer 类,输入以下方法:



确保数据被创建。然后修改 Startup.cs 文件中的 Configure 方法:



7. 创建 API 接口


现在写个 Controller 看看。在 Controller 文件夹中添加一个控制器:



这里可以使用依赖注入,将数据库上下文注入进来:



我们以一个搜索模板的 API 为例:



命令行转到项目目录,运行以下命令


dotnet run

 

可以使用前端调试利器 Postman 来测试:




API 项目运行的具体地址需要记一下,后面做 Add-in 的时候要用到。具体代码请参考 Github。


8. 允许跨域访问


为了支持 Add-in 能够跨域访问我们的接口,还需要安装以下的库:



然后在 Startup.cs 的 ConfigureServices 方法中添加以下代码:



在需要跨域的 WordTemplateController 上添加一行:


[EnableCors('AllowCrossDomain ')]

 

这样 API 就可以支持跨域访问了。



▶ 五、Word Add-in 开发


有了 API,就可以开发 Add-in 部分了。开篇说到,Add-in 实际上是一个 Web App,通过 JavaScript 操作 Office 文档对象,具体到这个项目来说,就是使用异步的 js 去查询、上传、搜索存在服务器上的模板文件,并动态的对当前 Word 文档进行操作。


微软在 Github 上开源了这个 JavaScript API:https://github.com/Microsoft/Office-js-docs_zh-cn,相关文档:https://msdn.microsoft.com/zh-cn/library/office/fp142185.aspx


开发步骤可参考:https://github.com/OfficeDev/Office-js-docs_zh-cn/blob/staging/docs/get-started/create-and-debug-office-add-ins-in-visual-studio.md


下面来开发 Add-in 部分。


1. 新建 Add-in 项目


在解决方案上点击右键,添加一个 Word Web 外接程序:



添加完成后,多了两个项目:




其中一个是清单文件,带 Web 后缀的就是 Web App 了。


2. 设置 manifest.xml


清单文件是非常重要的一个文件,描述加载项的所有设置。这个文件是自动生成的,但需要我们手动修改一些地方。好在文件中都有注释,所以修改还比较容易:




最重要的是修改 SourceLocation 这个节点,这个地址设置的是 Web App 托管的位置。在 Web 端开发并部署后,要将这个节点改为正确的位置才能发布。下面这个节点也要改掉。




3.Web App 分析


可以先运行一下这个模板试试,直接 F5:



点击此处就可以调出这个插件:


 

会自动打开 Word 并加载这个插件,文档中的文本就是插件插入的。那么是哪里的代码起作用的呢?


打开 Home.js 文件,找到如下代码:



这里的 Word 就是 JavaScript API 提供的对象,可以方便的对当前文档内容进行操作。这样思路就有了,可以通过 JavaScript 动态去调用 Web API 获取查询结果,将查询到的文档内容插入到当前文档中,就实现了最初的目的。同时还可以将当前文档的内容保存为模板上传到服务器上进行分享,一个完整功能的 sample 已经呼之欲出了。


4. 使用 Angular

我们使用最新的 Angular4 来开发前端页面。当然如果使用 JQuery 的话也可以,但现在已经有点 out 了不是吗?使用 Angular 可以快速开发一个 MVVM 架构的单页面 WebApp,非常适合这个需求。

这个 demo 的部分代码参考微软开源的一个项目:https://github.com/OfficeDev/Office-Add-in-UX-Design-Patterns-Code

Angular 上手曲线还是有点陡的,官方给出了 Angular CLI 工具,可以快速搭建一个 Angular 应用。首先安装 TypeScript:


npm install -g typescript

 

然后安装 Angular CLI:https://github.com/angular/angular-cli


npm install -g @angular/cli

 

运行以下命令创建一个 Angular 项目:


ng new WordTemplateHelperSource



然后使用 cd WordTemplateHelperSource 命令转到项目目录,运行以下命令:


npm install

 

这个命令会安装 ng 项目所需的依赖,如果安装不成功,建议切换成淘宝 npm 镜像进行安装。

使用以下命令运行 ng 项目:


ng serve

 

可以在 Chrome 浏览器中浏览 http://localhost:4200 来查看效果:



注意如果在 IE 中浏览是不正常的,这个问题我们到最后一节再给出解决办法。

为什么不直接在 WordTemplateHelperWeb 建呢?因为 Angular 应用还要进行打包,会在项目目录下生成 dist 目录,这才是正式要运行的部分。所以等开发完成后,将生成的 dist 目录内的文件拷到 WordTemplateHelperWeb 就可以了。


在开发 Angular 的过程中,推荐使用 VS Code,对 TypeScript 和 Angular 的支持都非常好。


因为本篇文章不是 Angular 的开发教程,所以 Angular 的具体知识这里就不展开详述了,感兴趣的话可以自行下载 Github 代码运行即可。


5. 添加操作 Word 文件的 service

为了操作 Word 文件,我们需要将其封装成服务。使用以下命令添加一个 service:


ng g service services\word-document\WordDocument

 

这样会在 app 目录中的相应路径中生成一个名为 WordDocumentService 的服务。与此类似,生成其他的几个 service。其中主要的几个方法如下:


查询搜索的方法:



这样可以得到服务器上存储的文档模板,实际是以 Ooxml 格式保存的 string。


对于这个 sample 来说,使用 Office JavaScript API 并没有太难的东西,主要用到了两个方法:getOoxml() 和 insertOoxml(),前者可以读取当前 word 文档的 Ooxml 格式,后者可以设置当前 word 文档的 Ooxml 格式。Ooxml 就是 Office2007 之后版本使用的格式,如 docx 这种。


原 API 提供的都是 callback 函数,为了使用方便我将其封装成 Promise:




当搜索到合适的模板后,可以单击按钮,调用 setOoxml() 方法,将其插入到当前 Word 文档中:


applyTemplate(template: WordTemplateInfo) {    this.wordDocument.setOoxml(template.TemplateContent);  }

 

这样就完成了应用模板的功能。

 

如果要实现将当前文档的内容保存为模板上传到服务器上,就可以调用 getOoxml() 方法得到当前文档的 Ooxml 格式文本,上传到服务器保存即可。至于其他的加为收藏、添加为机构模板、设置为个人模板等都是设置模板属性更新了,具体代码不再赘述。

还有一点需要注意的是,开发的时候,这里的服务器地址要写刚才我们开发的 ASP.NET Core 的地址。


6. 使用 Fabric UI

对于一个 Office Add-in 来说,具有简洁美观、与 Office 统一的 UI 是必须的。微软推荐使用 Fabric UI 来实现统一的界面样式,详见:https://dev.office.com/fabric


这里提供了样式、图标、设计规范等很多资源,甚至还提供了 React 版的组件,如果使用 React 开发的话直接拿来用就可以了。这个 demo 是直接引用的 style 文件,配置在. angular-cli.json 文件中:



应用后就变成这样子:



7. 打包 Add-in


刚才只是在一个新项目里开发了一个静态 Web App,还要将其打包,复制到 WordTemplateHelperWeb 项目中。使用 ng build –prod 来打包 Angular 应用。打包后的文件会输出到 dist 目录下:



注意还有一个需要注意的地方,如果仅这样打包的话,是不支持 IE 浏览器的,但 Office Add-In 实际上内置的浏览器就是 IE 内核,所以我们需要做如下修改,找到 src 目录中的 polyfills.ts 文件,将下面部分的注释取消:



还要根据提示,运行 npm install 命令安装几个必须的依赖。这样才能在 IE 系列浏览器中正常运行。再次运行 ng build –prod 进行打包。--prod 参数的意义是以生产模式进行 build,这样生成的代码体积更小,运行速度更快。


将 WordTemplateHelperWeb 项目中的原文件除了 Web.config 外,全部删除。把 dist 目录中的文件复制过来。


虽然本机开发时可以直接调试运行,但为了模拟真实的使用情况,我们把这个 Web App 也正式发布一下。如果我们有 Azure 或其他主机的话就直接部署到服务器上,现在只用本机 IIS 来承载这个 Web App:




这样该 Add-in 的地址就是:http://localhost/WordTemplateHelperWeb,

下面把 API 运行起来,进入 WordTemplateHelperApi 目录,运行 dotnet run 命令:



这样 API 项目的地址是:http://localhost:5000/api/


这两个地址不要混淆。刚才在打包 WebApp 的时候也要注意,在 common\app-global.ts 文件中的 API 地址也要改成和实际 API 地址一样的才可以:



现在打开 WordTemplateHelperManifest 清单文件,修改如下位置:



这里填的是 Add-in 的地址,一定不要搞错了。


6. 运行测试


现在可以重新运行 Add-in 项目了,将启动项目设置为 WordTemplateHelper,运行:



我们可以粘贴一个模板,并上传到服务器上:



点击 Upload 按钮即可将当前文档作为模板上传到服务器上分享。



搜索到相应的模板后,点击 apply 按钮即可将模板内容插入到当前文档。


我们可以搜索模板,添加自己的模板,并将模板内容应用到当前文档中。针对组织和个人还可以分别进行管理,我的设想是,这个小插件能够做成一个模板商店之类的平台,用户可以自由的交换彼此的文档模板,并可以收藏、添加到本人组织的模板库中等等。稍加扩展就可以做成一个正式产品了。


7. 载入加载动画


在页面加载时可以加一个载入提示,使用户体验更加友好。具体代码可参考 index.html 中的 css 样式。



▶ 六、小结


Office Add-in 是一个比较新的开发领域,跟以前的开发方式有所不同,但熟悉前端的同学可以迅速进入这个领域,实际上就是写网页。这个实例从后端接口到前台实现,是一个比较完整的项目,希望对 Office 开发有兴趣的同学下载代码研究一下,开发出更加实用的 Add-in。因为这个项目并没有实际部署,所以没有上传到商店中。下载代码的用户请勿用于商业用途。特此说明。



Office 365丨成就非凡力量

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
java生成复杂word文档的完美解决方案
word 宏的使用
强烈推荐10个让你事半功倍的Office办公资源
在Word2010中使用模板创建文档
在Word2007中使用模板创建文档
项目策划、会议记录、工作总结……去哪找合适的 Word 模板?
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服