微软 Office Online Server 2016 服务安装部署 + wopi代码实现

国内bat提供这样的服务,但是要收点钱,所以选择了免费的office online,当然缺点是安装贼烦 

安装过程很繁琐,文档写的很不友好,各种专有词汇,对于新手上手很难,什么域服务器,转换服务器,什么sharepoint,天马行空.之前在网上找到一篇安装的教程,奈何没有图片,全程摸打滚爬,最后安装成功.感觉国内用这个的人应该不多,所以详细教程较少,这次整理下,希望帮助后人.

概述

1.要使用office online功能,首先需要的是2台主机,并且主机的系统要求是windwos Server. 

2.这里提到一共要有2台windwos主机,其中一台是要安装officeOnline ,这个可以理解毕竟要提供officeOnline服务 ,另外一个windows 主机是需要作为域控制器,又是一个专业词汇,域控制器什么鬼? 这里就把这个主机当做主控吧,由这个主机专门负责管理office online主机,

3.上面说到了域控制器,这个是负责管理office online主机的,另外我们的项目是需要编程的,我们需要通过编程将office online融入到项目汇中,我们项目用到的java代码实现wopi,如果是其他的语言实现的wopi代码也可以,这些代码需要运行在域控制器上.

4.下面来看一下,具体的流程 
这里写图片描述

又一次想喷微软,上面还在说 域控制器,officeonline主机,这里又起了另外的2个名字, 
WOPI Server—->做域控的主机 
WOPI Client—–>安装office online 的主机

浏览器访问WOPI Server上面我们编写的程序,然后会有一大串的请求过程,最后得到的结果就是,浏览器会在web端看到office 文件的内容.

这里写图片描述

一、域控制器安装部署

请根据我的另一篇文章:《域控服务器安装教程》完成部署。

二、转换服务器部署

首先提供一下 office online server 2016 的中文安装包和语言包,因为这两个是比较难下载到的!

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|/

1、打开安装好的服务器。

这里推荐使用 windows server 2012 r2 with update。

因为我在安装的时候尝试过 windows server 2008、windows server 2012、windows server 2012 r2

唯独 windows server 2012 r2 with update 没有出错,直接一次到位!

2、运行 powershell ,输入以下命令:

Install-WindowsFeature Web-Server,Web-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

进行安装系统角色。

这里写图片描述

安装完成后重启。

这里写图片描述
 

3、按照顺序安装微软提供的软件。

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

 

4、下面进入主题了,安装office online。

双击下载好的office online 安装包,进行安装。

这里写图片描述

安装成功。

这里写图片描述

 

5、安装语言包。

这里写图片描述

安装成功。

这里写图片描述

至此,所有的软件安装就已经完成了。

三、WOPI代码实现

1、域控服务器安装java环境 

我们的java 代码在域控服务器上面运行,所以要现在域控服务器上面安装java环境,这个就不演示了,网上windows安装java教程一大推

2、启动office Online 服务器场

打开安装office Online 的主机,打开powerShell。

启动服务场

Import-Module OfficeWebApps

部署服务器场: 

New-OfficeWebAppsFarm -InternalURL “http://xx.domin.com” -ExternalUrl “http://192.168.37.138” -AllowHttp –EditingEnabled

–InternalURL内部访问地址,一般是http://office主机名.AD域控地址(如下图); 

–AllowHttp 是否允许http访问;

–ExternalUrl 外部访问地址,一般是服务器的ip地址;

–EditingEnabled 允许编辑office。

 

出现如下提示即部署成功!

这里写图片描述

这个时候用可以看下有没有启动起来

在office online 的浏览器 输入:http://win-5ldi2svjqoj.test.com/hosting/discovery 得到以下的结果就ok 了

这里写图片描述

当然通过ip地址访问也是ok,http://192.168.37.138/hosting/discovery

当然这两个地址在域控服务器上面访问 也是ok 的

3.安装好java环境后,启动服务场后,开始上代码

