## 优道PDF阅读控件使用帮助

- 功能概述
- 运行环境
- 网页中嵌入控件
- 服务器文档加密
- 服务器端版权控制
- 控件属性
- 控件方法
- 控件事件
- 错误码说明
- 其它

### 功能概述

优道PDF阅读控件（UUDoc PDF Control）是一款支持反截屏功能的PDF文档数字版权保护控件，支持对PDF文档的在线加密保护，可支持多种不同类型的浏览器和桌面应用程序使用。控件通过简单的属性设置即可完成对文档的复制、打印和截图的授权控制，独特的服务器端配置模式，支持在服务器端对控件进行属性设置, 防止了客户端通过脚本对版权控制功能进行篡改的可能。控件支持内存方式加载文档和加密传输方式远程加载文档，控件小巧可独立运行，不需要另外再安装其它庞大的PDF阅读器。

控件自带有换页、查找、缩放、拖拽、旋转、适应页面、适应页宽等常用文档浏览器的功能，可以轻松的嵌入到各类网站、Web应用系统和桌面应用程序当中，能有效的和您目前的应用进行无缝集成。控件支持PDF动态水印定义功能，能给您最强有力的文档阅读和数字版权保护功能支持。

### 运行环境

服务器端：支持Windows和Linux操作系统，支持任何的服务器编程语言，例如asp,asp.net,php,java,python,ruby等

支持使用HTTP、HTTPS、FTP协议从服务器远程加载文档，支持服务器身份验证

控件客户端支持的操作系统：WindowsXP/2003/2008/Vista/Win7/Win8/Win10

桌面开发支持的编程语言：VB、CSharp 、VB.NET、Delphi、C++等

支持32位及64位操作系统和浏览器

支持嵌入到基于ActiveX技术的IE浏览器和使用NPAPI技术的非IE浏览器中

支持英文、中文简体、中文繁体等多种语言用户界面

### 网页中嵌入控件

您可以参考我们提供的演示文件在网页中嵌入优道PDF阅读控件：

控件的PlogId为:UdPdf.Viewer

控件的ClassId为:8C3D3705-1100-4D52-9D04-7E9A435CE220

控件的ContentType为: application/udpdf-plugin

        <object id="pdfCtl" width="100%" height="600" classid="CLSID:8C3D3705-1100-4D52-9D04-7E9A435CE220"
             codebase="UdPdf/axUdPdf32.msi#Version=2,7,2,0">
             <param name="License" value="" />

             <embed id="pdfPlugin" width="100%" height="600" type="application/udpdf-plugin"
                pluginspage="UdPdf/npUdPdf.msi#Version=2,7,2,0"
                License=""
                onReady="f_onReady" onDownload="f_onDownload" onPageChanged="f_onPageChanged"
                onZoom="f_onZoom" onError="f_onError"></embed>
        </object>

其中axUdPdf32.msi为控件32位ActiveX版的安装程序,安装后控件支持IE访问；npUdPdf.msi为NPAPI版的安装程序，安装后支持FireFox、Chrome、Safari等使用NPAPI标准的非IE浏览器使用。

