2013-06-24 58 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发送的请求应该作为一个链处理,而不是像通常的控制器方法那样并行处理。