天天看点

使用iWebOffice实现电子签章

摘要:随着信息化的发展电子签章已经越来越多的被用到很多oa系统中,今天就来看一下如何使用iweboffice来实现电子签章功能。

内容:

1.iweboffice2003的基本原理

2.使用iweboffice2003实现电子签章

在开始今天的主题之前先简单的说一下iweboffice的原理。iweboffice控件由两部分组成:一个是用于集成在页面上的iweboffice2003.ocx文件,另一个是运行在后台服务器上的imsgserver2000.dll文件。前者就是大家所熟知的activex插件,当然要使用它在客户端必须安装此插件,后者是用于配合前者的请求进行通信,事实上控件工作的原来正是前后台通信和处理的过程。iweboffice2003.ocx集成在页面上,通过js脚本调用,用户文档的编辑以及传递消息到服务器;imsgserver2000.dll在服务器端运行,用于解析iweboffice2003.ocx控件发过来的信息包,以及将服务器上处理的结果反馈给客户端iweboffice2003.ocx。

使用iWebOffice实现电子签章

首先来看前端的代码,可以说同其他activex几乎完全一样。classid是固定的,是控件的注册id,这也是所有com组件必须拥有的;codebase由两部分组成#version之前的是控件的下载地址,后面是控件版本号,这两者当然务必要写正确,否则会造成控件不能正常下载、显示和使用。

前端页面代码:

<code>&lt;</code><code>object</code> <code>id="cweboffice" width="100%" height="100%" classid="clsid:23739a7e-5741-4d1c-88d5-d50b18f7c347" codebase=" iweboffice2003.ocx#version=6,0,0,4 " &gt;&lt;/</code><code>object</code><code>&gt;</code>

如果classid和version没有设置错的话运行会显示控件(前提是客户端安装了iweboffice插件),当然此时还不能打开文档,因为前端还没有js调用。为了方便调用,这里将js操作部分加以封装(注意封装部分用到了ext面向对象):

<code>/*</code>

<code>    </code><code>author:kenshincui</code>

<code>    </code><code>date:2011.11.16</code>

<code>    </code><code>description:weboffice operate class.</code>

<code>*/</code>

<code>ext.useshims=</code><code>true</code><code>;</code>

<code>ext.namespace(</code><code>"cmj.web.extextend"</code><code>);</code>

