zoukankan      html  css  js  c++  java
  • 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和文件名称,然后跳转到实际的预览界面。简单粗暴,不用每个应用都在实现上面的方法。

  • 相关阅读:
    <trim>: prefix+prefixOverrides+suffix+suffixOverrides
    时间js
    form表单中name和id区别
    SQL 递归
    表单中Readonly和Disabled的区别
    jquery select取值,赋值操作
    ie11
    mongodb 学习资料
    H5 限制input只能输入数字
    http头部解释
  • 原文地址:https://www.cnblogs.com/wolf-sun/p/6646309.html
Copyright © 2011-2022 走看看