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