hur.cn - 华软网

 热门搜索

[原创文章]使用Web Datawindow ActiveX实现Web页面的打印功能

  作者:未知    来源:网络    更新时间:2019/4/16
想起以前说过要把Web Datawindow ActiveX运用经验整理后发出来,由于项目实在是太忙,又想偷懒一直没搞。
转眼间2006快过去了,今年的事情照旧把它做了吧。

    其实,运用ActiveX自身实在是没有什么难度,Datawindow大家都很熟悉。这也是我没有把它写下来的动力的原因之一。不过在实施进程中,确实还遇到过一些问题,也有一些心得,也另有解决不了的问题存留。我就做个总结吧,今天吃的对照饱,有些絮絮叨叨,希望大家忍了,哈哈。

    大家都知道,Web页面中做打印一般就两种方法:
    首先是写纯Web的打印,也就是运用Web自己的打印功能,用ExecWB命令,直接打印页面。说实在的我对HTML的语法是有些怵的,也只可算小半桶水,经过一些了解,知道直接做Web页面打印难度对我来说很大,尤其是你要实现多条理的分组合计等等功能。项目紧迫也没有这个时间。

    那接下来,只可选择客户端打印控件了,我还真想去买一个好的控件用用,那多好啊,代码能够写的少些,代码执行效率,开发效率肯定也高,惋惜我深知Boss的为人,这几K钱就给他省了吧。

    幸好我一直对PB的Web开发方案一直坚持着兴趣,自己在n年前从PB6.5起头起就研讨Web.PB,Window ActiveX,Datawindow ActiveX,到PowerJ,再到后来的Web Datawindow,虽然说,有些东东看起来象是玩具,有些么闭门造车,没法流行。不过勉为其难,土法上马照旧能够解决些问题的。

    本来Web Datawindow还象个样子,不过Web Datawindow需要EAServer的支持。那就罢了,只有选择Web Datawindow ActiveX了。说实在的,它作为一个Web客户端打印工具照旧非常好的,由于Datawindow功能是太强盛了,哪怕ActiveX没有包括 Datawindow全数的功能,然则也足够打印运用了。其弱点就是界面临照难看单调,配不上那绚丽的Web页面效果。
   
    进入正题。
    首先要说明一下,我选择的是PB10版本的ActiveX控件。由于据我尝试,从PB8到10都有些问题,PB8的ActiveX不支持WinXP, PB9的ActiveX居然是已经逾期了,IE上装不了(当然可能和我用盗版PB有关系,哦弥陀佛,罪过),而PB10是不支持Win98系统的。最后只可不论Win98了,横竖现在很少人用98了。
   
    首先必需有个页面来装置控件,把以下代码增加到html页面中。别忘记了将psdwc100.cab放到响应服务器目录下,由于Cab包对照大(2M多),这个页面作为一个独立的装置页面临照好。
    <OBJECT id="webdw" width="0" height="0" codeBase="/tmsweb/include/dwprint/psdwc100.cab#Version=10,0,1,3600" classid="CLSID:AAAA1503-AAAA-1000-8000-080009AC61A9" name="webdw">
  装置Web DataWindow控件失利!</OBJECT>

    页面写好了,宣布到Web服务器,在客户端访问这个页面,装置插件即可。

    接下来在打印页面w_print.jsp中引用此控件:
     <OBJECT id="dw_print" height="0" width="0" classid="CLSID:AAAA1503-AAAA-1000-8000-080009AC61A9" name="dw_print">
     <PARAM NAME="SourceFileName" VALUE="">
     </PARAM>
     <PARAM NAME="DataWindowObject" VALUE="">
     </PARAM>
     <PARAM NAME="SuppressEvents" VALUE="false">
     </PARAM>
     <PARAM NAME="VScrollBar" VALUE="true">
     </PARAM>
     <PARAM NAME="HScrollBar" VALUE="true">
     </PARAM>
     <PARAM NAME="HSplitScroll" VALUE="true">
     </PARAM>

     以下都是javacript剧本:
      然后,设置打印用的dataobject:
    dw_print.SourceFileName="/tmsweb/pdwo/trafficorder_record.pbd"
    dw_print.DataWindowObject="trafficorder_record"

    //我所运用的是有两个子报表的NestReport作为例子,其余报表更简单
    //这里猎取子报表控件
    dw_print.GetChild("dw_header")
    print_h=dw_print.GetChildObject()
    dw_print.GetChild("dw_detail")
    print_d=dw_print.GetChildObject()

    //起头填入打印用的数据
    //由于是ActiveX客户端控件,因此不方便直接连接数据库来取数据,所以我这里是首先通过Web的方式
    //猎取到打印用的数据到客户端的一个类似datawindow的对象中,然后复制给dw_print的。
    print_h.reset();print_d.reset()
    dw_header.rowscopy_a(1,1,print_h)
    dw_detail.rowscopy_a(1,dw_detail.rowcount(),print_d)
    其中,dw_header,dw_detail是页面中的htc客户端控件,rowscopy_a我想就不用解释了,后续会贴出其完整代码。

    在rowscopy后,如果还需要对dw_print中的某些字段赋值,则比如调用:
    setitem(print_h,1,"year_1",“2006”)
    其中setitem方法是一个js函数,稍后贴出其代码。

    现在,dw_print的子报表的数据都已经填充好了,能够预览打印了,
    由于这里是复合报表,datawindow自动预览的,因此就不需要设置预览属性了,
    如果是一般的grid类型窗口,最好是设置预览属性,这样能够看得出页面的巨细,打印页数等。
    设置的时候用dw_print.modify()方法,用dw_print.Object.DataWindow.Print.Preview的方式是不行的,
    Activex不支持。

    最后,就能够打印了。
    if (confirm("是否打印?"))
        {
            dw_print.print(false)
        }
   
    很简单,是否是?

    附录:
    setitem方法:
    function setitem(dw_print,row,column,value)
{
    var datavalue,datatype
   
    datatype = dw_print.Describe(column+".Coltype")
           
    if (datatype.indexOf("char",0)>=0)
    {
        datavalue=value
    }else if (datatype.indexOf("decimal",0)>=0 || datatype.indexOf("number",0)>=0||datatype.indexOf("long",0)>=0)
    {
        datavalue=parseFloat(value)
    }else if (datatype.indexOf("integer",0)>=0)
    {
        datavalue=parseInt(value)
    }else if (datatype.indexOf("date",0)>=0)
    {
        alert("有系统不支持的Date,Datetime类型["+column+"],请检查打印数据源")
    }else
    {
        datavalue=value
    }
   
    dw_print.setitem(row,column,datavalue);
}

