博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
web office apps 在线预览实践
阅读量:7218 次
发布时间:2019-06-29

本文共 12141 字,大约阅读时间需要 40 分钟。

摘要

在一些项目中需要在线预览office文档,包括word,excel,ppt等。达到预览文档的目的有很多方法,可以看我之前总结,在线预览的n种方案:

,由于客户那里有安装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
GetFileInfo(string fileMD5); Task
GetSHA256Async(string url); string GetSHA256Async(byte[] buffer); }

接口实现

public class FileHelper : IFileHelper    {        FileBusiness _FileBusiness;        public FileHelper()        {            _FileBusiness = new FileBusiness();        }        ///         /// 获取文件信息        ///         ///         /// 
public async Task
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
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{    ///     ///     ///     public class WopiAppHelper    {        public WopiAppHelper() { }        ///         /// 获取office在线预览的链接        ///         ///         ///         /// 
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); } /// /// 根据文件扩展名获取预览url /// /// ///
private string FindUrlByExtenstion(string ext) { if (string.IsNullOrEmpty(ext)) { throw new ArgumentNullException("extension is empty."); } if (ext.IndexOf(".") >= 0) { //如果包含.则进行过滤 ext = ext.TrimStart('.'); } Dictionary
dic = new Dictionary
() { {
"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{    ///     /// Primary class for WOPI interface.  Supporting the 2 minimal API calls    /// requred for base level View    ///     public class FilesController : ApiController    {        IFileHelper _fileHelper;        HttpResponseMessage _response;        ///         /// Base constructor        ///         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");        }        ///         /// Required for WOPI interface - on initial view        ///         /// file name        /// 
public async Task
Get(string name) { return await _fileHelper.GetFileInfo(name); } ///
/// Required for WOPI interface - on initial view /// ///
file name ///
token that WOPI server will know ///
public async Task
Get(string name, string access_token) { return await _fileHelper.GetFileInfo(name); } ///
/// Required for View WOPI interface - returns stream of document. /// ///
file name ///
token that WOPI server will know ///
public async Task
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
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和文件名称,然后跳转到实际的预览界面。简单粗暴,不用每个应用都在实现上面的方法。

转载地址:http://rhtym.baihongyu.com/

你可能感兴趣的文章
mac 安装secureCRT
查看>>
/var/adm/wtmp文件太大该怎么办?
查看>>
反应器模式 vs 观察者模式
查看>>
Algernon's Noxious Emissions POJ1121 zoj1052
查看>>
iOS-数据持久化-对象归档
查看>>
iOS开发UI篇—程序启动原理和UIApplication
查看>>
MUI 里js动态添加数字输入框后,增加、减少按钮无效
查看>>
python pip 更换国内安装源(windows)
查看>>
结对编程2后篇
查看>>
oracle exp 和 imp 数据和表结构互相独立导出导入
查看>>
iphone-common-codes-ccteam源代码 CCNSPredicate.m
查看>>
这次项目中应该注意的问题和应该保持的好习惯
查看>>
python-数据结构化与保存
查看>>
LeetCode - 551. Student Attendance Record I
查看>>
Java用户线程和守护线程
查看>>
ClassLoader类加载机制&&JVM内存管理
查看>>
Caml语句 查询分配给当前用户及当前组
查看>>
记一次源码分析
查看>>
php版本引起的const问题
查看>>
js实现60s倒计时效果
查看>>