初始化判断控件是否安装,并获取PDF控件对象：

        function f_initPdf(){
            var udPdfCtl = null;
            if(window.ActiveXObject){//if IE
                var axobj = null;
                var setupFile = "UdPdf/axUdPdf32.msi";//PDF控件安装文件
                if(window.navigator.platform == "Win64"
                  || window.navigator.cpuClass == "x64")//64位浏览器安装文件
                    setupFile = "UdPdf/axUdPdf64.msi";

                try{
                    axobj = new ActiveXObject('UdPdf.Viewer');
                }catch(e){}
                if(axobj) {
                    if(f_checkNewVersion(axobj.GetVersion())){
                        document.getElementById("udPdfDiv").innerHTML = "<a href='" + setupFile
                         + "' class='inst' target='_blank'>PDF控件有新版本v"
                         + UDPDF_VERSION + "，点这里升级安装...</a>";
                    }
                    else{
                        udPdfCtl = document.getElementById("udPdfCtl");
                        return udPdfCtl;
                    }
                }
                else{
                    document.getElementById("udPdfDiv").innerHTML = "<a href='" + setupFile
                     + "' class='inst' target='_blank'>>您尚未安装PDF控件，点这里进行安装...</a>";
                }
            }
            else{//NOT IE
                var setupFile = "UdPdf/npUdPdf.msi";
                if (navigator.plugins && navigator.plugins.length > 0){
                    var plugin = navigator.plugins["UdPdf Plugin"];
                    if(plugin){
                        udPdfCtl = document.getElementById("udPdfPlugin");
                        if(f_checkNewVersion(udPdfCtl.GetVersion())){
                            document.getElementById("udPdfDiv").innerHTML = "<a href='" + setupFile
                             + "' target='_blank' class='inst'>PDF控件有新版本v"
                             + UDPDF_VERSION + "，点这里升级安装...</a>";
                        }
                        else{
                            return udPdfCtl;
                        }
                    }
                    else{
                        document.getElementById("udPdfDiv").innerHTML = "<a href='" + setupFile
                         + "' target='_blank' class='inst'>您尚未安装PDF插件，点这里进行安装...</a>";
                    }
                }
                else{
                    document.getElementById("udPdfDiv").innerHTML = "<span class='inst'>当前浏览器不支持插件<span>";
                }
            }
            return null;
        }

        //版本比较，检查是否安装了新版本
        function f_checkNewVersion(instVer){
            var newVer = UDPDF_VERSION.split(".");
            var curVer = instVer.split(".");
            if(parseInt(newVer[0]) > parseInt(curVer[0]))
                return true;
            if(parseInt(newVer[0]) == parseInt(curVer[0]) && parseInt(newVer[1]) > parseInt(curVer[1]))
                return true;
            if(parseInt(newVer[0]) == parseInt(curVer[0]) && parseInt(newVer[1]) == parseInt(curVer[1])
              && parseInt(newVer[2]) > parseInt(curVer[2]))
                return true;
            return false;
        }

        //初始化加载的时候获取控件对象
        var ctl;
        function f_onload() {
            ctl = f_initPdf();//获取失败返回null
            if(ctl){
                ctl.FileId="PdfSample"
                ctl.LoadFromWeb("GetFile.asp");
            }
        }

属性的设置示例：

        <script type="text/javascript">
            //根据复选框判断是否显示工具条
            function f_toolbarVisible() {
                if(ctl)
                    ctl.ToolbarVisible = document.getElementById("chkToolbarVisible").checked
            }
        </script>

方法的调用示例

        <script type="text/javascript">
            //放大操作
            function f_zoomIn() {
                if(ctl)
                    ctl.ZoomIn();
            }
        </script>

事件的捕捉示例，兼容所有浏览器：

        <script type="text/javascript" event="OnError(errorCode)" for="pdfCtl">
            f_onError(errorCode);
        </script>

        <script type="text/javascript">
            function f_onError(errorCode){
    	    document.getElementById("info").innerHTML = "OnError事件，文档加载失败，错误码：" + errorCode;
    	}
        </script>

### 服务器文档加密

使用优道科技提供的文档加密工具UdPdfTools.exe对文档进行加密，加密后的文件会在原扩展名前加上en前缀。加密工具支持命令行方式。

加密时可以指定加密密码，加密后需要将密码的哈希值填写到控件的HashKey参数当中

将加密后的文件上传到服务器上，在控件页面根据所传递的参数将需要的加密文件读取并进行输出

若不想别人通过页面获取到参数的配置情况，可以使用此工具对属性配置内容进行加密，原配置字符串使用"&"分隔的键值对格式，多个参数之间使用"|"进行分隔，支持相应的属性或方法名称

