2013-06-24 63 views
4

這個想法是使用Office Web Apps構建專有的Java後端文檔系統。Office Web Apps Word編輯

我們創建了WOPI客戶端,它允許我們查看/編輯PowerPoint和Excel Web應用程序文檔,但我們只能查看Word文檔。

爲了編輯Word Web App文檔,您需要實現MS-FSSHTTP。

似乎沒有關於如何在代碼中實際執行此操作的信息。有沒有人執行過這個或者會知道如何?

回答

4

最近我和我的團隊實現了一個支持查看和編輯Word,PPT和Excel文檔的WOPI主機。您可以看看https://github.com/marx-yu/WopiHost這是一個命令提示符項目,它監聽8080端口,並允許通過Microsoft Office Web Apps編輯和查看Word文檔。

我們已經在webApi中實現了這個解決方案,它的效果很好。希望這個示例項目能夠幫助你。

請求後,我會嘗試添加代碼示例,以闡明基於webApi實現實現它的方式,但是它們有很多代碼需要實現才能使其正常工作。首先要做的第一件事情是,要啓用編輯功能,您需要在FilesController中捕獲Http Posts。涉及實際編輯的每個帖子的標題爲X-WOPI-Override等於COBALT。在這些文章中,你會發現InputStream是Atom類型。根據MS-WOPI文檔,在您的回覆中,您需要包含以下標頭X-WOPI-CorrelationIDrequest-id

以下是我的webApi post方法的代碼(由於我仍在實現該WOPI協議,因此它並不完整)。

string wopiOverride = Request.Headers.GetValues("X-WOPI-Override").First(); 
if (wopiOverride.Equals("COBALT")) 
{ 
    string filename = name; 
    EditSession editSession = CobaltSessionManager.Instance.GetSession(filename); 
    var filePath = HostingEnvironment.MapPath("~/App_Data/"); 
    if (editSession == null){ 
     var fileExt = filename.Substring(filename.LastIndexOf('.') + 1); 
     if (fileExt.ToLower().Equals(@"xlsx")) 
     editSession = new FileSession(filename, filePath + "/" + filename, @"yonggui.yu", @"yuyg", @"[email protected]", false); 
     else 
     editSession = new CobaltSession(filename, filePath + "/" + filename, @"patrick.racicot", @"Patrick Racicot", @"[email protected]", false); 
     CobaltSessionManager.Instance.AddSession(editSession); 
     } 

     //cobalt, for docx and pptx 
     var ms = new MemoryStream(); 

     HttpContext.Current.Request.InputStream.CopyTo(ms); 
     AtomFromByteArray atomRequest = new AtomFromByteArray(ms.ToArray()); 
     RequestBatch requestBatch = new RequestBatch(); 

     Object ctx; 
     ProtocolVersion protocolVersion; 

     requestBatch.DeserializeInputFromProtocol(atomRequest, out ctx, out protocolVersion); 
     editSession.ExecuteRequestBatch(requestBatch); 


     foreach (Request request in requestBatch.Requests) 
     { 
     if (request.GetType() == typeof(PutChangesRequest) && request.PartitionId == FilePartitionId.Content) 
     { 
      //upload file to hdfs 
      editSession.Save(); 
     } 
     } 
     var responseContent = requestBatch.SerializeOutputToProtocol(protocolVersion); 
     var host = Request.Headers.GetValues("Host"); 
     var correlationID = Request.Headers.GetValues("X-WOPI-CorrelationID").First(); 

     response.Headers.Add("X-WOPI-CorrelationID", correlationID); 
     response.Headers.Add("request-id", correlationID); 
     MemoryStream memoryStream = new MemoryStream(); 

     var streamContent = new PushStreamContent((outputStream, httpContext, transportContent) => 
     { 
     responseContent.CopyTo(outputStream); 
     outputStream.Close(); 
     }); 

     response.Content = streamContent; 
     response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); 
     response.Content.Headers.ContentLength = responseContent.Length; 
} 

正如你可以在這個方法中我使用CobaltSessionManager和用於創建和管理上的鈷協議編輯會話CobaltSession看到。您還需要一個我稱之爲CobaltHostLockingStore的函數,該函數用於在編輯初始化中與Office Web App服務器通信時處理不同的請求。

我不會發布這3個類的代碼,因爲它們已經在我發佈的示例github項目中進行了編碼,並且即使它們很大也很容易理解。

如果您還有其他問題或者不夠清楚,請不要猶豫,我會立即更新我的帖子。

+0

你能否在這裏添加一些例子,而不是簡單地發佈關於你的項目的鏈接? – VMAtm

0

Patrick Racicot,提供了很好的答案。但是我在保存docx時遇到了問題(在CobaltCore.dll中出現異常),我甚至開始使用dotPeak反射器試圖弄清楚它。

但我鎖定editSession變量在我的WebApi方法後,一切開始像魔術一樣工作。看起來,OWA發送的請求應該作爲一個鏈處理,而不是像通常的控制器方法那樣並行處理。