ASP.NET Core 2.0集成Office Online Server(OWAS)實現辦公文檔的在線預覽與編輯(支持wordexcelpptpdf等格式)

發布日期:2019-10-17

Office Online ServerSHIWEIRUANKAIFADEYITAOJIYUOfficeSHIXIANZAIXIANWENDANGYULANBIANJIDEJISHUKUANGJIA(ZHICHIDANGQIANZHULIUDELIULANQI,QIELIULANQISHANGWUXUANZHUANGRENHECHAJIAN,ZHICHIword、excel、ppt、pdfDENGWENDANGGESHI),QIKEHUDUANTONGGUOWebApiFANGSHIKEJICHENGDAOZIYIDEYINGYONGZHONG,ZHICHIJava、C#DENGYUYAN。Office Online ServerYUANMINGWEI:Office Web Apps Server(JIANCHENGOWAS)。YINWEIJINQIYOUASP.NET Core 2.0DEXIANGMUZHONGYAOSHIXIANZAIXIANWENDANGYULANYUBIANJI,JIUXIANGZHUJIANGOffice Online ServerJICHENGDAOXIANGMUZHONGLAI,TONGGUOWANGSHANGCHAZHAO,FAXIANDABUFENDEKEHUDUANDESHIXIANDOUSHIJIYUASP.NETDE,ERWOZAISHIXIANDAOASP.NET Core 2.0DEGUOCHENGZHONGYEYUDAOLEBUSHAODEWENTI,SUOYIJIUYOULEJINTIANZHEPIANWENZHANG。

?

安裝Office Online Server

WEIRUANDEDONGXIZAIANZHUANGSHANGDOUSHIHENJIANDANDE,XIAZAIANZHUANGBAOYILU”XIAYIBU“JIUKEWANCHENG。YEKECANKAORUXIASHUOMINGLAIJINXINGANZHUANG:http://docs.microsoft.com/zh-cn/officeonlineserver/deploy-office-online-server

WANCHENGANZHUANGHOUHUIZAIFUWUQISHANGDEIISSHANGZIDONGCHUANGJIANLIANGGEWANGZHAN,FENBIEWEI:HTTP80、HTTP809。QIZHONGHTTP80ZHANBANGDING80、443DUANKOU,HTTP809ZHANBANGDING809、810DUANKOU。

?

業務關系

1、Office Online ServerFUWUDUAN(WOPI Server),ANZHUANGZAIFUWUQISHANGYONGYUSHOULILAIZIKEHUDUANDEYULAN、BIANJIQINGQIUDENG。FUWUDUANHENCHINEICUNDE,DANJIYIDINGBUNENGDIYU8GNEICUN。

2、Office Online ServerKEHUDUAN(WOPI Client),ZHELIYINWEIJICHENGZAILEZIYIDEXIANGMUZHONG,SUOYIOffice Online ServerKEHUDUANYEJIUSHIZIYIDEXIANGMUZHONGDEZIXITONG。

YONGHUTONGGUOXIANGMUZHONGDEYEWUXITONGQINGQIUKEHUDUANBINGFAQIDUIMOUYIWENDANGDEYULANHUOBIANJIQINGQIU,KEHUDUANJIESHOUQINGQIUHOUZAITONGGUODIAOYONGFUWUDUANDEWebApiWANCHENGYIXILIEYUEDINGTONGXUNHOU,FUWUDUANZAIXIANSHUCHUWENDANGBINGWANCHENGYULANYUBIANJIGONGNENG。

?

實現原理

KETONGGUORUXIATU(TUPIANLAIZIHULIANWANG)NENGQINGXIDEKANCHULIULANQI、Office Online ServerFUWUDUAN、Office Online ServerKEHUDUANZHIJIANDEJIAOHUSHUNXUYUGUANXI。ZAIZHEGUOCHENGZHONG,Office Online ServerKEHUDUANXUZIXINGSHENGCHENGTokenJISHENFENYANZHENG,ZHEYESHIWEIBAOZHANGOffice Online ServerKEHUDUANDEANQUANSHOUDUAN。

?

實現代碼