<code>cmj.web.extextend.weboffice=ext.extend(ext.util.observable,{</code>

<code>    </code><code>constructor:</code><code>function</code><code>(config){</code>

<code>//        this.addevents("beforeopen");</code>

<code>//        this.addevents("open");</code>

<code>//        this.addevents("beforeprint");</code>

<code>//        this.addevents("print");</code>

<code>        </code><code>this</code><code>.listeners=config.listeners;</code>

<code>        </code><code>cmj.web.extextend.weboffice.superclass.constructor.call(</code><code>this</code><code>,config);</code>

<code>        </code><code>this</code><code>.objectid=config.objectid;</code><code>//客户端对象id</code>

<code>        </code><code>this</code><code>.weburl=config.weburl;</code><code>//weboffice 的服務器端操作url</code>

<code>        </code><code>this</code><code>.filename=config.filename;</code><code>//文件名称(不包含完整路径并且后缀可有可无,如果没有后缀的话则必须配置filetype属性)</code>

<code>        </code><code>if</code><code>(config.filetype!=void 0){</code>

<code>            </code><code>this</code><code>.filetype=config.filetype;</code>

<code>        </code><code>}</code><code>else</code><code>{</code>

<code>            </code><code>this</code><code>.filetype=</code><code>""</code><code>;</code>

<code>        </code><code>}</code>

<code>        </code><code>this</code><code>.weboffice=ext.getdom(</code><code>this</code><code>.objectid);</code>

<code>    </code><code>},</code>

<code>    </code><code>getobject:</code><code>function</code><code>(){</code>

<code>        </code><code>return</code> <code>this</code><code>.weboffice;</code>

<code>    </code><code>load:</code><code>function</code><code>(){</code>

<code>        </code><code>weboffice=</code><code>this</code><code>.weboffice;</code>

<code>        </code><code>try</code><code>{</code>

<code>            </code><code>weboffice.weburl=</code><code>this</code><code>.weburl;</code>

<code>            </code><code>weboffice.recordid=</code><code>"cid"</code><code>;</code>

<code>            </code><code>weboffice.template=</code><code>""</code><code>;</code>

<code>            </code><code>weboffice.filename=</code><code>this</code><code>.filename;</code>

<code>            </code><code>weboffice.filetype=</code><code>this</code><code>.filetype;</code>

<code>            </code><code>weboffice.edittype=</code><code>"1"</code><code>;</code>

<code>            </code><code>weboffice.username=</code><code>"system"</code><code>;</code>

<code>            </code><code>weboffice.webopen();   </code><code>//打开该文档    </code>

<code>            </code><code>window.status=weboffice.status;</code>

<code>        </code><code>}</code><code>catch</code><code>(e){</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"打开文档过程中发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>showmenu:</code><code>function</code><code>(bool){</code>

<code>            </code><code>this</code><code>.weboffice.showmenu=bool?</code><code>"1"</code><code>:</code><code>"0"</code><code>;</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"设置菜单显示状态时发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>addmenus:</code><code>function</code><code>(menuarray){</code>

<code>        </code><code>try</code>

<code>        </code><code>{</code>

<code>            </code><code>var</code> <code>menu=ext.getdom(</code><code>'menueventscript'</code><code>);</code>

<code>            </code><code>for</code><code>(</code><code>var</code> <code>i=1;i&lt;=menuarray.length;++i){</code>

<code>                </code><code>if</code><code>(menuarray[i-1]==</code><code>"save"</code><code>){</code>

<code>                    </code><code>this</code><code>.weboffice.appendmenu(i,</code><code>"保存"</code><code>);</code>

<code>                    </code><code>menu.text+=</code><code>"if(index=="</code><code>+i+</code><code>"){ext.getdom('cweboffice').websave();}"</code><code>;   </code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>(menuarray[i-1]==</code><code>"saveas"</code><code>){</code>

<code>                    </code><code>this</code><code>.weboffice.appendmenu(i,</code><code>"另存为"</code><code>);</code>

<code>                    </code><code>menu.text+=</code><code>"if(index=="</code><code>+i+</code><code>"){ext.getdom('cweboffice').websavelocal();}"</code><code>;   </code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>(menuarray[i-1]==</code><code>"print"</code><code>){</code>

<code>                    </code><code>this</code><code>.weboffice.appendmenu(i,</code><code>"打印"</code><code>);</code>

<code>                    </code><code>menu.text+=</code><code>"if(index=="</code><code>+i+</code><code>"){ext.getdom('cweboffice').webopenprint();}"</code><code>;   </code>

<code>                </code><code>}</code><code>else</code> <code>if</code><code>(menuarray[i-1]==</code><code>"signature"</code><code>){</code>

<code>                    </code><code>this</code><code>.weboffice.appendmenu(i,</code><code>"电子签章"</code><code>);</code>

<code>                    </code><code>menu.text+=</code><code>"if(index=="</code><code>+i+</code><code>"){ext.getdom('cweboffice').webopensignature();}"</code><code>;   </code>

<code>                </code><code>}</code>

<code>            </code><code>}</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"创建菜单过程中发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>save:</code><code>function</code><code>(){</code><code>//保存到服务器</code>

<code>            </code><code>this</code><code>.weboffice.websave();</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"文档保存时发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>saveas:</code><code>function</code><code>(){</code><code>//另存到客户端</code>

<code>            </code><code>this</code><code>.weboffice.websavelocal();</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"文档另存时发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>print:</code><code>function</code><code>(){</code>

<code>            </code><code>this</code><code>.weboffice.webopenprint();</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"文档打印时发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>signature:</code><code>function</code><code>(type){</code><code>//打开电子签章操作窗口</code>

<code>            </code><code>if</code><code>(arguments.length&gt;0){</code>

<code>                </code><code>this</code><code>.weboffice.webopensignature(type);</code>

<code>            </code><code>}</code><code>else</code><code>{</code>

<code>                </code><code>this</code><code>.weboffice.webopensignature();</code>

<code>            </code><code>ext.msg.alert(</code><code>"系统提示"</code><code>,</code><code>"打开电子签章窗口时发生错误,错误信息:"</code><code>+e.message);</code>

<code>    </code><code>}</code>

<code>    </code> 

<code>});</code>

这里继承了ext的observable类方便对于事件管理(这里由于只是简单的演示因此事件部分注释掉了,需要的话可以加上)。首先在构造函数部分取得weboffice对象,getobject()方法用户向外部公开此对象。文档加载在load()方法中,从代码可以看出打开一个文档只需要设置weburl(后台http接口)、filename(文件名)和filetype(文件类型)属性,然后调用webopen()方法。值得一提的是addmenus()方法,这个方法用于创建菜单,但是注意菜单的创建是通过动态构建js动态创建的。正常使用菜单的方法是页面添加如下脚本(这里用到了控件的"onmenuclick"事件):

<code>&lt;script language=</code><code>"javascript"</code> <code>for</code><code>=weboffice event=</code><code>"onmenuclick(vindex,vcaption)"</code><code>&gt;</code>

<code>alert(</code><code>'编号:'</code><code>+vindex+</code><code>'\n\r'</code><code>+</code><code>'条目:'</code><code>+vcaption+</code><code>'\n\r'</code><code>+</code><code>'请根据这些信息编写菜单具体功能'</code><code>);</code>

<code>    </code><code>if</code> <code>(vindex==10){ …};</code>

<code>if</code> <code>(vindex==11){ …};</code>

<code>    </code><code>…</code>

<code>&lt;/script&gt;</code>

然后通过调用weboffice的appendmenu()方法进行添加:

<code>webform.weboffice.appendmenu(</code><code>"10"</code><code>,</code><code>"测试菜单一"</code><code>);</code>

<code>webform.weboffice.appendmenu(</code><code>"11"</code><code>,</code><code>"测试菜单二"</code><code>);</code>

<code>webform.weboffice.appendmenu(</code><code>"12"</code><code>,</code><code>"-"</code><code>);</code>

<code>webform.weboffice.appendmenu(</code><code>"13"</code><code>,</code><code>"测试菜单四"</code><code>);</code>

<code>webform.weboffice.appendmenu(</code><code>"14"</code><code>,</code><code>"测试菜单五"</code><code>);</code>

<code>//其中:“-”表示分割线,增加的顺序是在现有按钮的最前面。</code>

<code>webform.weboffice.appendmenu(</code><code>"主菜单"</code><code>,</code><code>""</code><code>);</code><code>//添加主菜单:</code>

<code>webform.weboffice.appendmenu(</code><code>"15"</code><code>,</code><code>"测试菜单七(&amp;c)"</code><code>);</code>

<code>webform.weboffice.appendmenu(</code><code>"16"</code><code>,</code><code>"测试菜单八(&amp;d)"</code><code>);</code>

在weboffice类中这部分代码及判断逻辑由js动态构建,实现菜单的可定制化。

其他方法都比较简单,这里不再赘余。有了这个weboffice.js类之后只需要简单调用即可:

<code>ext.onready(</code><code>function</code><code>(){</code>

<code>    </code><code>var</code> <code>menus=[</code><code>"save"</code><code>,</code><code>"saveas"</code><code>,</code><code>"print"</code><code>,</code><code>"signature"</code><code>];</code>

<code>    </code><code>weboffice.addmenus(menus);</code>

<code>    </code><code>weboffice.load();</code>

前端代码完成了,但是服务器端如何配合前端处理呢,下面的服务器端处理类officeserver:

<code>using</code> <code>system;</code>

<code>using</code> <code>system.data;</code>

<code>using</code> <code>system.configuration;</code>

<code>using</code> <code>system.collections;</code>

<code>using</code> <code>system.web;</code>

<code>using</code> <code>system.web.security;</code>

<code>using</code> <code>system.web.ui;</code>

<code>using</code> <code>system.web.ui.webcontrols;</code>

<code>using</code> <code>system.web.ui.webcontrols.webparts;</code>

<code>using</code> <code>system.web.ui.htmlcontrols;</code>

<code>using</code> <code>system.io;</code>

<code>using</code> <code>system.text;</code>

<code>using</code> <code>dbstep;</code>

<code>namespace</code> <code>digitalsignature.weboffice</code>

<code>{</code>

<code>    </code><code>public</code> <code>partial</code> <code>class</code> <code>officeserver : system.web.ui.page</code>

<code>    </code><code>{</code>

<code>        </code><code>private</code> <code>imsgserver2000 msgserver =</code><code>null</code><code>;</code><code>//服务器端weboffice控件</code>

<code>        </code><code>private</code> <code>const</code> <code>string</code> <code>_filepath =</code><code>@"document\"</code><code>;</code>

<code>        </code><code>private</code> <code>const</code> <code>string</code> <code>_signaturefilepath =</code><code>@"signature\"</code><code>;</code>

<code>        </code><code>private</code> <code>string</code> <code>mmarklist =</code><code>"kenshincui"</code><code>;</code>

<code>        </code><code>private</code> <code>byte</code><code>[] mfilebody =</code><code>null</code><code>;</code><code>//签章信息</code>

<code>        </code><code>private</code> <code>string</code> <code>moption;</code>

<code>        </code><code>private</code> <code>string</code> <code>mrecordid;</code>

<code>        </code><code>private</code> <code>string</code> <code>mtemplate;</code>

<code>        </code><code>private</code> <code>string</code> <code>mfilename;</code>

<code>        </code><code>private</code> <code>string</code> <code>mfiletype;</code>

<code>        </code><code>private</code> <code>string</code> <code>mhtmlname;</code>

<code>        </code><code>private</code> <code>string</code> <code>mdirectory;</code>

<code>        </code><code>private</code> <code>string</code> <code>mlabelname;</code>

<code>        </code><code>private</code> <code>string</code> <code>mimagename;</code>

<code>        </code><code>private</code> <code>string</code> <code>mcommand;</code>

<code>        </code><code>protected</code> <code>void</code> <code>page_load(</code><code>object</code> <code>sender, eventargs e)</code>

<code>            </code><code>string</code> <code>mfilepath;</code>

<code>            </code><code>string</code> <code>templatefilepath;</code>

<code>            </code><code>msgserver =</code><code>new</code> <code>imsgserver2000();</code>

<code>            </code><code>string</code> <code>currentpath =</code><code>"."</code><code>;</code>

<code>            </code><code>msgserver.msgvariant(request.binaryread(request.contentlength));</code>

<code>            </code><code>mfilepath = configurationmanager.appsettings[</code><code>"tempfile"</code><code>];  </code><code>//取得文档的存放路径</code>

<code>            </code><code>templatefilepath = configurationmanager.appsettings[</code><code>"template"</code><code>];</code><code>//取得存放模版文件的路径</code>

<code>            </code><code>if</code> <code>(mfilepath +</code><code>""</code> <code>==</code><code>""</code><code>)</code>

<code>            </code><code>{</code>

<code>                </code><code>mfilepath = server.mappath(</code><code>"/"</code><code>) +_filepath;</code>

<code>            </code><code>currentpath = mfilepath;</code>

<code>            </code><code>string</code> <code>n = msgserver.getmsgbyname(</code><code>"dbstep"</code><code>);</code>

<code>            </code><code>if</code> <code>(n.equals(</code><code>"dbstep"</code><code>))</code>

<code>                </code><code>moption = msgserver.getmsgbyname(</code><code>"option"</code><code>);</code>

<code>                </code><code>if</code> <code>(moption.equals(</code><code>"loadfile"</code><code>))                    </code><code>//请求调用文档</code>

<code>                </code><code>{</code>

<code>                    </code><code>mrecordid = msgserver.getmsgbyname(</code><code>"recordid"</code><code>);    </code><code>//取得文档编号</code>

<code>                    </code><code>mfilename = msgserver.getmsgbyname(</code><code>"filename"</code><code>);    </code><code>//取得文档名称</code>

<code>                    </code><code>mfiletype = msgserver.getmsgbyname(</code><code>"filetype"</code><code>);    </code><code>//取得文档类型</code>

<code>                    </code><code>mfilepath = mfilepath + mfilename;  </code><code>//取得文档完整路径和名称</code>

<code>                    </code><code>if</code> <code>(!path.hasextension(mfilepath))</code>

<code>                    </code><code>{</code>

<code>                        </code><code>mfilepath += mfiletype;</code>

<code>                    </code><code>}</code>

<code>                    </code><code>msgserver.msgtextclear();</code>

<code>                    </code><code>if</code> <code>(msgserver.msgfileload(mfilepath))  </code><code>//调入文档</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"打开成功!"</code><code>); </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>""</code><code>);                    </code><code>//清除错误信息</code>

<code>                    </code><code>else</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"打开失败!"</code><code>);       </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"savefile"</code><code>))                   </code><code>//请求保存文档</code>

<code>                    </code><code>if</code> <code>(msgserver.msgfilesave(mfilepath))              </code><code>//保存文档内容</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"保存成功!"</code><code>); </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"保存失败!"</code> <code>+ mfilename);       </code><code>//设置错误信息</code>

<code>                    </code><code>msgserver.msgfileclear();</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"loadtemplate"</code><code>))               </code><code>//请求调用模板文档</code>

<code>                    </code><code>mtemplate = msgserver.getmsgbyname(</code><code>"template"</code><code>);    </code><code>//取得文档编号</code>

<code>                    </code><code>mfilepath = currentpath;</code>

<code>                    </code><code>mcommand = msgserver.getmsgbyname(</code><code>"command"</code><code>);</code>

<code>                    </code><code>if</code> <code>(mcommand.equals(</code><code>"insertfile"</code><code>))</code>

<code>                        </code><code>msgserver.msgtextclear();</code>

<code>                        </code><code>if</code> <code>(msgserver.msgfileload(mfilepath + mtemplate))  </code><code>//调入模板文档</code>

<code>                        </code><code>{</code>

<code>                            </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"打开模板成功!"</code><code>);       </code><code>//设置状态信息</code>

<code>                            </code><code>msgserver.msgerror(</code><code>""</code><code>);                    </code><code>//清除错误信息</code>

<code>                        </code><code>}</code>

<code>                        </code><code>else</code>

<code>                            </code><code>msgserver.msgerror(</code><code>"打开模板失败!"</code><code>);     </code><code>//设置错误信息</code>

<code>                        </code><code>mfilepath = templatefilepath + mtemplate + mfiletype;  </code><code>//取得文档完整路径和名称</code>

<code>                        </code><code>file.setattributes(mfilepath, fileattributes.normal);</code>

<code>                        </code><code>if</code> <code>(msgserver.msgfileload(mfilepath))          </code><code>//调入模板文档</code>

<code>                        </code><code>file.setattributes(mfilepath, fileattributes.readonly | fileattributes.archive | fileattributes.compressed);</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"savetemplate"</code><code>))               </code><code>//请求保存模板文档</code>

<code>                    </code><code>mfilepath = templatefilepath + mtemplate + mfiletype;  </code><code>//取得文档完整路径和名称</code>

<code>                    </code><code>file.setattributes(mfilepath, fileattributes.normal);</code>

<code>                    </code><code>if</code> <code>(msgserver.msgfilesave(mfilepath))          </code><code>//调入模板文档</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"保存模板成功!"</code><code>);       </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"保存模板失败!"</code><code>);     </code><code>//设置错误信息</code>

<code>                    </code><code>file.setattributes(mfilepath, fileattributes.readonly | fileattributes.archive | fileattributes.compressed);</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"updatefile"</code><code>))                         </code><code>//请求保存文档</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"保存成功!"</code><code>);     </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"保存失败!"</code><code>);       </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"insertfile"</code><code>))                     </code><code>//请求调用正文文档</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"插入文件成功!"</code><code>);   </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"插入文件失败!"</code><code>);     </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"insertimage"</code><code>))        </code><code>//请求调用正文文档</code>

<code>                    </code><code>mlabelname = msgserver.getmsgbyname(</code><code>"lablename"</code><code>);         </code><code>//标签名</code>

<code>                    </code><code>mimagename = msgserver.getmsgbyname(</code><code>"imagename"</code><code>);         </code><code>//图片名</code>

<code>                    </code><code>mfilepath = mfilepath + mimagename;       </code><code>//图片在服务器的完整路径</code>

<code>                    </code><code>mfiletype = mimagename.substring(mimagename.length - 4, 4).tolower(); </code><code>//取得文件的类型</code>

<code>                    </code><code>if</code> <code>(msgserver.msgfileload(mfilepath))          </code><code>//调入图片</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"imagetype"</code><code>, mfiletype);    </code><code>//指定图片的类型</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"position"</code><code>, mlabelname);    </code><code>//设置插入的位置[书签对象名]</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"插入图片成功!"</code><code>);     </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"插入图片失败!"</code><code>);         </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"saveashtml"</code><code>))</code>

<code>                    </code><code>mhtmlname = msgserver.getmsgbyname(</code><code>"htmlname"</code><code>);    </code><code>//取得标签文档内容</code>

<code>                    </code><code>mdirectory = msgserver.getmsgbyname(</code><code>"directory"</code><code>);           </code><code>//取得标签文档内容</code>

<code>                    </code><code>if</code> <code>(mdirectory.equals(</code><code>""</code><code>))</code>

<code>                        </code><code>mfilepath = mfilepath +</code><code>"\\html"</code><code>;</code>

<code>                        </code><code>mfilepath = mfilepath +</code><code>"\\html\\"</code> <code>+ mdirectory;</code>

<code>                    </code><code>msgserver.makedirectory(mfilepath);</code>

<code>                    </code><code>if</code> <code>(msgserver.msgfilesave(mfilepath +</code><code>"\\"</code> <code>+ mhtmlname))</code>

<code>                        </code><code>string</code> <code>txt = msgserver.msgtextbody();</code>

<code>                        </code><code>byte</code><code>[] bitebody = getfilebody(mfilepath +</code><code>"\\"</code> <code>+ mhtmlname);</code>

<code>                        </code><code>encoding encode = encoding.getencoding(</code><code>"gb2312"</code><code>);</code>

<code>                        </code><code>string</code> <code>html = encode.getstring(bitebody);</code>

<code>                        </code><code>msgserver.msgerror(</code><code>""</code><code>);                              </code><code>//清除错误信息</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"保存成功"</code><code>);         </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"保存失败"</code> <code>+ mfilepath +</code><code>"\\"</code> <code>+ mhtmlname);                      </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"saveimage"</code><code>))</code>

<code>                        </code><code>mfilepath = mfilepath +</code><code>"\\htmlimage"</code><code>;</code>

<code>                        </code><code>mfilepath = mfilepath +</code><code>"\\htmlimage\\"</code> <code>+ mdirectory;</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"保存失败"</code><code>);                      </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"loadmarklist"</code><code>))</code><code>//获取电子印章列表</code>

