Редактирование Word в Office Web Apps

Идея состоит в том, чтобы создать проприетарную внутреннюю систему документов Java с использованием Office Web Apps.

Мы создали клиент WOPI, который позволяет нам просматривать / редактировать документы веб-приложений PowerPoint и Excel, но мы можем просматривать только документы Word.

Чтобы редактировать документы Word Web App, вам необходимо реализовать MS-FSSHTTP.

Похоже, что информации о том, как это сделать в коде, нет. Кто-нибудь выполнил это или знал бы как?


person topcat3    schedule 24.06.2013    source источник


Ответы (2)


Недавно мы с моей командой реализовали WOPI-Host, который поддерживает просмотр и редактирование документов Word, PPT и Excel. Вы можете взглянуть на https://github.com/marx-yu/WopiHost, который проект командной строки, который прослушивает порт 8080 и позволяет редактировать и просматривать текстовые документы через Microsoft Office Web Apps.

Мы реализовали это решение в webApi, и оно отлично работает. Надеюсь, этот образец проекта поможет вам.

После запроса я попытаюсь добавить образцы кода, чтобы прояснить способ его реализации на основе моей реализации webApi, но их нужно реализовать, чтобы заставить его работать должным образом.

Перво-наперво, чтобы включить редактирование, вам нужно будет записывать Http-сообщения в FilesController. Каждые сообщения, которые касаются фактического редактирования, будут иметь заголовок X-WOPI-Override, равный COBALT. В этом посте вы узнаете, что InputStream - это тип Atom. Согласно документации MS-WOPI, в свой ответ вам нужно будет включить следующие заголовки X-WOPI-CorrelationID и request-id.

Вот код моего метода публикации webApi (он не завершен, поскольку я все еще реализую этот протокол 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, которые используются для создания и управления сеансами редактирования по протоколу Cobalt. Вам также понадобится то, что я называю CobaltHostLockingStore, который используется для обработки различных запросов при взаимодействии с сервером Office Web App при инициализации выпуска.

Я не буду публиковать код для этих трех классов, поскольку они уже закодированы в опубликованном мною образце проекта github, и их довольно просто понять, даже если они большие.

Если у вас есть дополнительные вопросы или если они недостаточно ясны, не стесняйтесь комментировать, и я соответствующим образом обновлю свой пост.

person Patrick Racicot    schedule 06.08.2014
comment
не могли бы вы добавить сюда несколько примеров, а не просто разместить ссылку о своем проекте? - person VMAtm; 06.08.2014
comment
У меня такая же проблема. но я не могу предоставить своим клиентам другой сервер Microsoft. Как взаимодействовать с офисными продуктами без предоставления веб-сервера Microsoft? Я искал webdave, но webdav требует ActiveX и Firefox, а Chrome не поддерживает это. - person Amir Amiri; 28.08.2018

Патрик Расико дал отличный ответ. Но у меня возникла проблема с сохранением docx (исключение в CobaltCore.dll), и я даже начал использовать отражатель dotPeak, пытаясь понять это.

Но после того, как я заблокировал переменную editSession в моем методе WebApi, все начало работать как по волшебству. Кажется, что OWA отправляет запросы, которые следует обрабатывать как цепочку, а не параллельно, как обычно действует метод контроллера.

person bitval    schedule 13.02.2015