如何整合Office Web Apps至自己开发的信息系统整合

4479人阅读
ASP.NET(99)
Office(20)
其实网上有关office&web&app的整合已经有相关的文章了,典型的是&和,微软官网也有相应的。
这里在简单描述一下原理吧:office&web&apps(owas)扮演者一个客服端,它会访问我们asp.net&站点的文件然后呈现出来。而我们常用的API主要有如下3个:
GET api/wopi/files/{name}?access_token={access_token} &&&
GET api/wopi/files/{name}/contents?access_token={access_token} && &
POST api/wopi/files/{name}/contents?access_token={access_token}
至于每个API做什么&这里就不多说,第一个是owas&检查文件,传递的信息是json数据格式,第二个是owas获取文件流,第三个是owas&post的文件流(保存修改文件)。首先我们来看看第一个API的实现:
[Route(&files/{name}/&)]
public CheckFileInfo GetFileInfo(string name, string access_token)
Validate(name, access_token);
var fileInfo = _fileHelper.GetFileInfo(name);
bool updateEnabled =
if (bool.TryParse(WebConfigurationManager.AppSettings[&updateEnabled&].ToString(), out updateEnabled))
fileInfo.SupportsUpdate = updateE
fileInfo.UserCanWrite = updateE
fileInfo.SupportsLocks = updateE
return fileI
}这里的 Validate(name, access_token)&方法主要是验证请求的文件名name与参数access_token是否一致,主要是验证是否是非法访问,返回一个CheckFileInfo对象,CheckFileInfo的定义如下:
public class CheckFileInfo
public CheckFileInfo()
this.SupportsUpdate =
this.UserCanWrite =
public string BaseFileName { }
public string OwnerId { }
public long Size { } //in bytes
public string SHA256 { } //SHA256: A 256 bit SHA-2-encoded [FIPS180-2] hash of the file contents
public string Version { }
//changes when file changes.
public bool SupportsUpdate { }
public bool UserCanWrite { }
public bool SupportsLocks { }
现在在来看看第二个api的实现,主要返回对应文件的数据流:
[Route(&files/{name}/contents&)]
public HttpResponseMessage Get(string name, string access_token)
Validate(name, access_token);
var file = HostingEnvironment.MapPath(&~/App_Data/& + name);
var responseMessage = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(file, FileMode.Open, FileAccess.Read);
responseMessage.Content = new StreamContent(stream);
responseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue(&application/octet-stream&);
return responseM
catch (Exception ex)
var errorResponseMessage = new HttpResponseMessage(HttpStatusCode.InternalServerError);
var stream = new MemoryStream(UTF8Encoding.Default.GetBytes(ex.Message ?? &&));
errorResponseMessage.Content = new StreamContent(stream);
return errorResponseM
而第三个api是将返回的数据流保存到物理文件:
[Route(&files/{name}/contents&)]
public async void Post(string name, [FromUri] string access_token)
var body = await Request.Content.ReadAsByteArrayAsync();
var appData = HostingEnvironment.MapPath(&~/App_Data/&);
var fileExt = name.Substring(name.LastIndexOf('.') + 1);
var outFile = bine(appData,name);
File.WriteAllBytes(outFile, body);
现在我们再来看看如何请求owas,也就是对应的url是怎么产生的。例如我的owas&server是,那么我们在配置好owas后就可以访问/hosting/discovery 如图:
&这里我们以excel为例&&大家看到上面有view、edit、mobileview三个action,这里的app是一个excel,我们知道我们物理文件的后缀找到相应的app,在根据我们系统的配置采用edit还是view&action,如果是pdf&我们只能采用对应的view,如果请求是mobile发起的话, 那么我们只能用mobileview。&找到相应的action后我们就获取到对应的urlsrc属性,这里我们实际需要的url地址是 /x/_layouts/xlviewerinternal.aspx这个东东。那么获取这个url的代码如下:
public class LinkController : ApiController
/// &summary&
/// Provides a link that can be used to Open a document in the relative viewer
/// from the Office Web Apps server
/// &/summary&
/// &param name=&fileRequest&&indicates the request type&/param&
/// &returns&A link usable for HREF&/returns&
public Link GetLink([FromUri] FileRequest fileRequest)
if (ModelState.IsValid)
var xml = WebConfigurationManager.AppSettings[&appDiscoveryXml&];
var wopiServer = WebConfigurationManager.AppSettings[&appWopiServer&];
bool updateEnabled =
bool.TryParse(WebConfigurationManager.AppSettings[&updateEnabled&], out updateEnabled);
WopiAppHelper wopiHelper = new WopiAppHelper(HostingEnvironment.MapPath(xml), updateEnabled);
var result = wopiHelper.GetDocumentLink(wopiServer + fileRequest.name);
var rv = new Link
Url = result
throw new ApplicationException(&Invalid ModelState&);
public class WopiAppHelper
string _discoveryF
bool _updateEnabled =
WopiHost.wopidiscovery _wopiD
public WopiAppHelper(string discoveryXml)
_discoveryFile = discoveryX
using (StreamReader file = new StreamReader(discoveryXml))
XmlSerializer reader = new XmlSerializer(typeof(WopiHost.wopidiscovery));
var wopiDiscovery = reader.Deserialize(file) as WopiHost.
_wopiDiscovery = wopiD
public WopiAppHelper(string discoveryXml, bool updateEnabled)
: this(discoveryXml)
_updateEnabled = updateE
public WopiHost.wopidiscoveryNetzoneApp GetZone(string AppName)
var rv = _wopiDiscovery.netzone.app.Where(c =& c.name == AppName).FirstOrDefault();
public string GetDocumentLink(string wopiHostandFile)
var fileName = wopiHostandFile.Substring(wopiHostandFile.LastIndexOf('/') + 1);
var accessToken = GetToken(fileName);
var fileExt = fileName.Substring(fileName.LastIndexOf('.') + 1);
var netzoneApp = _wopiDiscovery.netzone.app.AsEnumerable()
.Where(c =& c.action.Where(d =& d.ext == fileExt).Count() & 0);
var appName = netzoneApp.FirstOrDefault();
if (null == appName) throw new ArgumentException(&invalid file extension & + fileExt);
var rv = GetDocumentLink(appName.name, fileExt, wopiHostandFile, accessToken);
string GetToken(string fileName)
KeyGen keyGen = new KeyGen();
var rv = keyGen.GetHash(fileName);
return HttpUtility.UrlEncode(rv);
const string s_WopiHostFormat = &{0}?WOPISrc={1}&access_token={2}&;
const string s_WopiHostFormatPdf = &{0}?PdfMode=1&WOPISrc={1}&access_token={2}&;
public string GetDocumentLink(string appName, string fileExtension, string wopiHostAndFile, string accessToken)
var wopiHostUrlsafe = HttpUtility.UrlEncode(wopiHostAndFile.Replace(& &, &%20&));
var appStuff = _wopiDiscovery.netzone.app.Where(c =& c.name == appName).FirstOrDefault();
if (null == appStuff)
throw new ApplicationException(&Can't locate App: & + appName);
var action = _updateEnabled ? &edit& : &view&;
if (appName.Equals(&WordPdf&))
action = &view&;
if (HttpContext.Current.Request.Browser.IsMobileDevice)
action = &mobileView&;
var appAction = appStuff.action.Where(c =& c.ext == fileExtension && c.name == action).FirstOrDefault();
if (null == appAction)
throw new ApplicationException(&Can't locate UrlSrc for : & + appName);
var endPoint = appAction.urlsrc.IndexOf('?');
var endAction = appAction.urlsrc.Substring(0, endPoint);
string fullPath =
////HACK: for PDF now just append WordPdf option...
if (fileExtension.Contains(&pdf&))
fullPath = string.Format( s_WopiHostFormatPdf, endAction, wopiHostUrlsafe, accessToken);
fullPath = string.Format(s_WopiHostFormat, endAction,
wopiHostUrlsafe, accessToken);
return fullP
相应的配置如下:
appDiscoveryXml&是我们owas(/hosting/discovery)产生的数据文件,appWopiServer&表示我们的owas将要访问interface地址。updateEnabled主要是表示owas是否可以修改我们的文档,如果是true 我们上面的action 采用edit,为false采用view。appHmacKey只是数据加密的一个key。生成的url如图:
注意这里的配置是updateEnabled=true&表示owas是可以编辑文件的,如图:
当我们点击在浏览器编辑&结果如图:
修改后可以直接保存:
点击确认后就可以直接保存。&pptx的编辑模式如下:
这里的docx文件的编辑模式一直都在报错搞了很久也没搞定,错误信息如下,如果大家知道还请指导指导:
pdf是没有编辑模式的,现在再来看看excel的只读模式(view)如下:
这里的菜单中并不包含“在浏览器中编辑”,其中第15行是我刚才修改的新数据。docx和pptx的只读模式就不贴图了,在mobile的运行结果如下(我这里是用android手机访问我的站点,由于是通过wifi来访问自己的电脑上的站点,这里需要把计算机的全名改为IP地址)。
注意上面的url是192.168.1.25XXX,这里的ip是的IP。这里总结一下的测试结果如下:
mobileview
在http和https协议下view都通过,edit&view没有通过,mobileview只测试了http协议
在http和https协议下view和edit都通过,mobileview只测试了http协议
在http和https协议下view和edit都通过,mobileview只测试了http协议
不存在edit action
view在http协议下通过,在https在协议下未通过,mobileview 未通过
&这里我把问题的重心放在word的edit上面,对于pdf&在owas采用https以及在mobile上不能访问的原因未未做调查。知道这些问题的革命前辈还请不吝赐教。源码下载地址:http://download.csdn.net/detail/dz5
https://code./office/Building-an-Office-Web-f98650d6
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:4128337次
积分:41131
积分:41131
排名:第89名
原创:388篇
转载:591篇
评论:215条
(1)(2)(7)(2)(9)(11)(9)(7)(19)(17)(22)(8)(1)(5)(3)(14)(4)(1)(7)(8)(1)(4)(4)(3)(2)(4)(3)(2)(5)(11)(8)(2)(11)(2)(14)(3)(4)(6)(9)(4)(9)(15)(4)(3)(8)(10)(9)(7)(6)(14)(3)(15)(37)(13)(14)(14)(14)(17)(14)(12)(9)(2)(22)(8)(7)(16)(16)(4)(30)(13)(11)(3)(2)(19)(12)(8)(8)(14)(2)(10)(32)(8)(16)(34)(10)(51)(63)(38)(11)(3)(1)

我要回帖

更多关于 整合营销系统服务 的文章

 

随机推荐