也可在服务器上调用加密命令行工具直接完成普通文档文件到加密文件的转换，命令行使用说明：

            参数说明:
              -input <file>           要进行加密保护的PDF文件名
              -output <folder>        指定加密后的文件输出目录或文件名
              -password <password>    设置加密使用的密码,会返回加密过的哈希码,可放在PDF控件的HashKey属性当中
              -encrypt <config>       创建使用"&"进行分隔的加密字符串,可用在PDF控件的EncryptConfig属性
                                            和EncryptExecute方法中使用
              -decrypt                解密选项,可以使用此选项对文档进行解密
              -help                   显示UdPdfTools.exe的使用帮助信息

            使用示例:
              UdPdfTools -input c:\test.pdf -output "c:\hello world" -password 123abc

              以下是对属性配置进行加密,加密后的字符串可以放在EncryptConfig属性当中
              UdPdfTools -encrypt "EnableCopy=true&EnablePrint=false&ToolbarVisible=false"

              以下是对方法进行加密,支持"|"分隔的多个参数,加密后的字符串可以用EncryptExecute(string)函数来执行
              UdPdfTools -encrypt "LoadFromWeb=sample.asp|123456"

              如果是对密码参数进行加密，传入密码参数时需要添加“[Encrypt]”前缀。
              例如:  UdPdfTools.exe –encrypt 123456
              The encrypt confing string is:
              4019DA9B613B82F72186203AA9ABE0C7

              然后可以添加“[Encrypt]”前缀使用加密密码的方式打开pdf文档：
              ctl.LoadFromWeb(“getfile.aspx”,“[Encrypt]4019DA9B613B82F72186203AA9ABE0C7”,“post”);

              工具也支持使用原密码对加密的文件进行解密:
              UdPdfTools -input c:\test.enpdf -password 123abc

              解密文档并输出到指定目录下:
              UdPdfTools -input c:\test.enpdf -output "c:\hello world"  -password 123abc

              “enpdf”扩展名的文件不使用 -decrypt 选项也可以调用解密功能,如果不是enpdf文件,可以使用 -decrypt 参数强制调用解密功能:
              UdPdfTools -input c:\test.xpdf -output "c:\hello world"  -password 123abc -decrypt

ActiveX控件的FileId会被提交回服务器，可以根据该值输出不同的文件，以下是C#的服务器ASP.NET示例代码，也可方便的用其它语言编写：

            protected void Page_Load(object sender, EventArgs e)
            {
                if (Request.Form["uudoc_getfile"] == "1")//如果是提交请求文件
                {
    		//可以通过HashKey的设置进行HTTP头安全校验
        		if (Request.Headers["UdPdf-HashKey"] != "3CE59E850E2C590AFD6E4D3516BA3F1B")
        	    	    return;

                    //根据文件ID获取不同的加密文件或原始文件，需要根据实际情况编写自己的业务逻辑
    		if (Request.Form["uudoc_encrypted"] == "1")//是否使用加密读取方式
    		{
    		    //读取加密过的PDF文件
                        Response.WriteFile(Server.MapPath("upload/" + Request.Form["uudoc_fileid"] + ".enpdf"));
    		}
    		else
    		{
    		    //读取原始PDF文件
                        Response.WriteFile(Server.MapPath("upload/" + Request.Form["uudoc_fileid"] + ".pdf"));
    		}
                    Response.End();
                }
            }

可向服务器提交的参数有：

参数名称 | 参数说明
--- | ---
uudoc_getfile | 1表示开始从后台读取文件
uudoc_fileid | 文件Id值，用来判断要读取的文件名称，对应前端控件设置的FileId属性值
uudoc_encrypted | 1表示采用的是加密文件读取方式

### 服务器端版权控制

优道PDF控件支持服务器端的属性设置，在服务器端进行属性设置后客户端的部分版权控制功能将不再有效，从而更安全的保护了PDF文档的安全性。

服务器端使用http头的方式对控件属性进行设置，支持的http头设置的名称为UdPdf-Config和UdPdf-EncryptConfig。

UdPdf-Config配置的参数值为使用“&”分隔的字符串，例如"EnableCopy=true&EnablePrint=false&ToolbarVisible=false"。

UdPdf-EncryptConfig配置的参数值为以上加密后的字符串内容，具体加密方法请参看上一节中UdPdfTools.exe工具的使用

在C#/VB.NET中可以使用Response.AppendHeader进行http头的设置，例如：

            Response.AppendHeader("UdPdf-Config", "EnableCopy=false&EnablePrint=false");
        或者：
    	Response.AppendHeader("UdPdf-EncryptConfig", "74321C0******BA168");

