java - Office Web Apps Word 编辑

标签 java c# ms-word fsshttp ms-wopi

想法是使用 Office Web Apps 构建专有的 Java 后端文档系统。

我们已经创建了 WOPI 客户端,它允许我们查看/编辑 PowerPoint 和 Excel 网络应用程序文档,但我们只能查看 Word 文档。

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

似乎没有关于如何在代码中实际执行此操作的信息。有人做过这个或知道怎么做吗?

最佳答案

最近我和我的团队实现了一个支持查看和编辑Word、PPT和Excel文档的WOPI-Host。你可以看看https://github.com/marx-yu/WopiHost这是一个命令提示符项目,它监听 8080 端口并允许通过 Microsoft Office Web Apps 编辑和查看 word 文档。

我们已经在 webApi 中实现了这个解决方案并且效果很好。希望这个示例项目对您有所帮助。

根据要求,我将尝试添加代码示例以阐明基于我的 webApi 实现的实现方式,但要实现它们需要大量代码才能使其正常工作。

首先,要启用编辑功能,您需要在 FilesController 中捕获 Http 帖子。每个涉及实际编辑的帖子的标题 X-WOPI-Override 等于 COBALT。在这些帖子中,您会发现 InputStream 是 Atom 类型。根据 MS-WOPI 文档,在您的响应中,您需要包含以下 header X-WOPI-CorrelationIDrequest-id

这是我的 webApi post 方法的代码(它并不完整,因为我仍在实现该 WOPI 协议(protocol))。

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;
}

如您在该方法中所见,我使用了 CobaltSessionManagerCobaltSession,它们用于在 Cobalt 协议(protocol)上创建和管理编辑 session 。您还需要一个我称之为 CobaltHostLockingStore 的东西,它用于在版本初始化中与 Office Web App 服务器通信时处理不同的请求。

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

如果您有更多问题或不够清楚,请随时发表评论,我会相应地更新我的帖子。

关于java - Office Web Apps Word 编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17280077/

相关文章:

java - 如何包含 Dagger 2?

java - 随机生成的数组中的数字总和

java - Android 中是否有 Raster.getSample(int, int, int) 的等效项?

Java:从 HTTP POST 获取参数和正文

c# - ASP :NET MVC: How can I render two styles in one page without any overlaps of CSS classes?

c# - c#导出数据到word

c# - 几个函数的通用替换

c# 在 IE 中托管用户控件

vba - dotm 创建新文档 - 如何删除对模板的引用?

ms-word - 如何以编程方式在整个 Word 文档中查找和替换