2013-06-12 12 views
5

Sto cercando di avere un sistema di gestione dei documenti in browser con ufficio. Ho trovato questa soluzione http://www.edrawsoft.com/officeviewer.php ma utilizza la copia client dell'ufficio.Posso utilizzare Office Web Apps Server

Vorrei utilizzare Office Web Apps, ma la mia domanda è ... Devo usarlo tramite SharePoint o altri prodotti Microsoft o posso semplicemente collegare un sito Web per utilizzare Office Web Apps nel browser per il mio documento sistema

risposta

10

È possibile scrivere il proprio server che implementa il protocollo WOPI, questo sosterrà PPTX/XSLX in modalità/edit, DOCX/PDF solo in modalità di visualizzazione. Il server WOPI è abbastanza semplice da implementare.

Per modificare documenti Word è necessario implementare cobalto o protocollo FSSHTTP/FSSHTTPB.

Inoltre, non dimenticare di licenza, Office Web Apps richiede che tutti gli utenti hanno una licenza valida ufficio.

Ecco un server di esempio .NET WOPI:

chiamata con:

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

come: http://WOPISERVER.HOST:2000/wopi/files/1.pptx

Si aprirà 1.pptx nella vostra 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; } 
    } 
} 

Aggiornamento per il 1 giugno 3 ° 2014:

Utilizzando API Cobalto è possibile modificare i documenti di Word, anche se la mia implementazione è ben lungi dall'essere perfetto. Andiamo con le basi. FSSHTTP richiede Shredded Storage, SharePoint implementato nel database, ma dopo aver guardato attorno al Cobalt Assembly ho identificato il modo di creare un file triturato sul file system ... Ecco i frammenti del codice rilevante, questa prima parte prende la parola doc da c : \ tmp \ test.docx e converte a chiazze triturati in c: \ tmp \ filestore e 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(); 

Ora che avete la cobaltFile è possibile modificare il mio codice wopi originale con questo:

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

     } 

e customlockingstore in arrivo. Conversione da tagliuzzato tornare al documento di parola non l'ho ancora fatto, ma credo di sapere come

l'aggiornamento finale - la soluzione completa è qui:

https://github.com/thebitllc/WopiBasicEditor

+0

Ho installato Office Web Apps su una casella virtuale su Windows Server 2012 e può colpire http: // localhost/hosting/discovery. Mi chiedo come testarlo ora – topcat3

+0

Questa guida è ciò di cui ho bisogno Credo in http://blogs.msdn.com/b/officedevdocs/archive/2013/03/20/introducing-wopi.aspx – topcat3

+0

Grazie mille . Se si può mettere una risposta qui http://stackoverflow.com/questions/16937990/how-to-use-ms-office-with-proprietary-java-back-end-document-system/17101144?noredirect=1#17101144 Ti assegnerò la grazia. La stessa risposta è adatta alle mie esigenze – topcat3

Problemi correlati