摘要

在使用office web apps实现office文档在线预览的时候,需要注意的地方。

web api

web api作为owa在线预览服务回调的接口,这里面核心代码片段如下:

using H5.Business;
using H5.Business.Log;
using H5.Enums;
using H5.Model;
using H5.Utility;
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
{ [RoutePrefix("api/wopi")]
public class FilesController : ApiController
{
IFileHelper _fileHelper;
HttpResponseMessage _response;
ILog _log;
/// <summary>
/// Base constructor
/// </summary>
public FilesController()
{
_fileHelper = new FileHelper();
_response = new HttpResponseMessage(HttpStatusCode.OK);
_log = new DbLog(LogSource.WebLog, AppNameType.office_view); }
/// <summary>
/// Required for WOPI interface - on initial view
/// </summary>
/// <param name="name">file name</param>
/// <returns></returns>
[HttpGet]
[Route("files/{name}")]
public CheckFileInfo Get(string name)
{
_log.Info(new LogModel { Content = "get fileinfo by name", Op = "get_fileinfo" });
return _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>
[HttpGet]
[Route("files/{name}")]
public CheckFileInfo Get(string name, string access_token)
{
_log.Info(new LogModel { Content = "get fileinfo by name&access_token", Op = "get_fileinfo" });
return _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>
[HttpGet]
[Route("files/{name}/contents")]
public HttpResponseMessage GetFile(string name, string access_token)
{
_log.Info(new LogModel { Content = "get file contents by name&access_token", Op = "get_fileinfo" });
return DownLoadFileStream(name, access_token);
}
/// <summary>
/// get owa file
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
[HttpGet]
[Route("files/{name}/contents")]
public HttpResponseMessage GetFile(string name)
{
_log.Info(new LogModel { Content = "get file contents by name", Op = "get_fileinfo" });
return DownLoadFileStream(name, string.Empty);
}
private HttpResponseMessage DownLoadFileStream(string name, string access_token)
{
try
{
_log.InfoAsync(new LogModel { Content = name + "_" + access_token, Itcode = string.Empty,
Op = "Office_View_GetFile" });
FastDFSFileBusiness fastDFSFileBusiness = new FastDFSFileBusiness();
var file = fastDFSFileBusiness.FindFastDFSFileByMD5(name);
if (file != null)
{
using (WebClient webClient = new WebClient())
{
byte[] buffer = webClient.DownloadData(file.Url);
_log.Info(new LogModel { Content = "download file success", Op = "get_fileinfo" });
MemoryStream stream = new MemoryStream(buffer);
_response.Content = new StreamContent(stream);
_response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
} }
return _response;
}
catch (Exception ex)
{
_log.Error(new LogModel { Ex = ex, Op = "Office_View_GetFile_err" });
_response.StatusCode = HttpStatusCode.InternalServerError;
var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(ex.Message ?? ""));
_response.Content = new StreamContent(stream);
return _response;
}
} }
}

需要注意:在获取文件流的时候,不要是否文件流,不然会造成有的文件预览正常,有的预览报错。

fileHelper用来获取文件信息,这里文件统一上传到文件服务器fastdfs上,通过下载文件流设置文件信息,在传递文件的时候,使用文件md5进行传递,避免因为文件名出现中文名或者空格造成编码问题。

构造owa预览地址

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>
/// <param name="fileUrl"></param>
/// <returns></returns>
public string GetDocumentLink(string fileMD5, string ext, string fileUrl)
{
string apiUrl = string.Format(ConfigManager.OWA_MY_VIEW_URL, fileMD5);
string findUrl = FindUrlByExtenstion(ext);
if (!string.IsNullOrEmpty(findUrl))
{
return string.Format("{0}{1}{2}&access_token={3}", ConfigManager.OWA_URL, findUrl, apiUrl, fileMD5);
}
else
{
return fileUrl;
} }
/// <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(".") >= )
{
//如果包含.则进行过滤
ext = ext.TrimStart('.').ToLower();
}
string url = string.Empty;
switch (ext)
{
case "ods":
case "xls":
case "xlsb":
case "xlsm":
case "xlsx":
url = "/x/_layouts/xlviewerinternal.aspx?WOPISrc=";
break;
case "one":
case "onetoc2":
url = "/o/onenoteframe.aspx?WOPISrc=";
break;
case "odp":
case "pot":
case "potm":
case "potx":
case "pps":
case "ppsm":
case "ppsx":
case "ppt":
case "pptm":
case "pptx":
url = "/p/PowerPointFrame.aspx?WOPISrc=";
break;
case "doc":
case "docm":
case "docx":
case "dot":
case "dotm":
case "dotx":
url = "/wv/wordviewerframe.aspx?WOPISrc=";
break;
default:
break;
}
return url;
}
}
}

总结

在开发中因为涉及到回调,最好找一个代理的工具,比如ngrok将机器代理到外网,方便调试开发。