rowscopy_a方法:
function RowsCopy_A(ai_start,ai_end,aobj_dw)
{
    var ll_columncount
    var datatype
    var datavalue
   
    if (ai_start<=0) return -1;
    if (ai_end >RowCount()) ai_end=RowCount();
   
    ll_columncount=getColumnCount();
    for (var i=ai_start;i<=ai_end;i++)
    {
        row=aobj_dw.insertrow(0);   
        for (var k=0;k<ll_columncount;k++)
        {           
            if ((Columns[k].ColumnType!=null)&&
                (Columns[k].ColumnType.Trim().toLowerCase()=="computed")&&
                (typeof(Columns[k].ColumnType)!="undefined")) continue               
            datatype = aobj_dw.Describe(Columns[k].ColumnName+".Coltype")
            if (datatype.indexOf("char",0)>=0)
            {
                datavalue=getItemWithID(i,k+1)
            }else if (datatype.indexOf("decimal",0)>=0 || datatype.indexOf("number",0)>=0||datatype.indexOf("long",0)>=0)
            {
                datavalue=parseFloat(getItemWithID(i,k+1))
            }else if (datatype.indexOf("integer",0)>=0)
            {
                datavalue=parseInt(getItemWithID(i,k+1))
            }else if (datatype.indexOf("date",0)>=0)
            {
                alert("有系统不支持的Date,Datetime类型["+Columns[k].ColumnName+"],请检查打印数据源")
            }else
            {
                datavalue=getItemWithID(i,k+1)
            }
            datavalue = getDisplayValue(row,Columns[k].ColumnName,datavalue)
            aobj_dw.setitem(row,Columns[k].ColumnName,datavalue);
        }
    }
    return 1;
}

