Java Office Web应用程序文字编辑

Java Office Web应用程序文字编辑,java,c#,ms-word,fsshttp,ms-wopi,Java,C#,Ms Word,Fsshttp,Ms Wopi,其想法是使用OfficeWebApps构建一个专有的Java后端文档系统 我们已经创建了WOPI客户端,它允许我们查看/编辑PowerPoint和Excel web app文档,但我们只能查看Word文档 为了编辑Word Web App文档,您需要实现MS-FSSHTTP 似乎没有关于如何在代码中实际执行此操作的信息。是否有人执行了此操作或知道如何执行此操作?最近,我的团队和我实现了一个WOPI主机,它支持查看和编辑Word、PPT和Excel文档。您可以查看哪个是命令提示符项目,它侦听808

其想法是使用OfficeWebApps构建一个专有的Java后端文档系统

我们已经创建了WOPI客户端,它允许我们查看/编辑PowerPoint和Excel web app文档,但我们只能查看Word文档

为了编辑Word Web App文档,您需要实现MS-FSSHTTP


似乎没有关于如何在代码中实际执行此操作的信息。是否有人执行了此操作或知道如何执行此操作?

最近,我的团队和我实现了一个WOPI主机,它支持查看和编辑Word、PPT和Excel文档。您可以查看哪个是命令提示符项目,它侦听
8080
端口,并通过Microsoft Office Web App编辑和查看word文档

我们已经在一个webApi中实现了这个解决方案,效果非常好。希望这个示例项目将帮助您

在收到请求后,我将尝试添加代码示例,以澄清如何基于我的webApi实现来实现它,但要使它真正正常工作,需要实现大量代码

首先,要启用编辑,您需要在FileController中捕获Http帖子。与实际编辑相关的每篇文章的标题
X-WOPI-Override
等于
COBALT
。在这些帖子中,您将发现InputStream是和Atom类型的。根据MS-WOPI文档,您需要在回复中包含以下标题
X-WOPI-CorrelationID
请求id

下面是我的webApi post方法的代码(由于我仍在实现WOPI协议,所以它还不完整)

正如您在这个方法中所看到的,我使用了
CobaltSessionManager
CobaltSession
,它们用于创建和管理Cobalt协议上的编辑会话。您还需要一个我称之为CobaltHostLockingStore的应用程序,用于在版本初始化中与Office Web App server通信时处理不同的请求

我不会发布这3个类的代码,因为它们已经在我发布的示例github项目中进行了编码,而且它们非常容易理解,即使它们很大


如果你有更多的问题或者不够清楚,请不要犹豫发表评论,我会相应地更新我的帖子。

帕特里克·拉西科特(Patrick Racico)提供了很好的答案。但我在保存docx(CobaltCore.dll中的异常)时遇到了问题,我甚至开始使用dotPeak reflector来解决这个问题


但当我在WebApi方法中锁定了
editSession
变量后,一切都像魔术一样开始工作。似乎OWA发送的请求应该作为一个链来处理,而不是像通常的控制器方法那样并行处理。

您能在这里添加一些示例,而不是简单地发布关于您的项目的链接吗?我也有同样的问题。但我无法为我的客户提供另一台Microsoft服务器。如何在不提供Microsoft Web online server的情况下与office产品交互?我搜索了webdave,但WebDav需要ActiveX,Firefox和chrome不支持。
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", @"yonggui.yu@emacle.com", false);
      else
         editSession = new CobaltSession(filename, filePath + "/" + filename, @"patrick.racicot", @"Patrick Racicot", @"patrick.racicot@hospitalis.com", 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;
}