package com.wopihost.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wopihost.entity.FileInfo;
import org.apache.tomcat.util.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * WOPI HOST
 * Created by ethendev on 2017/4/15.
 */
@RestController
@RequestMapping(value="/wopi")
public class WopiHostContrller {

    @Value("${file.path}")
    private String filePath;

    /**
     * 获取文件流
     * @param name
     * @param response
     */
    @GetMapping("/files/{name}/contents")
    public void getFile(@PathVariable(name = "name") String name, HttpServletResponse response) {
        System.out.println("GET获取文件啦!!!!");
        InputStream fis = null;
        OutputStream toClient = null;
        try {
            // 文件的路径
            String path = filePath + name;
            File file = new File(path);
            // 取得文件名
            String filename = file.getName();
            // 以流的形式下载文件
            fis = new BufferedInputStream(new FileInputStream(path));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            // 清空response
            response.reset();

            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" +
                    new String(filename.getBytes("utf-8"), "ISO-8859-1"));
            response.addHeader("Content-Length", "" + file.length());
            toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            toClient.write(buffer);
            toClient.flush();
            System.out.println("GET获取文件Contents结束!!!!");

        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                fis.close();
                toClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 保存更新文件
     * @param name
     * @param content
     */
    @PostMapping("/files/{name}/contents")
    public void postFile(@PathVariable(name = "name") String name, @RequestBody byte[] content) {
        System.out.println("POST获取文件Contents啦!!!!");
        // 文件的路径
        String path = filePath + name;
        File file = new File(path);
        FileOutputStream fop = null;
        try {
            if (!file.exists()) {
                file.createNewFile();//构建文件
            }
            fop = new FileOutputStream(file);
            fop.write(content);
            fop.flush();
            System.out.println("POST获取文件结束!!!!");

            System.out.println("------------ save file ------------ ");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fop.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取文件信息
     * @param request
     * @param response
     * @return
     * @throws UnsupportedEncodingException
     */
    @GetMapping("/files/{name}")
    public void getFileInfo(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("获取文件啦!!!!");
        String uri = request.getRequestURI();
        FileInfo info = new FileInfo();
        try {
            // 获取文件名, 防止中文文件名乱码
            String fileName = URLDecoder.decode(uri.substring(uri.indexOf("wopi/files/") + 11, uri.length()), "UTF-8");
            if (fileName != null && fileName.length() > 0) {
                System.out.println("文件不为空啊");
                File file = new File(filePath + fileName);
                if (file.exists()) {
                    // 取得文件名
                    info.setBaseFileName(file.getName());
                    info.setSize(file.length());
                    info.setOwnerId("admin");
                    info.setVersion(file.lastModified());
                    info.setSha256(getHash256(file));
                    info.setAllowExternalMarketplace(true);
                    info.setUserCanWrite(true);
                    info.setSupportsUpdate(true);
                    info.setSupportsLocks(true);
                }
            }

            ObjectMapper mapper = new ObjectMapper();
            String Json =  mapper.writeValueAsString(info);

            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write(Json);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取文件的SHA-256值
     * @param file
     * @return
     */
    public static String getHash256(File file) {
        String value = "";
        // 获取hash值
        try {
            byte[] buffer = new byte[1024];
            int numRead;
            InputStream fis = new FileInputStream(file);
            //如果想使用SHA-1或SHA-256,则传入SHA-1,SHA-256
            MessageDigest complete = MessageDigest.getInstance("SHA-256");
            do {
                //从文件读到buffer
                numRead = fis.read(buffer);
                if (numRead > 0) {
                    //用读到的字节进行MD5的计算,第二个参数是偏移量
                    complete.update(buffer, 0, numRead);
                }
            } while (numRead != -1);

            fis.close();
            value = new String(Base64.encodeBase64(complete.digest()));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return value;
    }

}

看过了代码,再来看下,第一篇说到的那个图

这里写图片描述

从图中可以看到,office online主机一共会回调2次域控主机,分别是 tell me about the file 还有一个是give me the file

这两次回调 分别对应下面两个接口 
@GetMapping(“/files/{name}”) 
@PostMapping(“/files/{name}/contents”)

代码中,还有一个 @Value(“${file.path}”) 配置

因为 WOPI Server 主机需要把文件传给 WOPI Client 主机,那么问题来了? WOPI Server 从哪里获取文件? 这里我是直接放在WOPI Server 的C盘,这个文件可以放在任何地方,只要WOPI Server可以拿到这个文件就可以,我为了方便直接放在WOPI Server的c盘

用mvn package 把 这个应用打包成war包 上传到域控 服务器上面.

4.运行域控里面的java代码,查看效果

直接在jar 包所在的目录运行cmd:

java -jar wopihost-0.0.1-SNAPSHOT.jar
  • 1

程序跑起来如图:

这里写图片描述

我把一个123.docx放到了域控的磁盘里面,怎么才能预览word 文件? 
上面说到的地址 http://win-5ldi2svjqoj.test.com/hosting/discovery 在浏览器返回的结果中搜索 word 
就可以看到访问的地址

这里写图片描述

比如我要查看word ,那么主机地址就是:http://win-5ldi2svjqoj.test.com/wv/wordviewerframe.aspx 
当然这个还不够

上面说过 office online 主机会 回调 域控的我们写的java 代码,但是office online主机还不知道 域控在哪里 所以在网址后面还要 
加点东西 
整个地址是这样:http://win-5ldi2svjqoj.test.com/wv/wordviewerframe.aspx?WOPISrc=http://192.168.37.142/wopi/files/123.docx

从这个地址中可以看出,其实是域控主机访问的office online的主机,并在url中带上了域控的主机的地址WOPISrc,这样office Online主机会根据这个地址回调域控主机里面我们写的代码,一共2次,从而进行office 的显示.

把上面的这个地址输入到域控的浏览器中发现,并不能正确的显示,还报错.

这里写图片描述

5.原因排查

半个月前弄好的时候忘记记录,现在搞突然没有用,一定是有什么细节忘记了,只好开始排查

首先是 http://win-5ldi2svjqoj.test.com/hosting/discovery 访问这个地址的话,浏览器可以正确的返回一些数据,这个说明office online服务场是正确安装的.

然后在域控的主机上面单独的访问我们编写的wopi 的代码

http://127.0.0.1/wopi/files/123.docx/contents
  • 1

控制台也确实有输出,说明访问到了,但是ie由于安装没有给我们下载文件,但至少说明wopi 的代码是没有问题的.

这里写图片描述

继续排查,这个时候突然想起一件事情,office online 的主机是会回调 域控的主机的,那么手动的去调用看看

域控的主机ip:192.168.37.142 
在office online 的主机里面的浏览器输入

 http://192.168.37.142/wopi/files/123.docx
  • 1

显示的是无法访问网页

这里写图片描述

这个时候一想,对啊,可能域控主机的防火墙没有关掉,赶紧进入域控的控制面板–>windows防火墙—>启动或关闭windows防火墙,将域防火墙暂时先关掉,点击确定 
这里写图片描述

这个时候再回到域控的主机 ,把上面的那个地址输入按下回车

这里写图片描述

ok啦,结果成功的显示了,在右上角上面有 在浏览器中编辑,点击看一下.

这里写图片描述

可以进行编辑.

大吉大利,一切都是ok 的

至此整个office online 的安装部署,java wopi 代码的运行全部ok.可喜可贺.

6.后记

在我一开始准备安装office online 的时候,同事就跟我说要用到2台机器,一台是安装域控,一台是安装office Online主机, 
自己也是这么摸索着安装,测试,运行.

后来在真实的项目中的时候,甲方对安全要求比较高,安装域控是要经过审核的,金融行业,对钱比较敏感,不可能随随便便让你去在他们那里安装个域控的.

重新整理下整个安装过程和代码的运行过程,其实整个过程好像和域控也没啥关系,我们的服务都是office online 主机提供的,能不能只安装这一台服务器,不安装域控了 ?

想法:直接在一台主机上面安装office online ,并在office online 主机上面配置服务场,然后在随便的另外一台主机上面运行java 编写的wopi的代码.

结果是不行的,因为在服务场的时候,运行的power shell 代码有两个参数

New-OfficeWebAppsFarm -InternalURL “http://WIN-5LDI2SVJQOJ.test.com” -ExternalUrl “http://192.168.37.138 -AllowHttp –EditingEnabled

一个是 InternalURL ,一个是ExternalUrl 
ExternalUrl是office online 的主机的ip地址,这个好说, 
但是InternalURL 你怎么搞了?

如果我们的office online 主机不加入域的话,他的计算机名称里面是没有类似xxx.com 这样的东西的,只是简单的一个名字

这里写图片描述

不死心,继续用这个名字开启服务场试试? 
报错信息明确指明:必须将服务器加入到域中

这里写图片描述

到微软的官方文档 看一看

这里写图片描述

官方文档也写了office online 必须是域的一部分.看来域控是必须要有的,office online 主机不能脱离 域控单独运行.

那怎么办?甲方不让安装域控,那只有使用甲方的域控了,好在这个是可以的.

方法: 
我们只需要把office online添加到甲方的域中就ok,然后甲方自己再把我们的office online主机 添加进管理,和之前的操作是一样的,只不过,域控主机的操作不是我们而已.然后再申请一个机器,在里面跑wopi 代码就ok.

之前做测试WOPI代码的时候,直接在域控上面跑的,现在加入的是甲方的域控,是不能让你在上面跑java 代码的,所以要另外一个机器,在另外一台机器上跑wopi代码

回到自己的测试. 
在虚拟机中新建一个主机,ip地址是:192.168.37.135,安装java 环境,把word文件上传到该服务器的c盘,把之前编写的wopi 的代码上传到上面去,并运行.

访问的地址要变化,回调地址从域控的地址,改成新的主机的地址,也就是下面的这个地址:

http://192.168.37.138/wv/wordviewerframe.aspx?WOPISrc=http://192.168.37.135/wopi/files/123.docx

这里写图片描述

结果是ok 的

其实在整个过程中,域控的唯一作用就是 让office online主机添加进域,并管理了office online主机,只有这样office online 主机的服务才能跑起来,一旦跑起来了,后面的事情也就跟域控的主机没有什么关系了

 

  • 13
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 66
    评论
onlyoffice本地开发可以按照以下步骤进行: 1. 首先,你需要从官方网站下载onlyoffice的开源文档服务器(DocumentServer)的代码。你可以在中找到官方的github地址。 2. 下载代码后,你需要根据开发文档中提供的指导,搭建本地的onlyoffice开发环境。你可以按照开发文档中的说明进行操作。 3. 在搭建好开发环境后,你可以使用Office Web App Server来进行本地文件的预览。你可以参考中提供的格式来配置文件预览。 4. 如果你遇到上传Word文件后显示"download failed"的问题,可以尝试解决以下几个可能的原因: - 确保你的本地地址正确配置,不要使用"localhost"或"127.0.0.1"来访问,而是使用你的完整地址(例如:192.168.0.xx:8090/...)。 - 检查代理工具的设置,确保只有本地地址可以使用代理,否则可能会出现https安全问题。 - 检查app.js和api.js的版本是否一致,如果不一致,可以尝试将版本号同步,并进行部署。 5. 最后,你可以按照需要修改代码和配置文件来满足你的本地开发需求。 请注意,以上步骤仅供参考,具体的onlyoffice本地开发过程可能因个人需求和环境而异。你可以参考官方的开发文档和github代码库来获取更详细的信息和指导。希望这些信息对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [onlyoffice 本地二次开发基础教程](https://blog.csdn.net/makuta888/article/details/114264592)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [ows-project:office web app server 文档预览部署&&wopi 集成](https://download.csdn.net/download/weixin_42134094/18731539)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 66
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值