<code>                    </code><code>if</code> <code>(loadmarklist())</code>

<code>                    </code><code>{                                  </code><code>//获得列表信息mmarklist</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"marklist"</code><code>, mmarklist);             </code><code>//显示签章列表(多个之间用换行符\r分割)</code>

<code>                        </code><code>msgserver.msgerror(</code><code>""</code><code>);                            </code><code>//清除错误信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"创建印章列表失败!"</code><code>);                   </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"loadmarkimage"</code><code>))</code><code>//打开印章文件</code>

<code>                    </code><code>string</code> <code>mmarkname = msgserver.getmsgbyname(</code><code>"imagename"</code><code>);            </code><code>//取得签名名称</code>

<code>                    </code><code>string</code> <code>musername = msgserver.getmsgbyname(</code><code>"username"</code><code>);             </code><code>//取得用户名称</code>

<code>                    </code><code>string</code> <code>mpassword = msgserver.getmsgbyname(</code><code>"password"</code><code>);             </code><code>//取得用户密码</code>

<code>                    </code><code>msgserver.msgtextclear();                              </code><code>//清除文本信息</code>

<code>                    </code><code>if</code> <code>(loadmarkimage(mmarkname, mpassword))</code>

<code>                        </code><code>//调入签名信息mfilebody</code>

<code>                        </code><code>//msgserver.setmsgbyname("imagetype", mfiletype);           //设置签名类型</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"imagetype"</code><code>,</code><code>".jpg"</code><code>);           </code><code>//设置签名类型</code>

<code>                        </code><code>msgserver.msgfilebody(mfilebody);                      </code><code>//将签名信息打包</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"position"</code><code>,</code><code>"manager"</code><code>);         </code><code>//设置插入位置</code>

<code>                        </code><code>msgserver.setmsgbyname(</code><code>"status"</code><code>,</code><code>"打开成功!"</code><code>);             </code><code>//设置状态信息</code>

<code>                        </code><code>msgserver.msgerror(</code><code>"签名或密码错误!"</code><code>);                </code><code>//设置错误信息</code>

<code>                </code><code>else</code> <code>if</code> <code>(moption.equals(</code><code>"savesignature"</code><code>))</code><code>//保存签章信息</code>

<code>                    </code><code>//mrecordid = msgserver.getmsgbyname("recordid");               //取得文档编号</code>

<code>                    </code><code>//mfilename = msgserver.getmsgbyname("filename");               //取得文件名称</code>

<code>                    </code><code>//mmarkname = msgserver.getmsgbyname("markname");               //取得签名名称</code>

<code>                    </code><code>//musername = msgserver.getmsgbyname("username");               //取得用户名称</code>

<code>                    </code><code>//mdatetime = msgserver.getmsgbyname("datetime");               //取得签名时间</code>

<code>                    </code><code>//mhostname = request.getremoteaddr();                      //取得用户ip</code>

<code>                    </code><code>//mmarkguid = msgserver.getmsgbyname("markguid");               //取得唯一编号</code>

<code>                    </code><code>//msgserver.msgtextclear();                             //清除文本信息</code>

<code>                    </code><code>//if (savesignature())</code>

<code>                    </code><code>//{                                 //保存签章信息进数据库</code>

<code>                    </code><code>//    msgserver.setmsgbyname("status", "保存印章成功!");          //设置状态信息</code>

<code>                    </code><code>//    msgserver.msgerror("");                               //清除错误信息</code>

<code>                    </code><code>//}</code>

<code>                    </code><code>//else</code>

<code>                    </code><code>//{</code>

<code>                    </code><code>//    msgserver.msgerror("保存印章失败!");                        //设置错误信息</code>

<code>            </code><code>else</code>

<code>                </code><code>msgserver.msgerror(</code><code>"error:packet message"</code><code>);</code>

<code>                </code><code>msgserver.msgtextclear();</code>

<code>                </code><code>msgserver.msgfileclear();</code>

<code>            </code> 

<code>            </code><code>response.binarywrite(msgserver.msgvariant());</code>

<code>            </code><code>response.end();</code>

<code>        </code><code>private</code> <code>bool</code> <code>loadmarkimage(</code><code>string</code> <code>mmarkname,</code><code>object</code> <code>mpassword)</code>

<code>            </code><code>if</code> <code>(signature.hasright(session[</code><code>"username"</code><code>]+</code><code>""</code><code>,mpassword.tostring()))</code>

<code>                </code><code>string</code> <code>picpath = server.mappath(</code><code>"/"</code><code>) + _signaturefilepath + mmarkname +</code><code>".jpg"</code><code>;</code>

<code>                </code><code>mfilebody = file.readallbytes(picpath);</code>

<code>                </code><code>return</code> <code>true</code><code>;</code>

<code>                </code><code>return</code> <code>false</code><code>;</code>

<code>        </code><code>private</code> <code>bool</code> <code>loadmarklist()</code>

<code>            </code><code>string</code> <code>tmarklist = signature.getmasklist();  </code><code>//印章列表</code>

<code>            </code><code>if</code> <code>(tmarklist +</code><code>""</code> <code>!=</code><code>string</code><code>.empty)</code>

<code>                </code><code>mmarklist = tmarklist;</code>

<code>        </code><code>private</code> <code>byte</code><code>[] getfilebody(</code><code>string</code> <code>strfullfilename)</code>

<code>            </code><code>byte</code><code>[] file =</code><code>new</code> <code>byte</code><code>[0];</code>

<code>            </code><code>fileinfo finfo =</code><code>new</code> <code>fileinfo(strfullfilename);</code>

<code>            </code><code>if</code> <code>(finfo.exists ==</code><code>true</code><code>)</code>

<code>                </code><code>if</code> <code>((finfo.attributes &amp; fileattributes.readonly) == fileattributes.readonly)</code>

<code>                    </code><code>file.setattributes(strfullfilename, fileattributes.archive);</code>

<code>            </code><code>file =</code><code>new</code> <code>byte</code><code>[finfo.length];</code>

<code>            </code><code>filestream fs =</code><code>new</code> <code>filestream(strfullfilename, filemode.open);</code>

<code>            </code><code>fs.read(file, 0, (</code><code>int</code><code>)finfo.length);</code>

<code>            </code><code>fs.close();</code>

<code>            </code><code>return</code> <code>file;</code>

<code>}</code>