在Java语言中可以使用response.setHeader进行http头的设置，例如：

    	response.setHeader("UdPdf-Config", "EnableCopy=false&EnablePrint=false");
        或者：
    	response.setHeader("UdPdf-EncryptConfig", "***加密后的字符串***");

使用http头进行属性设置后下列和版权保护相关的属性在客户端的设置将不再有效：

服务器端设置影响的属性 | 参数说明
--- | ---
HashKey | 加密密码Hash值，该值同时会被以http头的方式提交回服务器
EnableCopy | 是否允许复制
EnablePrint | 是否允许打印
EnableCapture | 是否允许屏幕截图
ToolbarVisible | 是否显示工具栏
RemoveWaterMark | 移除水印的方法，使用任何服务器属性设置后均不能再移除水印
PrintCurrentOnly | 设置是否只允许打印当前页面

ActiveX控件向服务器请求文件的时候同时会以http头的方式提交下列值：

- UdPdf-Version：优道PDF阅读控件的版本号
- UdPdf-HashKey：HashKey属性，可用作请求合法性校验
- UdPdf-UrlType：如果使用相对路径来请求的这里值为0，使用绝对路径值为1，可以用来控制是否只允许相对路径来获取文件

在C#/VB.NET语言中可以使用Request.Headers["UdPdf-UrlType"]来获取到相关的http头的值，Java中可以使用request.getHeader("UdPdf-UrlType")来获取。

### 控件属性

