web office apps 在线预览实践
摘要
在一些項目中需要在線預覽office文檔,包括word,excel,ppt等。達到預覽文檔的目的有很多方法,可以看我之前總結,在線預覽的n種方案:
[Asp.net]常見word,excel,ppt,pdf在線預覽方案,有圖有真相,總有一款適合你!
,由于客戶那里有安裝web office apps服務,調用該服務就可以實現文檔的在線預覽,所以在項目中就采用了這種方式,下面列出了實踐步驟。
步驟
定義文件信息:
?該信息用來調用web office apps服務回調查找文件信息時用到。
public class CheckFileInfo{public CheckFileInfo();public string BaseFileName { get; set; }public string OwnerId { get; set; }public long Size { get; set; }public string SHA256 { get; set; }public string Version { get; set; }}獲取文件信息的接口
public interface IFileHelper{Task<CheckFileInfo> GetFileInfo(string fileMD5);Task<string> GetSHA256Async(string url);string GetSHA256Async(byte[] buffer);}接口實現
public class FileHelper : IFileHelper{FileBusiness _FileBusiness;public FileHelper(){_FileBusiness = new FileBusiness();}/// <summary>/// 獲取文件信息/// </summary>/// <param name="filePath"></param>/// <returns></returns>public async Task<CheckFileInfo> GetFileInfo(string fileMD5){var fileInfo = _FileBusiness.FindFileByMD5(fileMD5);if (fileInfo != null){var rv = new CheckFileInfo{Version = DateTime.Now.ToString("s"),Size = Convert.ToInt64(fileInfo.FileSize),OwnerId = fileInfo.Itcode,BaseFileName = fileInfo.FileName,SHA256 = fileInfo.SHA256};if (string.IsNullOrEmpty(fileInfo.SHA256)){rv.SHA256 = await GetSHA256Async(fileInfo.Url);fileInfo.SHA256 = rv.SHA256;await _FileBusiness.UpldateAsyncByUrl(fileInfo);}return rv;}else{return null;}}public async Task<string> GetSHA256Async(string url){string sha256 = string.Empty;using (var sha = SHA256.Create()){WebClient webClient = new WebClient();byte[] buffer = await webClient.DownloadDataTaskAsync(url);byte[] checksum = sha.ComputeHash(buffer);sha256 = Convert.ToBase64String(checksum);}return sha256;}public string GetSHA256Async(byte[] buffer){string sha256 = string.Empty;using (var sha = SHA256.Create()){WebClient webClient = new WebClient();byte[] checksum = sha.ComputeHash(buffer);sha256 = Convert.ToBase64String(checksum);}return sha256;}}這里用到了文件分布式存儲,要預覽的放在了另外的文件服務器上面,所以這里使用webclient下載,獲取到文件信息,保存在數據庫中,如果存在則直接返回。當然,你可以使用FileStream來讀取文件的響應信息。
獲取文件預覽的地址
根據web office apps服務的地址,文件擴展名獲取預覽的link
using H5.Utility; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web; using System.Xml.Serialization;namespace WebSite.OfficeViewerService.Helpers {/// <summary>/// /// </summary>public class WopiAppHelper{public WopiAppHelper() { }/// <summary>/// 獲取office在線預覽的鏈接/// </summary>/// <param name="fileMD5"></param>/// <param name="ext"></param>/// <returns></returns>public string GetDocumentLink(string fileMD5, string ext){string apiUrl = string.Format(ConfigManager.OWA_MY_VIEW_URL, fileMD5);return string.Format("{0}{1}{2}&access_token={3}", ConfigManager.OWA_URL, FindUrlByExtenstion(ext), apiUrl, fileMD5);}/// <summary>/// 根據文件擴展名獲取預覽url/// </summary>/// <param name="ext"></param>/// <returns></returns>private string FindUrlByExtenstion(string ext){if (string.IsNullOrEmpty(ext)){throw new ArgumentNullException("extension is empty.");}if (ext.IndexOf(".") >= 0){//如果包含.則進行過濾ext = ext.TrimStart('.');}Dictionary<string, string> dic = new Dictionary<string, string>() { {"ods","/x/_layouts/xlviewerinternal.aspx?WOPISrc="},{"xls", "/x/_layouts/xlviewerinternal.aspx?WOPISrc="},{"xlsb", "/x/_layouts/xlviewerinternal.aspx?WOPISrc="},{"xlsm", "/x/_layouts/xlviewerinternal.aspx?WOPISrc="},{"xlsx", "/x/_layouts/xlviewerinternal.aspx?WOPISrc="},{"one", "/o/onenoteframe.aspx?WOPISrc="},{"onetoc2", "/o/onenoteframe.aspx?WOPISrc="},{"odp", "/p/PowerPointFrame.aspx?WOPISrc="},{"pot", "/p/PowerPointFrame.aspx?WOPISrc="},{"potm", "/p/PowerPointFrame.aspx?WOPISrc="},{"potx", "/p/PowerPointFrame.aspx?WOPISrc="},{"pps", "/p/PowerPointFrame.aspx?WOPISrc="},{"ppsm", "/p/PowerPointFrame.aspx?WOPISrc="},{"ppsx", "/p/PowerPointFrame.aspx?WOPISrc="},{"ppt", "/p/PowerPointFrame.aspx?WOPISrc="},{"pptm", "/p/PowerPointFrame.aspx?WOPISrc="},{"pptx", "/p/PowerPointFrame.aspx?WOPISrc="},{"doc", "/wv/wordviewerframe.aspx?WOPISrc="},{"docm", "/wv/wordviewerframe.aspx?WOPISrc="},{"docx", "/wv/wordviewerframe.aspx?WOPISrc="},{"dot", "/wv/wordviewerframe.aspx?WOPISrc="},{"dotm", "/wv/wordviewerframe.aspx?WOPISrc="},{"dotx", "/wv/wordviewerframe.aspx?WOPISrc="},{"pdf", "/wv/wordviewerframe.aspx?WOPISrc="}};return dic[ext];}} }web office apps 預覽接口回調使用的api時,需要注意盡量傳遞id之類,如果傳遞name,文件名涉及到了中文,會有編碼的問題,所以我這里傳遞的是文件的md5值。
using Newtonsoft.Json; using System; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Web; using System.Web.Hosting; using System.Web.Http; using WebSite.OfficeViewerService.Helpers; namespace WebSite.OfficeViewerService.Controllers.Api {/// <summary>/// Primary class for WOPI interface. Supporting the 2 minimal API calls/// requred for base level View/// </summary>public class FilesController : ApiController{IFileHelper _fileHelper;HttpResponseMessage _response;/// <summary>/// Base constructor/// </summary>public FilesController(){_fileHelper = new FileHelper();_response = new HttpResponseMessage(HttpStatusCode.Accepted);//允許哪些url可以跨域請求到本域_response.Headers.Add("Access-Control-Allow-Origin", "*");//允許的請求方法,一般是GET,POST,PUT,DELETE,OPTIONS_response.Headers.Add("Access-Control-Allow-Methods", "POST");//允許哪些請求頭可以跨域_response.Headers.Add("Access-Control-Allow-Headers", "x-requested-with,content-type");}/// <summary>/// Required for WOPI interface - on initial view/// </summary>/// <param name="name">file name</param>/// <returns></returns> public async Task<CheckFileInfo> Get(string name){return await _fileHelper.GetFileInfo(name);}/// <summary>/// Required for WOPI interface - on initial view/// </summary>/// <param name="name">file name</param>/// <param name="access_token">token that WOPI server will know</param>/// <returns></returns>public async Task<CheckFileInfo> Get(string name, string access_token){return await _fileHelper.GetFileInfo(name);}/// <summary>/// Required for View WOPI interface - returns stream of document./// </summary>/// <param name="name">file name</param>/// <param name="access_token">token that WOPI server will know</param>/// <returns></returns>public async Task<HttpResponseMessage> GetFile(string name, string access_token){try{_response.StatusCode = HttpStatusCode.OK;FileBusiness FileBusiness = new FileBusiness();var file = FileBusiness.FindFileByMD5(name);if (file != null){WebClient webClient = new WebClient();byte[] buffer = await webClient.DownloadDataTaskAsync(file.Url);MemoryStream stream = new MemoryStream(buffer);_response.Content = new StreamContent(stream);_response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");}return _response;}catch (Exception ex){_response.StatusCode = HttpStatusCode.InternalServerError;var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(ex.Message ?? ""));_response.Content = new StreamContent(stream);return _response;}}} }路由配置
using System; using System.Collections.Generic; using System.Linq; using System.Web.Http;namespace WebSite.OfficeViewerService {public static class WebApiConfig{public static void Register(HttpConfiguration config){// Web API 配置和服務// Web API 路由 config.Routes.MapHttpRoute(name: "Contents",routeTemplate: "api/wopi/files/{name}/contents",defaults: new { controller = "files", action = "GetFile" });config.Routes.MapHttpRoute(name: "FileInfo",routeTemplate: "api/wopi/files/{name}",defaults: new { controller = "Files", action = "Get" });config.Routes.MapHttpRoute(name: "DefaultApi",routeTemplate: "api/{controller}/{id}",defaults: new { controller = "Files", id = RouteParameter.Optional });}} } using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; using System.Web; using System.Web.Configuration; using System.Web.Hosting; using System.Web.Mvc; using WebSite.OfficeViewerService.Helpers;namespace WebSite.OfficeViewerService.Controllers {public class HomeController : Controller{IFileHelper _fileHelper = new FileHelper();public ActionResult Index(){return View();}public async Task<ActionResult> Viewer(string url, string name){string itcode = string.Empty;try{if (string.IsNullOrEmpty(url)){throw new ArgumentNullException("Sorry,Url is errr,the file is not found");}string fileExt = url.Substring(url.LastIndexOf('.'));WopiAppHelper wopiHelper = new WopiAppHelper();FileBusiness FileBusiness = new FileBusiness();var file = FileBusiness.FindFileByUrl(url);string fileMD5 = string.Empty;if (file == null){WebClient webClient = new WebClient();byte[] buffer = await webClient.DownloadDataTaskAsync(url);fileMD5 = MD5Helper.GetMD5FromFile(buffer);string sha256 = _fileHelper.GetSHA256Async(buffer);await fastDFSFileBusiness.SaveAsync(new FastDFSFile{Dt = DateTime.Now,FileMd5 = fileMD5,FileName = name,FileSize = buffer.Length,Itcode = itcode,Url = url,SHA256 = sha256});}else{fileMD5 = file.FileMd5;}var result = wopiHelper.GetDocumentLink(fileMD5, fileExt);return Redirect(result);}catch (Exception ex){ViewBag.Message = ex.Message;}return View();}} }
包裝預覽接口,其它應用通過傳遞文件的url和文件名稱,然后跳轉到實際的預覽界面。簡單粗暴,不用每個應用都在實現上面的方法。
轉載于:https://www.cnblogs.com/wolf-sun/p/6646309.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的web office apps 在线预览实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用supervisor启动hbase
- 下一篇: java多线程 -- ReadWrite