服务器端主要通过imsgserver2000对象进行同前端的交互,前端执行某些操作时(注意是某些操作,并非所有操作都同服务器端交互,具体见iweboffice白皮书)会向后端发送一个消息,服务器端通过imsgserver2000对象的getmsgbyname()方法可以接收参数并根据不同参数配合前端做出相应的处理。例如加载文档时,当前端js调用webopen()方法时就会向服务器端传递一个名为"option"的参数,通过这个参数可以判断要执行的操作类型,例如此时它的值等于"loadfile",服务器端就可以知道是要打开一个文档,当然此时也就知道它还会传递一些和打开文档相关的参数(例如filename、filetype)通过这些参数,服务器端构建一个完整的文件路径,然后调用msgfileload()方法加载此文档,这时客户端就会打开此文档。当然,其他还有很多类似的操作,但是原理都是一样的,包括今天要说的电子签章。下面先看一下文档加载的后的截图:

使用iWebOffice实现电子签章

在iweboffice中一个电子签章操作包括三个交互过程,分别是:加载签章列表(loadmarklist)、加载签章文件(loadmarkimage)、保存签章信息(savesignature)。

loadmarklist是加载签章列表的过程,在这个过程中服务器端需要通过imsgserver2000对象的setmsgbyname()方法给客户端传递一个列表字符串(多个签章中间用换行符分割)。

