Редактирование Word в Office Web Apps
Идея состоит в том, чтобы создать собственную систему документов Java-приложений с использованием Office Web Apps.
Мы создали клиент WOPI, который позволяет нам просматривать / редактировать документы веб-приложений PowerPoint и Excel, но мы можем только просматривать документы Word.
Для редактирования документов Word Web App необходимо реализовать MS-FSSHTTP.
Похоже, что нет никакой информации о том, как на самом деле сделать это в коде. Кто-нибудь выполнил это или знает как?
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", @"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;
}
Как вы можете видеть в этом методе, я использую CobaltSessionManager
а также CobaltSession
которые используются для создания и управления сеансами редактирования по протоколу Cobalt. Вам также понадобится то, что я называю CobaltHostLockingStore, которое используется для обработки различных запросов при взаимодействии с сервером Office Web App при инициализации выпуска.
Я не буду публиковать код для этих 3 классов, так как они уже написаны в примере проекта Github, который я опубликовал, и что их довольно просто понять, даже если они большие.
Если у вас есть еще вопросы или если это не совсем понятно, не стесняйтесь комментировать, и я обновлю свой пост соответственно.
Патрик Racicot, предоставил отличный ответ. Но у меня были проблемы с сохранением docx(исключение в CobaltCore.dll), и я даже начал использовать отражатель dotPeak, пытаясь выяснить это.
Но после того, как я запер editSession
Переменная в моем методе WebApi все начало работать как по волшебству. Похоже, что OWA отправляет запросы, которые должны обрабатываться как цепочка, а не параллельно, как обычно действует метод контроллера.