这里要说明一下,现在维一解决不了的问题是,我在javascript中没法找到一个类型能够匹配Datawindow的datatime类型列,而如果不转换直接赋值,是没有效果的。可能是我对javascript的研讨还不够吧?如果有那位兄弟知道解决措施,请告诉我。我现在只可在pbl中把 datatime列都先用convert转换为string类型。

   
大家也能够访问博客:  
http://blog.csdn.net/daixf_csdn/archive/2006/12/30/1469730.aspx  
 
另外,大家有没有分多的用不完的,捐一点给我吧,我都穷死了。现在学习java中,  
很多问题想问,可是没有分。  
先谢谢咯
------华软网友回答------
学习.
------华软网友回复------
楼主,养几个马甲,用它们的分问.
------华软网友回复------
比如我,就是.
------华软网友回复------
楼上的,这个方法我也想过,
不过天天都要登录太麻烦,好像又找不到自动登陆软件
自己写也没有时间。
------华软网友回复------
装两个浏览器,用自动登录.
------华软网友回复------
我现在是netscape+ie,两个号同时开.
------华软网友回复------
  class="deleted_message"> 该回复被版主删除
------华软网友回复------
mark
------华软网友回复------
对于datetime的措置惩罚我也没有搞定,不过如果不怕烦的话能够把年月日分成三个字段,需要显示的地方做成计算字段,应该算是一个临时解决方案吧:-(
------华软网友回复------
不知道楼主有没有用过ActiveX 的importfile方法,如果找出运用方法大家一起提高一下:D
------华软网友回复------
  class="deleted_message"> 该回复被版主删除
------华软网友回复------
试了一下运用importString方法,也不用什么楼主的rowscopy_A了,只需把一个多行文本变量导入进来就能够了!强烈推荐大家运用此法!
------华软网友回复------
试了一下运用importString方法,也不用什么楼主的rowscopy_A了,只需把一个多行文本变量导入进来就能够了!强烈推荐大家运用此法!
---
这个方法应该能够提高赋值效率,谢谢关注!
------华软网友回复------
不止提高效率,还能绕过datetime问题呢:D
顺便说几个问题:
1. daixf_csdn给我message说"datawindow activex的import方法不能用?",可能情况有下:
__1.我想你可能用的是importfile方法,我试过这个方法没有成功,但importString方法照旧成功的.
__2.importString是不能在设置完"DataWindowObject"马上调用的,如果这时调用则数据没法导入到一个没有完全"设置完格式"的数据窗口中.我试验出的解决方法有两个:
____1.运用javaScript的setInterval方法,直到能够描写出数据窗口的语法再clearInterval;
____2.运用AJAX技术,这个就不多说了,由于我照旧个外行人,只是临时解决了一下:(
2. 对于 datawindow ActiveX 其实不能提供跨浏览器支持,现在正在学习 openlaszlo ,不过这不是一个报表解决方案,而是RIA(Rich Internet Application)解决方案,它其实不擅长解决报表问题.再有的一个技术是java中的 birt ,还没有研讨,但这是一个专门解决报表问题的东东.
3. 有一个想法,能够把 datawindow ActiveX中加入数据操作功能(三层),只需要封装出其中的update,retrieve等方法就完全可能实现.
4. 照旧跨浏览器问题:用了“如意报表”就能够在firefox中通过ietab插件切换到ie内核时显示报表(实际上它也不能跨浏览器),而对于datawindow就不行,不知道是我机器的问题照旧写的程序有问题:(
------华软网友回复------
在做了上面回复之后又做了一篇文章下在面的地址,大家如果有兴趣能够去看一下:
################################
http://blog.csdn.net/renwanly/archive/2007/01/25/1493550.aspx
################################      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。