zoukankan      html  css  js  c++  java
  • 在线编辑Office文件

    前言

    第一次用SharePoint的时候感觉很惊奇,竟然可以在本地编辑服务器上的Office文件!不过不知道为什么一直没有想要知道为什么可以这样做。

    前两天园子里有一篇文章引发了激烈的讨论。其中有人问楼主一些问题,其中就有这个。OK,那就看看到底的为什么吧。

    准备

    此部分可忽略,可直接看正文部分。

    找原因的过程蛮简单。随便打开了公司SharePoint上的Document页,看HTML源码。发现链接的onfocus事件OnLink(this)。

    好吧,那就找找这个函数吧。还是看源码,里面没有找到这个函数。那就去引用的两个js文件里看看吧。

    最终在init.js里找到了。

    function OnLink(elm)
    {
        DeferCall('OnLinkDeferCall', elm);
    }

    DeferCall函数是干嘛的就先不管了,找找OnLinkDeferCall函数。然后在core.js里找着了。

    function OnLinkDeferCall(elm)
    {
        if (!IsMenuEnabled())
            return false;
        elm.onblur=OutItem;
        elm.onkeydown=PopMenu;
        var elmTmp=FindSTSMenuTable(elm, "CTXName");
        if (elmTmp==null)
            return false;
        OnItem(elmTmp);
        return false;
    }

    没什么值得注意的,再找PopMenu函数。

    function PopMenu(e)
    {
        if (!IsMenuEnabled())
            return true;
        if (e==null)
            e=window.event;
        var nKeyCode;
        if (browseris.nav6up)
            nKeyCode=e.which;
        else
            nKeyCode=e.keyCode;
        if (!IsMenuOn() && ((e.shiftKey && nKeyCode==13) || (e.altKey && nKeyCode==40)))
        {
            onKeyPress=true;
            CreateMenu(e);
            onKeyPress=false;
            return false;
        }
        else
            return true;
    }

    真他娘的悲剧,找CreateMenu函数;继续悲剧,找CreateMenuEx函数;再次悲剧,找AddDocLibMenuItems函数。好吧,在这个函数里有一句:

    strAction="editDocumentWithProgID2('"+currentItemFileUrl+"', '"+currentItemProgId+"', '"
    +currentItemOpenControl+"', '"+bIsCheckout+"', '"+ctx.HttpRoot+"', '"+currentItemCheckedoutToLocal+"')";

    editDocumentWithProgID2函数又调用editDocumentWithProgIDNoUI函数。

    editDocumentWithProgIDNoUI里面有一段是这样的:

    objEditor=new ActiveXObject(varEditor+".3");
    if (objEditor !=null )
    {
        if (bCheckout=="1")
        {
            if (!objEditor.CheckoutDocumentPrompt(strDocument, true, varProgID))
            return 1;
        }
        else
        {
            if (strCheckouttolocal=="1")
            fUseLocalCopy=true;
            if (!objEditor.EditDocument3(window, strDocument, fUseLocalCopy, varProgID))
            return 1;
        }
        var  fRefreshOnNextFocus=false;
        fRefreshOnNextFocus=objEditor.PromptedOnLastOpen();
        if (fRefreshOnNextFocus)
        {
            window.onfocus=RefreshOnNextFocus;
        }
        else
        {
            SetWindowRefreshOnFocus();
        }
        return;
    }

    objEditor.EditDocument3,看来就是varEditor参数的问题了。然后往回找,到AddDocLibMenuItems函数这里卡住了。

    function AddDocLibMenuItems(m, ctx)

    就两个参数,真他大爷的!

    找找currentItemOpenControl参数,没什么有价值的内容。

    那就随便看看吧,AddCheckinCheckoutMenuItem函数应该是签入签出用的。函数里有一句:

    strAction="CheckoutDocument('"+ctx.HttpRoot+"', '"+url+"', '"+opencontrol+"')";

    继续找:

    function CheckoutDocument(strhttpRoot, strDocument, strOpenControl)
    {
        var stsOpen=null;
        var fRet=true;
        var fClientCheckout=false;
        if (strDocument.charAt(0)=="/" || strDocument.substr(0,3).toLowerCase()=="%2f")
            strDocument=document.location.protocol+"//"+document.location.host+strDocument;
        var strextension=SzExtension(unescapeProperly(strDocument));
        if (FSupportCheckoutToLocal(strextension) &&
            strOpenControl=="SharePoint.OpenDocuments.3")  //应该就是这玩意儿了吧
        {
            stsOpen=StsOpenEnsureEx(strOpenControl);
        }
        if (stsOpen !=null)
        {
            try
            {
                fRet=stsOpen.CheckoutDocumentPrompt(unescapeProperly(strDocument), false, "");
                SetWindowRefreshOnFocus();
                fClientCheckout=true;
                return;
            }
            catch (e)
            {
            }
        }
         if (!fClientCheckout)
            NavigateToCheckinAspx(strhttpRoot, "FileName="+escapeProperly(unescapeProperly(strDocument))+"&Checkout=true");
    }

    OK,google一下。在MSDN里提到%ProgramFiles%\Microsoft Office\Office14\OWSSUPP.dll 。我的电脑里只有OFFICE11。所以实例化var obj = new ActiveXObject('SharePoint.OpenDocuments.3');用不了。

    再看看其他资源,看来还有SharePoint.OpenDocuments.2和SharePoint.OpenDocuments.1,测试一下,都可以用。

     

    正文

    好吧,既然找着了就试试怎么用的吧。

    查了下MSDN,SharePoint.OpenDocuments控件在安装了Office2007后将3用做版本号,Office2003是将2作版本号,Office2003之前的版本以1作版本号。

    1.新建网站。

    2.网站里新建文件夹,并在文件夹里放拷贝一个word文件test.doc,一个excel文件test.xls。

    3.在Default.aspx里写javascript。

    var objEditor;
    try{
        objEditor = new ActiveXObject("SharePoint.OpenDocuments.3");
    }catch(e){
        try{
            objEditor = new ActiveXObject("SharePoint.OpenDocuments.2");
        }catch(e){
            try{
                objEditor = new ActiveXObject("SharePoint.OpenDocuments.1");
            }catch(e){
                alert("你还是洗洗睡吧!");//当然,洗洗睡是解决不了问题的,先装Office吧
            }
        }
    }

    试试打开,编辑和新建。

    expression.ViewDocument(bstrDocumentLocation, varProgID) //俗称“打开”
    expression.EditDocument(bstrDocumentLocation, varProgID) //编辑
    expression.CreateNewDocument(bstrTemplateLocation, bstrDefaultSaveLocation)//新建文档
    /**********************************************************************
    参数
    expression:一个返回 OpenDocuments 控件 对象的表达式。
    bstrDocumentLocation:一个字符串,其中包含要打开以读取的文档的 URL。
    varProgID:一个可选字符串,其中包含要用来打开文档的应用程序的 ProgID。如果省略此参数,将使用文档的默认查看器。
    bstrTemplateLocation:一个字符串,包含从中创建文档的文档模板的 URL 或创建文档时要调用的应用程序的编程标识符 (progID)。
    bstrDefaultSaveLocation:一个字符串,包含可指定用于保存新文档的建议默认位置的路径。
    返回值
    3个函数返回值都是成功为 true;失败为 false。
    ***********************************************************************/

    按规则分别些好3个函数,然后用3个A标签调用。建个模版,用来创建文件。但是路径不清楚,浏览一遍Default.aspx,把路径改好。刷新一下。

    objEditor.ViewDocument("http://localhost:1773/WebSite1/Documents/Test.doc");
    objEditor.EditDocument("http://localhost:1773/WebSite1/Documents/Test.xls");
    objEditor.CreateNewDocument("http://localhost:1773/WebSite1/Documents/Template.dot","http://localhost:1773/WebSite1/Documents/");

    试试Open:

    image

    点击“确定”,成功以只读打开Test.doc文件。

    试试Edit,成功以只读打开。干嘛是只读啊?

    Create呢?好吧,可以打开一个新文档,当然是跟模版一个样儿的。在文档中写“Hello Kitty”,保存。见鬼,保存不了。

    看来还是只读的问题啊。赋予Documents文件夹Users用户修改、写入权限,问题依然。

    部署到IIS看看,毕竟网站最终要靠它的。配置完成,再次修改函数里的路径。然后通过IIS浏览,My God!怎么还是没法保存?明明有修改和写入的权限啊?再通过IIS赋予Documents目录写入权限。大功告成!

    结语

    OpenDocuments对象的公共方法有十几个,具体可查看MSDN:http://msdn.microsoft.com/zh-cn/library/cc264316(v=office.12).aspx

    然后需要注意权限问题。我是在本机测试,IIS是5.1的,如果是IIS6,应该不需要再通过IIS赋权限了。

  • 相关阅读:
    Cipherlab CPT9300手持扫描枪开发体验 [转]
    引用(ajaxfileupload.js) ajaxfileupload.js报jQuery.handleError is not a function错误解决方法
    C#锐利体验2.0:泛型编程
    Visual C#中调用Windows服务初探
    C#操作XML代码整理
    个人代码库のC#背景色渐变的功能
    ~~ C#数字时钟 ~~
    DevExpress随笔10.1.5的汉化与破解
    用C#获取局域网内所有机器
    C# 图片格式(JPG,BMP,PNG,GIF)等转换为ICO图标
  • 原文地址:https://www.cnblogs.com/ainijiutian/p/1912305.html
Copyright © 2011-2022 走看看