KEHUDUANBIANXIELANJIEQI,LANJIEQIZHONGZHUYAOJIESHOULAIZIFUWUDUANDEQINGQIU,BINGGENJUFUWUDUANDEQINGQIULEIXINGZUOCHUXIANGYINGDONGZUO,QINGQIULEIXINGBAOHANRUXIAJIZHONG:CheckFileInfo、GetFile、Lock、GetLock、RefreshLock、Unlock、UnlockAndRelock、PutFile、PutRelativeFile、RenameFile、DeleteFile、PutUserInfoDENG。JUTIDAIMARUXIA:

1 using Microsoft.AspNetCore.Http; 2 using Newtonsoft.Json; 3 using System; 4 using System.Collections.Generic; 5 using System.IO; 6 using System.Linq; 7 using System.Text; 8 using System.Threading; 9 using System.Threading.Tasks; 10 using System.Web; 11?//編寫一個處理WOPI請求的客戶端攔截器 12 namespace Lezhima.Wopi.Base 13 { 14 public class ContentProvider 15 { 16 //聲明請求代理 17 private readonly RequestDelegate _nextDelegate; 18 19 20 public ContentProvider(RequestDelegate nextDelegate) 21 { 22 _nextDelegate = nextDelegate; 23 } 24 25 26 //拉截并接受所有請求 27 public async Task Invoke(HttpContext context) 28 { 29 //判斷是否為來自WOPI服務端的請求 30 if (context.Request.Path.ToString().ToLower().IndexOf("files") >= 0) 31 { 32 WopiRequest requestData = ParseRequest(context.Request); 33 34 switch (requestData.Type) 35 { 36 //獲取文件信息 37 case RequestType.CheckFileInfo: 38 await HandleCheckFileInfoRequest(context, requestData); 39 break; 40 41 //嘗試解鎖并重新鎖定 42 case RequestType.UnlockAndRelock: 43 HandleUnlockAndRelockRequest(context, requestData); 44 break; 45 46 //獲取文件 47 case RequestType.GetFile: 48 await HandleGetFileRequest(context, requestData); 49 break; 50 51 //寫入文件 52 case RequestType.PutFile: 53 await HandlePutFileRequest(context, requestData); 54 break; 55 56 default: 57 ReturnServerError(context.Response); 58 break; 59 } 60 } 61 else 62 { 63 await _nextDelegate.Invoke(context); 64 } 65 } 66 67 68 69 70 /// <summary> 71 /// 接受并處理獲取文件信息的請求 72 /// </summary> 73 /// <remarks> 74 /// </remarks> 75 private async Task HandleCheckFileInfoRequest(HttpContext context, WopiRequest requestData) 76 { 77 //判斷是否有合法token 78 if (!ValidateAccess(requestData, writeAccessRequired: false)) 79 { 80 ReturnInvalidToken(context.Response); 81 return; 82 } 83 //獲取文件 84 IFileStorage storage = FileStorageFactory.CreateFileStorage(); 85 DateTime? lastModifiedTime = DateTime.Now; 86 try 87 { 88 CheckFileInfoResponse responseData = new CheckFileInfoResponse() 89 { 90 //獲取文件名稱 91 BaseFileName = Path.GetFileName(requestData.Id), 92 Size = Convert.ToInt32(size), 93 Version = Convert.ToDateTime((DateTime)lastModifiedTime).ToFileTimeUtc().ToString(), 94 SupportsLocks = true, 95 SupportsUpdate = true, 96 UserCanNotWriteRelative = true, 97 98 ReadOnly = false, 99 UserCanWrite = true100 };101 102 var jsonString = JsonConvert.SerializeObject(responseData);103 104 ReturnSuccess(context.Response);105 106 await context.Response.WriteAsync(jsonString);107 108 }109 catch (UnauthorizedAccessException ex)110 {111 ReturnFileUnknown(context.Response);112 }113 }114 115 /// <summary>116 /// 接受并處理獲取文件的請求117 /// </summary>118 /// <remarks>119 /// </remarks>120 private async Task HandleGetFileRequest(HttpContext context, WopiRequest requestData)121 {122 //判斷是否有合法token 123 if (!ValidateAccess(requestData, writeAccessRequired: false))124 {125 ReturnInvalidToken(context.Response);126 return;127 }128 129 130 //獲取文件 131 var stream = await storage.GetFile(requestData.FileId);132 133 if (null == stream)134 {135 ReturnFileUnknown(context.Response);136 return;137 }138 139 try140 {141 int i = 0;142 List<byte> bytes = new List<byte>();143 do144 {145 byte[] buffer = new byte[1024];146 i = stream.Read(buffer, 0, 1024);147 if (i > 0)148 {149 byte[] data = new byte[i];150 Array.Copy(buffer, data, i);151 bytes.AddRange(data);152 }153 }154 while (i > 0);155 156 157 ReturnSuccess(context.Response);158 await context.Response.Body.WriteAsync(bytes, bytes.Count);159 160 }161 catch (UnauthorizedAccessException)162 {163 ReturnFileUnknown(context.Response);164 }165 catch (FileNotFoundException ex)166 {167 ReturnFileUnknown(context.Response);168 }169 170 }171 172 /// <summary>173 /// 接受并處理寫入文件的請求174 /// </summary>175 /// <remarks>176 /// </remarks>177 private async Task HandlePutFileRequest(HttpContext context, WopiRequest requestData)178 {179 //判斷是否有合法token 180 if (!ValidateAccess(requestData, writeAccessRequired: true))181 {182 ReturnInvalidToken(context.Response);183 return;184 }185 186 try187 {188 //寫入文件189 int result = await storage.UploadFile(requestData.FileId, context.Request.Body);190 if (result != 0)191 {192 ReturnServerError(context.Response);193 return;194 }195 196 ReturnSuccess(context.Response);197 }198 catch (UnauthorizedAccessException)199 {200 ReturnFileUnknown(context.Response);201 }202 catch (IOException ex)203 {204 ReturnServerError(context.Response);205 }206 }207 208 209 210 private static void ReturnServerError(HttpResponse response)211 {212 ReturnStatus(response, 500, "Server Error");213 }214 215 }216 }

