?
?1.先要在Windows Server 2008或2012上安装好Office Web Apps Server,网上已有相关文章,此处不再赘述。Windows Server 2008部署步骤:http://www.cnblogs.com/yanweidie/p/4516164.html 微软官方地址:https://technet.microsoft.com/zh-cn/library/jj219455.aspx
2.服务安装成功后,输入http://owa.domain.com/hosting/discovery和http://owa.domain.com/op/generate.aspx,owa.domain.com为自己配置的域名,如果自己配置的域名访问失败,将对应的ip添加到hosts文件中即可,也可直接访问ip,即http://192.168.1.11/hosting/discovery和http://192.168.1.11/op/generate.aspx。效果图如下:
?
?
?
3.重点:编写java代码,实现WOPI协议
下面代码是用Servlet实现的,先用Filter拦截用户请求,拦截器配置:
@WebFilter("/wopi/*")
?
1.CheckFileInfo服务:需要返回一个JSON字符串,包含5个基本信息:BaseFileName(文件名), OwnerId(文件所有者的唯一编号), Size(文件大小,以bytes为单位), SHA256(文件的256位bit的SHA-2编码散列内容), Version(文件版本号)
好多资料都介绍说返回这5个数据,但经本人亲测,在Java中实现不需要SHA256,需要AllowExternalMarketplace,值为true,根据微软官网参数介绍:AllowExternalMarketplace: A Boolean value that indicates the WOPI client MAY allow connections to external services referenced in the file (for example, a marketplace of embeddable JavaScript apps). If this value is false, then the WOPI client MUST NOT allow such connections.
2.GetFile服务:以Stream流的方式返回该文件
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest)request; HttpServletResponse httpResponse = (HttpServletResponse)response; String uri = httpRequest.getRequestURI(); ///wopihost/wopi/files/excel.xlsx //解决中文乱码问题 String fileUri = URLDecoder.decode(uri.substring(uri.indexOf("/wopi/") + 1, uri.length()),"UTF-8"); // /wopi/files/test.docx String filePath = request.getServletContext().getRealPath("/")+fileUri; if(fileUri.endsWith("/contents")) { // GetFile :返回文件流 filePath = filePath.substring(0, filePath.indexOf("/contents")); getFile(filePath, httpResponse); } else { // CheckFileInfo :返回json response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); PrintWriter out = null; try { out = response.getWriter(); out.write(FileUtils.checkFileInfo(filePath)); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); } } } return; }
其中getFile(filePath, httpResponse);是返回文件下载流,FileUtils.checkFileInfo(filePath)是返回文件的JSON信息。
getFile(filePath, httpResponse)
private HttpServletResponse getFile(String path, HttpServletResponse response) { try { // path是指欲下载的文件的路径。 File file = new File(path); // 取得文件名。 String filename = file.getName(); String contentType = "application/octet-stream"; // 以流的形式下载文件。 InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); // 清空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()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType(contentType); toClient.write(buffer); toClient.flush(); toClient.close(); } catch (IOException ex) { ex.printStackTrace(); } return response; }
FileUtils.checkFileInfo(filePath)实现:
/** * 获取文件基本信息 * @param filePath 文件路径 * @return */ public static String checkFileInfo(String filePath) { File file = new File(filePath); String baseFileName = null; //文件名 String ownerId = null; //文件所有者的唯一编号 long size = 0; //文件大小,以bytes为单位 //String sha256 = null; //文件的256位bit的SHA-2编码散列内容 long version = 0; //文件版本号,文件如果被编辑,版本号也要跟着改变 if(file.exists()) { // 取得文件名。 baseFileName = file.getName(); size = file.length(); // 取得文件的后缀名。 //String ext = baseFileName.substring(baseFileName.lastIndexOf(".") + 1); ownerId = "admin"; //sha256 = new SHAUtils().SHA(FileUtils.readByByte(file), "SHA-256"); version = file.lastModified(); } return "{\"BaseFileName\":\"" + baseFileName + "\",\"OwnerId\":\"" + ownerId + "\",\"Size\":\"" + size + "\",\"AllowExternalMarketplace\":\"" + true + "\",\"Version\":\"" + version + "\"}"; }
代码实现后访问http://127.0.0.1:8080/wopihost/wopi/files/test.docx则出现如下页面:
?
访问http://127.0.0.1:8080/wopihost/wopi/files/test.docx/contents则下载该文件
访问http://owa.domain.com/wv/wordviewerframe.aspx?WOPISrc=http%3A%2F%2F192.168.1.11%3A8080%2Fwopihost%2Fwopi%2Ffiles%2Ftest.docx
注意:
1.WOPISrc后的ip地址要写真实的ip地址,否则会转换失败
2.不同类型文档的访问地址对应的地址不同
3.如果文件名为中文名,要进行两次URLEncoder.encode,即URLEncoder.encode(URLEncoder.encode(fileName,"utf-8"),"utf-8"),否则预览失败,这与微软的内部实现有关。
实现效果图如下:
?
?
?
?
相关文章:
Office Web Apps Server的介绍:https://blogs.technet.microsoft.com/office_resource_kit/2012/09/11/introducing-office-web-apps-server/
WOPI协议介绍:https://blogs.msdn.microsoft.com/officedevdocs/2013/03/21/introducing-wopi/#comments
实现WOPI协议(C#):https://blogs.msdn.microsoft.com/scicoria/2013/07/22/building-an-office-web-apps-owa-wopi-host/
微软的官方文档:https://technet.microsoft.com/zh-cn/library/jj219456(v=office.15).aspx
其它相关资料:http://www.tuicool.com/articles/ayeENz
http://www.cnblogs.com/poissonnotes/p/3267190.html
http://www.cnblogs.com/poissonnotes/p/3277280.html
?
Office Web Apps Server作为Client,Java代码作为Host实现Office在线预览
原文:http://rebecca-zhong.iteye.com/blog/2287774