[Office Web Apps]实现在线office文档预览的更多相关文章

  1. 在线文档预览方案-office web apps续篇

    上一篇在线文档预览方案-office web apps发布后收到很多网友的留言提问,所以准备再写一篇,一来介绍一下域控服务器安装,总结一下大家问的多的问题,二来宣传预览服务安装与技术支持的事情. 阅读 ...

  2. 在线文档预览方案-office web apps

    最近在做项目时,要在手机端实现在线文档预览的功能.于是百度了一下实现方案,大致是将文档转换成pdf,然后在通过插件实现预览.这些方案没有具体实现代码,也没有在线预览的地址,再加上项目时间紧迫.只能考虑 ...

  3. [转载]在线文档预览方案-Office Web Apps

    最近在做项目时,要在手机端实现在线文档预览的功能.于是百度了一下实现方案,大致是将文档转换成pdf,然后在通过插件实现预览.这些方案没有具体实现代码,也没有在线预览的地址,再加上项目时间紧迫.只能考虑 ...

  4. 微软office web apps 服务器搭建之在线文档预览(一)

    office web apps安装 系统要求为Windows Server 2012, 注意:转换文档需要两台服务器,一台为转换server,另外一台为域控server.(至于为什么要两台,这个请自行 ...

  5. 微软office web apps 服务器搭建之在线文档预览(二)

    上一篇文章已经介绍了整个安装过程了.只要在浏览器中输入文档转换server的ip,会自动跳转,出现如下页面. 那么就可以实现本地文档预览了,你可以试试.(注意:是本地哦,路径不要写错,类似“\\fil ...

  6. office web apps 部署-搭建office web apps服务器

    二.搭建office web apps服务器 相关文件可以去焰尾迭分享的百度网盘下载,下载地址:http://pan.baidu.com/s/1o6tCo8y#path=%252Foffice%252 ...

  7. 使用OpenOffice实现文档预览

    概述 使用OpenOffice将 office文档转为pdf,然后再将pdf转为图片,实现文档预览的功能. 依赖组件 OpenOffice.org或者LibreOffice JODConverter ...

  8. 秒级接入、效果满分的文档预览方案——COS文档预览

    一.导语 ​ 说起 Microsoft Office 办公三件套,想必大家都不会陌生,社畜日常的工作或者生活中,多多少少遇到过这种情况: 本地创建的文档换一台电脑打开,就出现了字体丢失.排版混乱的情况 ...

  9. 一文带你玩转对象存储COS文档预览

    随着"互联网+"的发展,各行各业纷纷"去纸化",商务合同.会议纪要.组织公文.商品图片.培训视频.学习课件.随堂讲义等电子文档无处不在.而要查看文档一般需要先下 ...

随机推荐

  1. android getWidth()和getMeasuredWidth()方法的区别

    getWidth() Return the width of the your view. Returns The width of your view, in pixels. 源代码: public ...

  2. inux系统用户名和全名有什么区别

    问:linux系统安装完毕,进入系统,创建用户的时候,要填入用户名和全名,请问用户名和全名有什么区别,登录的时候,是用户名还是全名? ================================= ...

  3. QTP设置共享对象库

    第一步:把需要加到共享对象库中的各个用例脚本的对象库,分别导出成.tsr文件. 操作方法:先用QTP打开已经录制完毕的脚本后,选择Resources-->Object Repository.然后 ...

  4. asp.net动态增加服务器端控件并提交表单

    为什么要用原生的呢? 1.目的 原生出现浏览器兼容性问题 极少,不用测试多浏览兼容性 .需要考虑到市面上的其他垃圾浏览器. 2.性能不好 如果不考虑第一条 你可以换一种方式 直接上代码 .aspx页面 ...

  5. The project cannot be built until its prerequisite base-service is built. Cleaning and building all projects is recommended

    参考网址:http://chiangfai.iteye.com/blog/2223661,谢谢! 果然如文中所述,close,重新编译即可!

  6. springmvc接收jquery提交的数组数据

    var selectedUsers = $('#users').tagbox('getValues'); if (selectedUsers.length > 0) { $.post(appPa ...

  7. 解决方案:centos运行shell脚本时报“$'\r': 未找到命令”

    =============================================== 2018/9/12_第1次修改                       ccb_warlock == ...

  8. .gitkeep

    看一个开源项目中有个.gitkeep文件,不知道是干嘛用的查询知道 git是不允许提交一个空的目录到版本库上的,可以在空的文件夹里面建立一个.gitkeep文件,然后提交去即可. 其实在git中 .g ...

  9. GeoHash解析及java实现

    GeoHash解析请参考这里: http://www.open-open.com/lib/view/open1417940079964.html java实现GeoHash,代码已注释. import ...

  10. .NetCore中使用ExceptionLess记录Polly中的操作异常日志

    结合上一篇文章我写了一个demo测试下 重试2次 _polly.PollyRetry<Exception>(()=>_demoQuery.GetTestAOPAsync(), ); ...