loadmarkimage是加载签章文件的过程,有了签章名称客户端就可以选择相应的签章,但是选择了签章名称之后需要加载对应的签章文件(事实上是一个图片),加载签章文件的过程就发生这个阶段。在这个过程中服务器端的任务就是根据签章名称加载对应的文件,然后使用imsgserver2000对象的msgfilebody()方法将文件的字节流返回给客户端。注意这个过程中客户端需要输入密码,因此签章的权限验证部分可以在此进行处理。

savesignature是保存签章信息的过程,对于签章操作后的信息可以在此时进行保存(例如文档编号、文件名称、签章名称、签章日期等可以在此时记录到数据库),在本例中由于没有使用数据库因此就不对签章信息进行保存了。

这三个过程处理好之后,客户端使用时只需要调用weboffice对象的webopensignature()方法即可调出电子签章管理界面,下面是界面窗口:

使用iWebOffice实现电子签章

通过上面的窗口可以看出,在iweboffice中电子签章的不仅包括印章还包括签名、批注。从签章列表中选择一个签章,然后输入密码,点"盖章",此时就会从服务器端加载对应的签章文件:

使用iWebOffice实现电子签章

点击确定就可以添加到文档中:

使用iWebOffice实现电子签章

在看两张手写签名效果:

使用iWebOffice实现电子签章
使用iWebOffice实现电子签章

当然添加过签章之后需要对文档进行保存,不过注意文档保存到客户端还是服务器端,在本例中的"保存"是将文档在服务器端进行保存,"另存为"即保存到客户端。

使用iWebOffice实现电子签章