本文主要是对我部署Office Web Apps Server 2013 及 Office Online Server 2016(下面都只提Office Online Server 2016) 过程的一个整理,包括遇到的一些问题的解决办法,其中引入到了前辈们的文章(比如域控服务器等已经有大神给出了很完美的教程,所以这些我只是替大家做了个收集工作)。
本文主要讲了部署Office Online Server 2016 的流程,以及一些问题的解决办法(主要是部署Office Web Apps Server 2013 时踩的坑),还有一些注意事项。
部署Office Online Server 2016 的流程如下:
1、干什么的?
先安装一个并配置AD用来作为域控服务器,再安装一个并安装Office Online Server 2016用来作为Word等文件的转换服务器
2、为什么是Windows Server 2012 R2 With Update?
因为
”我在安装的时候尝试过 windows server 2008、windows server 2012、windows server 2012 r2唯独 windows server 2012 r2 with update 没有出错,直接一次到位“,来自:https://blog.csdn.net/jiaqu2177/article/details/81945692
请参考文章
https://blog.csdn.net/jiaqu2177/article/details/81943615
https://www.cnblogs.com/lovechengcheng/p/4117391.html
1、干什么的?
安装Office Online Server 2016 的转换服务器必须部署在域服务器下,才能成功启动,所以建一个域控服务器来维护一个域,并将转换服务器加入到该域中来。
2、注意了!
域控服务器貌似只在转换服务器中的Office Online Server 2016 第一次初始化时起作用,也就是说等Office Online Server 2016正常运行了,你可以把域空服务器关闭,甚至重启转换服务器重启也不用理他(初步测试得出的结论,不一定准确)
请参考文章
https://blog.csdn.net/jiaqu2177/article/details/81945692
https://www.cnblogs.com/ldybyz/archive/2017/03/14/6547795.html
1、干什么的?
用来安装Office Online Server 2016,然后就不用我多说了吧
2、下载
这个东东真心不好下载,官网各种注册了一圈最后放弃了,幸亏从帝魂Dreams大神的文章:https://blog.csdn.net/jiaqu2177/article/details/81945692 中找到了资源,万幸啊,感谢!!!
请允许我给大家拷贝一份,以方便大家查看:
安装包
ed2k://|file|cn_office_online_server_may_2016_x64_dvd_8480704.iso|709687296|99014E02579B6E08E7172D05857F2D05|/
语言包
ed2k://|file|cn_office_online_server_language_pack_may_2016_x64_8783021.exe|122025248|3E8073A25EE45E0C106E34FA86CB006B
3、注意一
对于转换服务器,我看过另一篇文章,要在 【添加角色和功能】中各种操作的,但 帝魂Dreams 大神的文章中用一句代码搞定了
运行 powershell ,输入以下命令:
-Mgmt-Tools,Web-Mgmt-Console,Web-WebServer,Web-Common-Http,Web-Default-Doc,Web-Static-Content,Web-Performance,Web-Stat-Compression,Web-Dyn-Compression,Web-Security,Web-Filtering,Web-Windows-Auth,Web-App-Dev,Web-Net-Ext45,Web-Asp-Net45,Web-ISAPI-Ext,Web-ISAPI-Filter,Web-Includes,InkandHandwritingServices,Windows-Identity-Foundation,Server-Media-Foundation
4、注意二
安装微软提供的软件
Visual C++ Redistributable Packages for Visual Studio 2013
Visual C++ Redistributable for Visual Studio 2015
Microsoft.IdentityModel.Extention.dll
如果不安装,我试过在安装Office Online Server 2016 时肯定过不了,点击链接直接官方下载就可以
还是请参考文章
https://blog.csdn.net/jiaqu2177/article/details/81945692
https://www.cnblogs.com/ldybyz/archive/2017/03/14/6547795.html
1、干什么的?
其实我也不是很清楚,不过从用到的场景来说,应该是用于将 Office Online Server 2016 集成到我们自己的项目中的。
比如集成到我们的Springboot项目中时,你可以写个Rest风格的Controller,里面实现三个 WOPI REST 的接口,然后就可以通过Office Online Server 2016 的接口访问到我们自己项目里面的word等文件了,
比如你写了个Controller,三个接口分别为:
/**
* 获取文件信息
*/
@GetMapping("/files/{name}")
public void getFileInfo(HttpServletRequest request, HttpServletResponse response) {}
/**
* 获取文件流
*/
@GetMapping("files/{name}/contents")
public void getFile(@PathVariable String name, HttpServletResponse response) {}
/**
* 保存更新文件(就是当你在编辑docx等时Office Online Server 2016 将通过这个接口将编辑后的文件返给我们,我们再用其覆盖源文件,以达到编辑保存的目的)
*/
@PostMapping("files/{name}/contents")
public void postFile(@PathVariable(name = "name") String name, @RequestBody byte[] content) {}
2、WOPI REST接口文档 - CheckFileInfo属性参照
https://wopirest.readthedocs.io/en/latest/files/CheckFileInfo.html
https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-wopi/71e66fb4-144b-4369-b597-f425f0b700b9?redirectedfrom=MSDN
3、注意
这里WOPI REST接口 中用到的 CheckFileInfo 对象的属性加几个必要的就OK了, 加的多了有时倒还报错,很坑的;
注意了,属性首字母都是大写!!!
注意了,SHA256这个属性的赋值(获取该文件的文件流->SHA256计算文件流Hash值->将Hash值转换为Base64String)
4、我的WopiHostController(很重要)
package com.soybean.concise.modules.api.web;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.soybean.utils.StringUtils;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
/**
* OfficeOnlineServer的WOPI HOST
*
* zkh
* 2019年9月30日 10:09
*/
@RestController
@RequestMapping("api/wopi")
public class WopiHostController {
private String filePath = "F:\\mytemp\\";
private final String CHARSET = "UTF-8";
/**
* 获取文件信息
* zkh
* 2019年10月11日 10:33
*/
@RequestMapping("files/{name}")
public void getCheckFileInfo(HttpServletRequest request, HttpServletResponse response) {
FileInfo info = new FileInfo();
try {
String uri = request.getRequestURI();
// 获取文件名, 防止中文文件名乱码
String fileName = URLDecoder.decode(uri.substring(uri.indexOf("wopi/files/") + 11), CHARSET);
if (StringUtils.isNotBlank(fileName)) {
File file = new File(filePath + fileName);
if (file.exists()) {
info.setBaseFileName(file.getName());
info.setSize(file.length());
info.setOwnerId("admin");
info.setVersion(file.lastModified() + "");
// 获取该文件的文件流->SHA256计算文件流Hash值->将Hash值转换为Base64String
info.setSha256(Base64.encodeBase64String(DigestUtils.sha256(new FileInputStream(file))));
}
}
// 作用是使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据
response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
response.getWriter().write(new ObjectMapper().writeValueAsString(info));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取文件流
* zkh
* 2019年10月11日 10:34
*/
@GetMapping("files/{name}/contents")
public void getFile(@PathVariable String name, @PathVariable(name = "access_token") String access_token, HttpServletResponse response) {
// access_token getCheckFileInfo接口时传给OfficeWebApps的自定义参数,用于自定义权限检验
// 文件的路径
String path = filePath + name;
File file = new File(path);
try (InputStream fis = new BufferedInputStream(new FileInputStream(path)); OutputStream toClient = new BufferedOutputStream(response.getOutputStream())) {
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
// Response处理
response.reset();
response.addHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes(CHARSET), "ISO-8859-1"));
response.addHeader("Content-Length", String.valueOf(file.length()));
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
toClient.write(buffer);
toClient.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 保存修改文件
* zkh
* 2019年10月11日 10:36
*/
@PostMapping("files/{name}/contents")
public void saveFile(@PathVariable(name = "name") String name, @PathVariable(name = "access_token") String access_token, @RequestBody byte[] content) {
// access_token getCheckFileInfo接口时传给OfficeWebApps的自定义参数,用于自定义权限检验
File file = new File(filePath + name);
try (FileOutputStream fop = new FileOutputStream(file)) {
fop.write(content);
fop.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 文件属性对象
* 描述:由于wopi的接口不遵守驼峰命名规则,所以需要用@JsonProperty指定别名
*
* zkh
* 2019年10月12日 13:45
*/
class FileInfo implements Serializable {
/**
* 必须字段
*/
// 包含扩展的文件名
@JsonProperty("BaseFileName")
private String baseFileName;
// 文件大小(单位:byte)
@JsonProperty("Size")
private Long size;
// 唯一标识文件所有者
@JsonProperty("OwnerId")
private String ownerId;
// 文件版本号,文件如果被编辑,版本号也要跟着改变
@JsonProperty("Version")
private String version;
// SHA-2 256位散列编码值(获取该文件的文件流->SHA256计算文件流Hash值->将Hash值转换为Base64String)
@JsonProperty("SHA256")
private String sha256;
/**
* 编辑时可能用到的字段
*/
// 是否允许连接到文件中引用的外部服务(例如,可嵌入javascript应用程序)
@JsonProperty("AllowExternalMarketplace")
private boolean allowExternalMarketplace = true;
// 是否有权限修改
@JsonProperty("UserCanWrite")
private boolean userCanWrite = true;
// 是否支持更新
@JsonProperty("SupportsUpdate")
private boolean supportsUpdate = true;
// 是否支持锁定
@JsonProperty("SupportsLocks")
private boolean supportsLocks = true;
/**
* 其他字段
*/
// 是否支持使用WOPI客户端创建新文件
private boolean SupportsFileCreation = true;
// 是否支持用户可以通过受限制的URL以有限的方式对文件进行操作的方案
private boolean SupportsScenarioLinks = true;
public String getBaseFileName() {
return baseFileName;
}
public void setBaseFileName(String baseFileName) {
this.baseFileName = baseFileName;
}
public Long getSize() {
return size;
}
public void setSize(Long size) {
this.size = size;
}
public String getOwnerId() {
return ownerId;
}
public void setOwnerId(String ownerId) {
this.ownerId = ownerId;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSha256() {
return sha256;
}
public void setSha256(String sha256) {
this.sha256 = sha256;
}
public boolean isAllowExternalMarketplace() {
return allowExternalMarketplace;
}
public void setAllowExternalMarketplace(boolean allowExternalMarketplace) {
this.allowExternalMarketplace = allowExternalMarketplace;
}
public boolean isUserCanWrite() {
return userCanWrite;
}
public void setUserCanWrite(boolean userCanWrite) {
this.userCanWrite = userCanWrite;
}
public boolean isSupportsUpdate() {
return supportsUpdate;
}
public void setSupportsUpdate(boolean supportsUpdate) {
this.supportsUpdate = supportsUpdate;
}
public boolean isSupportsLocks() {
return supportsLocks;
}
public void setSupportsLocks(boolean supportsLocks) {
this.supportsLocks = supportsLocks;
}
public boolean isSupportsFileCreation() {
return SupportsFileCreation;
}
public void setSupportsFileCreation(boolean supportsFileCreation) {
SupportsFileCreation = supportsFileCreation;
}
public boolean isSupportsScenarioLinks() {
return SupportsScenarioLinks;
}
public void setSupportsScenarioLinks(boolean supportsScenarioLinks) {
SupportsScenarioLinks = supportsScenarioLinks;
}
}
}
1、在域服务器中登录(右键管理方式->输入账号/密码登录:zkh\Administrator Mmxxx)转换服务器,以确保转换服务器联机
2、启动Office Web App 服务器场(使用管理员方式运行 PowerShell )
Import-Module OfficeWebApps
3、部署 OfficeOnlineServer 服务器场(其中的参数需要根据自己的服务器进行修改)(部署 OfficeOnlineServer 服务器场时InternalURL 的域服务器必须是启动状态)
New-OfficeWebAppsFarm -InternalURL http://zh.zkh.com -ExternalURL http://192.168.0.113 -AllowHttp -EditingEnabled -OpenFromUrlEnabled
4、在浏览器地址输入 http://zh.zkh.com 进行浏览,界面如下则成功
5、Office Online Server 2016 服务器场参数说明:
New-OfficeWebAppsFarm 的使用及各参数含义可以去微软官网查看:http://technet.microsoft.com/zh-cn/library/jj219436.aspx
-InternalURL:内网访问地址,http://xx.domin.com 其中 xx表示计算机名 domin.com 表示域名
-ExternalURL:外网访问地址,一般为服务器的IP地址
-AllowHttp 允许80端口访问
-EditingEnabled 允许编辑(编辑支持docx,xlsx,pptx,不支持doc,xls,ppt;在线查看上述都支持)(经测试只能实现编辑excel、ppt,而word编辑暂未实现)
-OpenFromUrlEnabled 允许通过url方式进行预览
-CacheLocation 缓存文件存放路径 默认是C:\ProgramData\Microsoft\OfficeWebApps\Working\d
-CacheSizeInGB 最大缓存文件大小 单位GB 默认为15GB
更多参数
https://docs.microsoft.com/zh-cn/powershell/module/officewebapps/new-officewebappsfarm?redirectedfrom=MSDN&view=officewebapps-ps
使用过程中如果想修改服务配置,可以通过Set-OfficeWebAppsFarm命令进行修改
Set-OfficeWebAppsFarm -AllowHttp
Set-OfficeWebAppsFarm -ExternalURL http://192.168.0.117
血泪史啊。。。
问题一
”域服务器 的服务器列表中 转换服务器显示:联机-访问被拒绝“ 的解决方法:
1、右键该服务->管理方式;
2、使用域服务器账号密码登录 xtsm\Administrator Xt123456
问题二
Windows 身份验证”Windows 服务器功能必须安装并启用“
1、打开服务器管理界面;
2、点击添加角色和功能;
3、点击Web服务器(IIS);
4、勾选身份验证。
问题三
很抱歉,出现问题,无法打开此文档。如果此情况持续发生,请尝试在 Microsoft Word 中打开文档。
第一种解决方法
给转换服务器中安装最新版NET Framework
下载链接 : http://www.microsoft.com/en-us/download/details.aspx?id=42643
1、下载并安装最新版 NET Framework(本次下载的是4.5.2)。
2、重新服务器。
第二种解决方法
如果是wopi方式访问时出错可能是要打开的”文件不存在“
问题四
客户机加入到域报错:找不到网络路径
1、关闭客户机防火墙试试。
问题五
双击安装时提示:安装程序无法继续,本产品需要 Windows identity foundtion
1、打开服务器管理器->添加角色和功能->功能->勾选 “Windows Identity Foundtion3.5”
问题六
部署服务器场时报错:必须将服务器加入到域中
可能一:没有将服务器加入到域中;
可能二:虽然加入到域中的,但域服务器此时没有启动;
问题七
打开编辑word的页面时报错:很抱歉,无法打开此文档进行编辑
获取文件信息的接口Bean->FileInfo中定义了”多余“的属性,去掉几个试试,比如BreadcrumbDocName(这里调试时注意服务器缓存,定位这个问题浪费了我大半天时间)
1、部署 OfficeOnlineServer 服务器场时InternalURL 的域服务器必须是启动状态
2、转换服务器中OfficeOnlineServer服务器场启动部署好之后是可以关闭域服务器的;
3、被转换的文档地址需要跟OfficeOnlineServer服务器在同一个局域网下或这在公网下;
4、SHA256的计算(获取该文件的文件流->SHA256计算文件流Hash值->将Hash值转换为Base64String);
5、WPOI的CheckFileInfo接口的参数必须与其API中保持一致(首字母大写);
6、编辑功能不支持多人同时操作;
7、如果出错了,调试时注意缓存;
8、服务器带宽和内存越高越好,测试发现比较耗性能(如果打开较大文件时如果服务器配置过低,会导致打开失败);
9、默认支持单个文件最大为10M;
10、确保80 443 809端口不被其他应用占用;
11、服务器带宽和内存越高越好,测试发现比较耗性能;
12、文件名不能为中文;
13、查看功能支持IE8及以上,编辑功能支持IE9及以上;
支持查看的文件类型(以下为测试成功的文档类型,理论上支持查看更多类型)
doc,docx,xls,xlsx,ppt,pptx,pdf
支持编辑的文档类型
docx,xlsx,pptx
http://你的转换服务器的域名或IP/hosting/discovery
具体如下页面:
当你需要查看docx文件时,输入:http://192.168.0.113/wv/wordviewerframe.aspx?WOPISrc=http://192.168.0.102:8080/wopi/files/a.docx
效果如下
注意了
WOPISrc:别问这个参数怎么来的,反正就这么用
问号前是Office Online Server 2016提供的接口,等号后是你自己服务器里实现的WOPI HOST 接口,这样Office Online Server 2016 就可以打开我们系统里的文件了,重点是这两个地址要在同一个局域网下,或者说后者要能被前者访问到
如果是用的虚拟机部署的,那么域空服务器和转换服务器都配置为桥接模式,这样跟你的第三方系统在一个局域网下,就可以直接访问到了
域控服务器
https://blog.csdn.net/jiaqu2177/article/details/81943615
https://www.cnblogs.com/lovechengcheng/p/4117391.html
主要参考的文章
https://blog.csdn.net/jiaqu2177/article/details/81945692
https://www.cnblogs.com/ldybyz/archive/2017/03/14/6547795.html
WOPI REST接口文档 - CheckFileInfo属性参照
https://wopirest.readthedocs.io/en/latest/files/CheckFileInfo.html
https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-wopi/71e66fb4-144b-4369-b597-f425f0b700b9?redirectedfrom=MSDN
其他资料
https://blog.csdn.net/yufeiyanliu/article/details/70226769
https://www.cnblogs.com/poissonnotes/p/3267190.html
https://blog.csdn.net/weixin_30396699/article/details/95196650
https://blog.csdn.net/q386815991/article/details/81705128
https://blog.csdn.net/l_8369/article/details/83900654#comments
https://blog.csdn.net/jiaqu2177/article/details/81944185
由于这篇文章引入了大量别人文章的链接,本来文章类型想标个转载,但转载只能写一个地址,所以暂时先弄个远传吧,另外如果文章中引用到了哪位大神的文章,望谅解!!!
溜。。。