继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

web office apps 在线预览实践

慕田峪是谁我也不认识
关注TA
已关注
手记 271
粉丝 40
获赞 95

摘要

在一些项目中需要在线预览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和文件名称,然后跳转到实际的预览界面。简单粗暴,不用每个应用都在实现上面的方法。

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP