office for apps app c# .net sharepoint ms-office ms-wopi

c# - for - ¿Puedo usar Office Web Apps Server?



download office web apps server (1)

Estoy tratando de tener un sistema de administración de documentos en el navegador con la oficina. Encontré esta solución http://www.edrawsoft.com/officeviewer.php pero usa la copia del cliente de la oficina.

Me gustaría usar Office Web Apps, pero mi pregunta es ... ¿Necesito usarla a través de SharePoint u otros productos de Microsoft o puedo conectar un sitio web para usar Office Web Apps en el navegador de mi propio sistema de documentos?


Puede escribir su propio servidor que implemente el protocolo WOPI, esto admitirá PPTX / XSLX en el modo de visualización / edición, DOCX / PDF en el modo de visualización solamente. El servidor WOPI es bastante simple de implementar.

Para editar documentos de Word, debe implementar el protocolo Cobalt o FSSHTTP / FSSHTTPB.

Además, no olvide las licencias, Office Web Apps requiere que todos los usuarios tengan una licencia de oficina válida.

Aquí hay un ejemplo del servidor .NET WOPI:

Llámalo con:

http://OFFICEWEBAPPS.HOST/p/PowerPointFrame.aspx?PowerPointView=EditView&access_token=12345&WOPISrc=URLENCODED_URL_OF_THE_WOPI_SERVER

Me gusta: http://WOPISERVER.HOST:2000/wopi/files/1.pptx