?

LANJIEQIYOULEHOU,ZAIDAOStartup.csWENJIANZHONGZHURUJIKE,JUTIDAIMARUXIA:

1 public void Configure(IApplicationBuilder app, IHostingEnvironment env) 2 { 3 if (env.IsDevelopment()) 4 { 5 app.UseDeveloperExceptionPage(); 6 app.UseBrowserLink(); 7 } 8 else 9 { 10 app.UseExceptionHandler("/Home/Error"); 11 } 12 13 app.UseStaticFiles(); 14 app.UseAuthentication(); 15 16 //注入中間件攔截器,這是將咱們寫的那個Wopi客戶端攔截器注入進來 17 app.UseMiddleware<ContentProvider>(); 18 19 app.UseMvc(routes => 20 { 21 routes.MapRoute( 22 name: "default", 23 template: "{controller=Home}/{action=Index}/{name?}"); 24 }); 25 }

?

ZHIZHI,ZHENGGEJIYUOffice Online ServerJISHUKUANGJIAZAIASP.NET CoreSHANGDEWENDANGYULAN/BIANJIGONGNENGJIUWANCHENGLE。GOUJIANDANDEBA!!

?

總結

1、Office Online ServerFUWUDUANJIANYIZAIFUWUQISHANGDULIBUSHU,BUYAOYUQITAYEWUXITONGHUNHEBUSHU。YINWEIZHEHUOSHIZAISHITAINENGCHINEICUNLE,QINEIBUYONGLEWebCachedHUANCUNJIZHISHIDAOZHINEICUNZENGGAODEYIGEYINSU。

2、Office Online ServerHENDUOZILIAOSHANGYAOQIUYAOYONGADYU,DANWOSHIJIZAIJICHENGKEHUDUANSHIMEIYOUSHEJIDAOZHEKUAI,YEJIUSHISHUOFUWUDUANSHIKAIFANGDE,DANKEHUDUANSHITONGGUOZIXINGBANFADETokenYUYANZHENGLAIBAOZHANGANQUANDE。

3、LIYONGBIANXIEZHONGJIANJIANLANJIEQI,BINGZAIStartup.csWENJIANZHONGZHURUZHONGJIANJIANDEFANGSHILAIJIEHUOLAIZIWOPIFUWUDUANDESUOYOUQINGQIU,BINGDUIBUTONGDEQINGQIULEIXINGZUOCHUXIANGYINGDECHULI。

?