属性名称 | 类型 | 属性说明
--- | --- | ---
Width | 整数 | 控件区域宽度
Height | 整数 | 控件区域高度
License | 字符 | 获取或设置控件的注册码信息
HashKey | 字符 | 获取或设置密码的MD5 Hash值，可以用UdPdfTools.exe命令行工具加-password <password>获取
FileId | 字符 | 获取或设置文件的ID值，该值会提交回服务器端
Encrypted | 布尔 | 获取或设置是否采用加密方式加载文档，默认为True，加载加密过的文档；若设置为False，则加载原始未加密的文档文件
EnableCapture | 布尔 | 获取或设置是否允许进行屏幕截图，默认为True
EnableCopy | 布尔 | 获取或设置是否允许复制文档内容，默认为True
EnablePrint | 布尔 | 获取或设置是否允许打印文档，默认为True
PrintCurrentOnly | 布尔 | 获取或设置是否只允许打印当前页面,默认为False
ShowPrintDialog | 布尔 | 获取或设置是否显示打印选择对话框,默认为True
ToolbarVisible | 布尔 | 获取或设置是否显示文档工具栏，默认为True
HasBookmark | 布尔 | 获取文档是否含有书签
BookmarkVisible | 布尔 | 获取或设置是否显示书签栏，默认为True
DocBgColor | 颜色 | 获取或设置文档的背景颜色
ShowContextMenu | 布尔 | 获取或设置是否显示右键上下文菜单，默认为True
TotalPage | 整数 | 只读属性，获取文档的总页码
CurrentPage | 整数 | 只读属性，获取文档的当前页码
DefaultZoom | 浮点 | 获取或设置文档打开时的默认缩放比例,默认为-1，表示适合内容，-2表示适合宽度，100表示实际大小显示
DefaultDisplayMode | 整数 | 获取或设置文档打开时的默认显示模式，默认为0，1为单页显示，4为连续显示
UILanguage | 字符 | 获取或设置控件所使用的界面语言，en为英文、cn为中文简体、tw为中文繁体，留空为根据操作系统自动判断所使用的语言
FileName | 字符 | 获取或设置打印时所使用的文件名称
EncryptConfig | 字符 | 获取或设置文档打开时的加密配置字符串，加密需要使用UdPdfTools.exe命令行工具，参看UdPdfTools.exe相关说明
EnableShowAbout | 布尔 | 获取或设置是否按Ctrl+Shift+A时显示关于对话框，默认为True显示
IsReady | 布尔 | 只读属性，获取文档是否已加载完成，状态已就绪
FindMode | 整数 | 查找模式：0显示向上向下查找(默认）；1显示查找全部按钮；2同时显示查找全部及向上向下查找按钮；3不显示查找
ScrollWheelZoom | 布尔 | 鼠标滚轮滑动时是否对页面进行缩放操作：为true进行缩放，默认为false不缩放（页面上下滚动）
NavbarPosition | 整数 | 导航栏显示位置，默认0显示在左侧，为1则显示在右侧
NavbarWidth | 字符 | 导航栏的宽度，可以设置为数字，也可以设置为%结尾的百分比，默认为空为20%（导航栏最小宽度为130px，最大宽度为窗口宽度的一半）
SelectionBgColor | 整数 | 选中项的背景色，可以用0x146482这样表示BGR

### 控件方法

方法名称 | 参数说明 | 方法说明
--- | --- | ---
void Zoom(float zoom) | zoom:缩放比例，实际大小为100.00 | 对文档进行指定比例缩放
void ZoomIn() | 无 | 放大文档视图
void ZoomOut() | 无 | 缩小文档视图
void ZoomFitWidth() | 无 | 以适应宽度方式显示文档
void ZoomFitPage() | 无 | 以适应页面大小方式显示文档
void ZoomActual() | 无 | 以实际大小显示文档
float GetZoom() | 无 | 获取文档的缩放比例
void RotateLeft() | 无 | 左旋转90°，即逆时针旋转
void RotateRight() | 无 | 右旋转90°，即顺时针旋转
void FindNext(string findText) | findText:要搜索的内容 | 查找下一个字符
void FindPrev(string findText) | findText:要搜索的内容 | 查找上一个字符
void GoToPage() | 无 | 进行换页操作
void GoToPageNo(int no) | no:要转到的页码 | 转到指定的页码
void GoToNextPage() | 无 | 转到下一页
void GoToPrevPage() | 无 | 转到上一页
void GoToFirstPage() | 无 | 转到第一页
void GoToLastPage() | 无 | 转到最后一页
void ToggleFullScreen() | 无 | 全屏幕显示模式转换，进入或退出全屏状态
void Print(int copies) | copies：可选参数，要打印的份数 | 打印当前文档
void CancelPrint() | 无 | 取消打印
void LoadFromWeb(string url,string password,string method) | url:加载地址，如果为空字符串表示当前页 以http开头则为绝对路径，否则为相对路径 password:PDF文件自带加密密码,可选 method:请求方式,Post或Get,默认为Get | 向WEB页面提交POST请求加载文档文件 提交参数为uudoc_getfile=1和uudoc_fileid Web网络版支持该函数
void LoadFromData(Byte[] pData,string password) | pData：字节数组指针 password:PDF文件自带加密密码,可选 | 从字节数组中加载文档 桌面控件版支持该函数
void LoadFromFile(string fileName,string password) | fileName：文件名 password:PDF文件自带加密密码,可选 | 根据文件名加载指定文档
void SetServerUser(string username,string password) | username：服务器身份验证使用用户名 password：服务器用户登录密码 | 如果需要，设置服务器身份验证的用户名和密码
void AppendHeader(string name,string value) | name：自定义Http Header的名称 value：自定义Http Header的值 | 添加自定义的Http Header
int GetErrorCode() | 无 | 获取异常的错误码。详见错误码说明
int GetFileSize() | 无 | 获取文档文件的字节大小
int GetPageWidth(int pageNo) | pageNo:页码,可选参数,为空取第1页 | 获取指定页的屏幕像素宽度
int GetPageHeight(int pageNo) | pageNo:页码,可选参数,为空取第1页 | 获取指定页的屏幕像素高度
void EncryptExecute() | 无 | 执行加密字符定义的命令，具体参见UdPdfTools.exe相关说明
void Close() | 无 | 关闭打开的文档
string GetHostName() | 无 | 获取电脑主机的名称
string GetVersion() | 无 | 获取控件的版本号
string Hash(string str) | 要加密的字符串 | 获取字符串的32位Md5 Hash码,可用于HashKey属性
void ScrollTo(int x,int y) | 无 | 滚动文档显示位置到指定像素值
void SetWaterFont(string fontName, long fontSize,long fontColor, bool bold,bool italic, bool underline,bool strikeOut) | fontName:字体名称 fontSize:字体大小,单位pt fontColor:字体颜色值 bold:是否粗体显示(可选) italic:是否斜体显示(可选)
underline:是否添加下划线(可选)
strikeOut:是否添加删除线(可选)
设置水印文本的字体格式
long AddWaterText(string text,long x,long y, long transparent,long rotate, long repeatX,long repeatY) | text:水印文字 x:水印位置的横坐标 y:水印位置的纵坐标 transparent:透明度(0-100),100为完全透明(可选) rotate:逆时针旋转角度(可选)
repeatX:横轴重复显示的间距,0不重复(可选)
repeatY:纵轴重复显示的间距,0不重复(可选)
添加文字水印,返回值为所添加水印的索引号
long RemoveWaterMark(long index) | index:要删除水印的索引号,可选参数,为空删除所有水印 | 删除指定的水印或所有水印,成功返回0
void SetFindText(string text) | text:要查找的文本字符串 | 设置工具条上查找框中要查找的文本
string GetFindText() | 无 | 获取当前正在搜索的文本内容
void FindAll(string text) | text:要全文查找的文本字符串 | 对指定的字符串进行全文搜索
string GetSelectedText() | 无 | 获取当前选中的字符串内容

在需要传入密码的方法中，例如LoadFromWeb,LoadFromFile,SetServerUser等方法，可以先使用UdPdfTools.exe工具对密码进行加密，然后使用“[Encrypt]”前缀(不区分大小写)支持传入加密过的密码，防止别人获取到密码直接对PDF文档进行解密。

例如某个pdf文档的默认加密密码是：123456，使用命令行工具：

UdPdfTools.exe –encrypt 123456

获取到加密后的密码是：4019DA9B613B82F72186203AA9ABE0C7

然后可以添加“[Encrypt]”前缀使用加密密码的方式打开pdf文档：

ctl.LoadFromWeb(“getfile.aspx”,“[Encrypt]4019DA9B613B82F72186203AA9ABE0C7”,“post”);

### 控件事件

事件名称 | 参数说明 | 事件说明
--- | --- | ---
OnReady() | 无 | 文档加载完成触发该事件
OnDownload(int totalSize,int downSize) | totalSize：总共要下载的文件大小；downSize：已经下载的字节大小 | 文档下载过程中触发该事件
OnPageChanged(int currentPage,int totalPage) | currentPage：当前页码；totalPage：总页码 | 换页时触发该事件
OnZoom(float zoomScale) | zoom：缩放比例 | 缩放操作时候触发该事件
OnError(int errorCode) | errorCode：错误码。详见以下错误码说明 | 出现异常时触发该事件
OnBeforePrint(string printerName) | printerName：选择的打印机的名称 | 打印前触发该事件
OnPrint() | 无 | 打印完成时触发该事件
OnPrintAborted() | 无 | 打印中断时触发该事件,打印完成也会触发
OnFind(int page) | page:被找到文本所在的页码,没有找到为 -1 | 查找文本时触发该事件，传入参数page为所找到文本所在的页码,没找到则为 -1
OnHScrolled(int x) | x:水平移动到的位置 | 水平移动文档查看区域后触发该事件
OnVScrolled(int y) | y:垂直移动到的位置 | 垂直移动文档查看区域后触发该事件
OnClosed() | 无 | 文档关闭后触发该事件
OnDblClick(int button,int x,int long y) | button:鼠标按键，0为鼠标左键，1为鼠标中键，2为鼠标右键； x,y:鼠标点击的坐标位置 | 在页面中双击鼠标时触发该事件
OnFindAll() | 无 | 查找所有后触发该事件

### 错误码说明

错误码值 | 异常说明
--- | ---
0 | 一切正常
1 | 在虚拟机或远程桌面中打开文档
2 | 使用非HTTP访问模式
3 | 加载文档安全组件失败
4 | 文件格式错误
5 | 加载文件失败
6 | 请求服务器文件失败

### 其它

- 关于优道：珠海市优道信息科技有限公司是一家致力于文档管理、数字版权保护和移动办公产品研发和推广的科技公司。
- 优道网站：www.uudoc.com
- 优道服务热线：0756-2132796，技术支持邮件：support@uudoc.com，技术支持QQ：13063574