Esto abrirá 1.pptx en tu c: / temp

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; using System.Runtime.Serialization; using System.Net; using System.Net.Http; using System.Threading.Tasks; using System.Web; using System.IO; using System.Runtime.Serialization.Json; namespace WopiServerTutorial { public class WopiServer { private HttpListener Listener; static void Main(string[] args) { WopiServer s = new WopiServer(); s.Start(); Console.WriteLine("A simple wopi webserver. Press a key to quit."); Console.ReadKey(); s.Stop(); } public void Start() { Listener = new HttpListener(); Listener.Prefixes.Add(@"http://+:8080/"); Listener.Start(); Listener.BeginGetContext(ProcessRequest, Listener); Console.WriteLine(@"WopiServer Started"); } public void Stop() { Listener.Stop(); } private void ProcessRequest(IAsyncResult result) { HttpListener listener = (HttpListener)result.AsyncState; HttpListenerContext context = listener.EndGetContext(result); Console.WriteLine(@"Got a " + context.Request.HttpMethod + " request for URL: " + context.Request.Url.PathAndQuery); var stringarr = context.Request.Url.AbsolutePath.Split(''/''); var rootDir = @"C://temp//"; if (stringarr.Length == 5 && context.Request.HttpMethod.Equals(@"GET")) { Console.WriteLine(@"Getting content for the file: " + rootDir + stringarr[3]); // get file''s content var file = rootDir + stringarr[3]; var stream = new FileStream(file, FileMode.Open); var fi = new FileInfo(file); context.Response.ContentType = @"application/octet-stream"; context.Response.ContentLength64 = fi.Length; stream.CopyTo(context.Response.OutputStream); context.Response.Close(); } //else if (stringarr.Length == 5 && context.Request.HttpMethod.Equals(@"POST")) //{ // // write //} else if (stringarr.Length == 4 && context.Request.HttpMethod.Equals(@"GET")) { Console.WriteLine(@"Getting metdata for the file: " + rootDir + stringarr[3]); var fi = new FileInfo(rootDir + stringarr[3]); CheckFileInfo cfi = new CheckFileInfo(); cfi.AllowExternalMarketplace = false; cfi.BaseFileName = fi.Name; cfi.BreadcrumbBrandName = ""; cfi.BreadcrumbBrandUrl = ""; cfi.BreadcrumbDocName = ""; cfi.BreadcrumbDocUrl = ""; cfi.BreadcrumbFolderName = ""; cfi.BreadcrumbFolderUrl = ""; cfi.ClientUrl = ""; cfi.CloseButtonClosesWindow = false; cfi.CloseUrl = ""; cfi.DisableBrowserCachingOfUserContent = true; cfi.DisablePrint = true; cfi.DisableTranslation = true; cfi.DownloadUrl = ""; cfi.FileUrl = ""; cfi.FileSharingUrl = ""; cfi.HostAuthenticationId = "s-1-5-21-3430578067-4192788304-1690859819-21774"; cfi.HostEditUrl = ""; cfi.HostEmbeddedEditUrl = ""; cfi.HostEmbeddedViewUrl = ""; cfi.HostName = @"SharePoint"; cfi.HostNotes = @"HostBIEnabled"; cfi.HostRestUrl = ""; cfi.HostViewUrl = ""; cfi.IrmPolicyDescription = ""; cfi.IrmPolicyTitle = ""; cfi.OwnerId = @"4257508bfe174aa28b461536d8b6b648"; cfi.PresenceProvider = "AD"; cfi.PresenceUserId = @"S-1-5-21-3430578067-4192788304-1690859819-21774"; cfi.PrivacyUrl = ""; cfi.ProtectInClient = false; cfi.ReadOnly = false; cfi.RestrictedWebViewOnly = false; cfi.SHA256 = ""; cfi.SignoutUrl = ""; cfi.Size = fi.Length; cfi.SupportsCoauth = false; cfi.SupportsCobalt = false; cfi.SupportsFolders = false; cfi.SupportsLocks = true; cfi.SupportsScenarioLinks = false; cfi.SupportsSecureStore = false; cfi.SupportsUpdate = true; cfi.TenantId = @"33b62539-8c5e-423c-aa3e-cc2a9fd796f2"; cfi.TermsOfUseUrl = ""; cfi.TimeZone = @"+0300#0000-11-00-01T02:00:00:0000#+0000#0000-03-00-02T02:00:00:0000#-0060"; cfi.UserCanAttend = false; cfi.UserCanNotWriteRelative = false; cfi.UserCanPresent = false; cfi.UserCanWrite = true; cfi.UserFriendlyName = ""; cfi.UserId = ""; cfi.Version = @"%22%7B59CCD75F%2D0687%2D4F86%2DBBCF%2D059126640640%7D%2C1%22"; cfi.WebEditingDisabled = false; // encode json var memoryStream = new MemoryStream(); var json = new DataContractJsonSerializer(typeof(CheckFileInfo)); json.WriteObject(memoryStream, cfi); memoryStream.Flush(); memoryStream.Position = 0; StreamReader streamReader = new StreamReader(memoryStream); var jsonResponse = Encoding.UTF8.GetBytes(streamReader.ReadToEnd()); context.Response.ContentType = @"application/json"; context.Response.ContentLength64 = jsonResponse.Length; context.Response.OutputStream.Write(jsonResponse, 0, jsonResponse.Length); context.Response.Close(); } else { byte[] buffer = Encoding.UTF8.GetBytes(""); context.Response.ContentLength64 = buffer.Length; context.Response.ContentType = @"application/json"; context.Response.OutputStream.Write(buffer, 0, buffer.Length); context.Response.OutputStream.Close(); } Listener.BeginGetContext(ProcessRequest, Listener); } } [DataContract] public class CheckFileInfo { [DataMember] public bool AllowExternalMarketplace { get; set; } [DataMember] public string BaseFileName { get; set; } [DataMember] public string BreadcrumbBrandName { get; set; } [DataMember] public string BreadcrumbBrandUrl { get; set; } [DataMember] public string BreadcrumbDocName { get; set; } [DataMember] public string BreadcrumbDocUrl { get; set; } [DataMember] public string BreadcrumbFolderName { get; set; } [DataMember] public string BreadcrumbFolderUrl { get; set; } [DataMember] public string ClientUrl { get; set; } [DataMember] public bool CloseButtonClosesWindow { get; set; } [DataMember] public string CloseUrl { get; set; } [DataMember] public bool DisableBrowserCachingOfUserContent { get; set; } [DataMember] public bool DisablePrint { get; set; } [DataMember] public bool DisableTranslation { get; set; } [DataMember] public string DownloadUrl { get; set; } [DataMember] public string FileSharingUrl { get; set; } [DataMember] public string FileUrl { get; set; } [DataMember] public string HostAuthenticationId { get; set; } [DataMember] public string HostEditUrl { get; set; } [DataMember] public string HostEmbeddedEditUrl { get; set; } [DataMember] public string HostEmbeddedViewUrl { get; set; } [DataMember] public string HostName { get; set; } [DataMember] public string HostNotes { get; set; } [DataMember] public string HostRestUrl { get; set; } [DataMember] public string HostViewUrl { get; set; } [DataMember] public string IrmPolicyDescription { get; set; } [DataMember] public string IrmPolicyTitle { get; set; } [DataMember] public string OwnerId { get; set; } [DataMember] public string PresenceProvider { get; set; } [DataMember] public string PresenceUserId { get; set; } [DataMember] public string PrivacyUrl { get; set; } [DataMember] public bool ProtectInClient { get; set; } [DataMember] public bool ReadOnly { get; set; } [DataMember] public bool RestrictedWebViewOnly { get; set; } [DataMember] public string SHA256 { get; set; } [DataMember] public string SignoutUrl { get; set; } [DataMember] public long Size { get; set; } [DataMember] public bool SupportsCoauth { get; set; } [DataMember] public bool SupportsCobalt { get; set; } [DataMember] public bool SupportsFolders { get; set; } [DataMember] public bool SupportsLocks { get; set; } [DataMember] public bool SupportsScenarioLinks { get; set; } [DataMember] public bool SupportsSecureStore { get; set; } [DataMember] public bool SupportsUpdate { get; set; } [DataMember] public string TenantId { get; set; } [DataMember] public string TermsOfUseUrl { get; set; } [DataMember] public string TimeZone { get; set; } [DataMember] public bool UserCanAttend { get; set; } [DataMember] public bool UserCanNotWriteRelative { get; set; } [DataMember] public bool UserCanPresent { get; set; } [DataMember] public bool UserCanWrite { get; set; } [DataMember] public string UserFriendlyName { get; set; } [DataMember] public string UserId { get; set; } [DataMember] public string Version { get; set; } [DataMember] public bool WebEditingDisabled { get; set; } } }

Actualización para el 13 de junio de 2014:

Usando Cobalt API es posible editar documentos de Word, aunque mi implementación está lejos de ser perfecta. Vayamos con lo básico. FSSHTTP requiere Shredded Storage, SharePoint implementado en la base de datos, pero después de mirar alrededor de Cobalt Assembly identifiqué la manera de crear un archivo triturado en el sistema de archivos ... Aquí están los fragmentos del código relevante, esta primera parte toma la palabra doc from c : / tmp / test.docx y se convierte en blobs triturados en c: / tmp / filestore y c: / tmp / wacupdate

DisposalEscrow disposal = new DisposalEscrow("temp1"); CobaltFilePartitionConfig content = new CobaltFilePartitionConfig(); content.IsNewFile = false; content.HostBlobStore = new FileSystemHostBlobStore("C://tmp//filestore//", "filestore", new FileSystemHostBlobStore.Config(), disposal, true, false); content.cellSchemaIsGenericFda = true; content.CellStorageConfig = new CellStorageConfig(); content.Schema = CobaltFilePartition.Schema.ShreddedCobalt; content.PartitionId = FilePartitionId.Content; CobaltFilePartitionConfig wacupdate = new CobaltFilePartitionConfig(); wacupdate.IsNewFile = false; wacupdate.HostBlobStore = new FileSystemHostBlobStore("C://tmp//wacstore//", "wacstore", new FileSystemHostBlobStore.Config(), disposal, true, false); wacupdate.cellSchemaIsGenericFda = false; wacupdate.CellStorageConfig = new CellStorageConfig(); wacupdate.Schema = CobaltFilePartition.Schema.ShreddedCobalt; wacupdate.PartitionId = FilePartitionId.WordWacUpdate; Dictionary<FilePartitionId, CobaltFilePartitionConfig> pd = new Dictionary<FilePartitionId, CobaltFilePartitionConfig>(); pd.Add(FilePartitionId.Content, content); pd.Add(FilePartitionId.WordWacUpdate, wacupdate); // custom locking store is my implementation of hostlockingstore CobaltFile cobaltFile = new CobaltFile(disposal, pd, new CustomHostLockingStore(), null); var src = FileAtom.FromExisting("C://tmp//Test.docx", disposal); Cobalt.Metrics o1; cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).SetStream(RootId.Default.Value, src, out o1); cobaltFile.GetCobaltFilePartition(FilePartitionId.Content).GetStream(RootId.Default.Value).Flush(); cobaltFile.CommitChanges();

Ahora que tienes el cobaltFile, puedes editar mi código wopi original con esto:

} else if (context.Request.HttpMethod.Equals(@"POST") && context.Request.Headers["X-WOPI-Override"].Equals("COBALT")) { Console.WriteLine(@"Got a cobalt request for the file"); var ms = new MemoryStream(); context.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); cobaltFile.CobaltEndpoint.ExecuteRequestBatch(requestBatch); cobaltFile.CommitChanges(); var response = requestBatch.SerializeOutputToProtocol(protocolVersion); context.Response.Headers.Add("X-WOPI-MachineName", "test"); context.Response.Headers.Add("X-WOPI-CorellationID", context.Request.Headers["X-WOPI-CorrelationID"]); context.Response.Headers.Add("request-id", context.Request.Headers["X-WOPI-CorrelationID"]); context.Response.ContentType = @"application/octet-stream"; context.Response.ContentLength64 = response.Length; response.CopyTo(context.Response.OutputStream); context.Response.Close(); }

y customlockingstore próximamente. Convirtiendo de triturado de nuevo a la palabra documento que aún no he hecho, pero creo que sé cómo

la actualización final: la solución completa está aquí:

https://github.com/thebitllc/WopiBasicEditor