Недавно мы с моей командой реализовали 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