反馈已提交

网络繁忙

iframe框架自适应报表高度

  • 文档创建者:文档助手1
  • 历史版本:32
  • 最近更新:Leo.Tsai 于 2022-08-22
  • 1. 概述

    1.1 问题描述

    将报表集成至 Web 页面中时,报表往往只是作为页面的某一部分嵌入在一个框架中如 iframe 中显示出来。

    由于报表每页数据是不定的,在最后一页可能只有几条数据,此时 iframe 框架将留有大片的空白,造成空间的浪费也使得界面不美观。

    这个时候我们就会希望,要是 iframe 框架大小能够根据报表页面的内容自动调整高度或宽度,如下图效果:

    222

    当页面记录数较少,此时 iframe 框架高度变小,如下图:

    222

    1.2 实现思路

    主要思路如下通过网页加载结束事件监听报表页面的高度,进而设置所在 iframe 框架的高度,即可实现 iframe 框架高度根据报表内容来自适应了。

    2. 操作步骤

    2.1 实现翻页功能

    可参考 自定义翻页按钮

    具体使用代码如下:

    <div id="toolbar">  
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoFirstPage();" value="首页"></input>  
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoPreviousPage();" value="上一页"></input>  
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoNextPage();" value="下一页"></input>   
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoLastPage();" value="末页"></input>  
    </div>

    2.2 添加监听

    我们需要获取服务器返回给浏览器的页面,因此需要添加一个监听看浏览器是否已经将结果加载完毕。添加监听的方法为contentPane.on("afterload",function(){});

    注:若存在跨域调用 iframe 的时候,会被浏览器禁止,需要进行中转,具体操作方法请参照 JS 跨域调用

    2.3 设置 iframe 框架高度

    一旦发现浏览器已经将结果加载完毕,我们便可以获取结果如最后一页数据有多少行,遍历每行获得高度并进行累计,将最终需要的高度(像素 px 为单位)赋给框架。

    for(var i = 0;i<tr.length;i++){
    //由于报表页面加载完成之后,可能会将单元格也在加载成一个 tr,会导致重复计算,这里通过条件判断来获取行的 tr
    if(tr[i].id.substring(0,1)=="r"){
    height = height + tr[i].offsetHeight;
    }
    }
    reportFrame.height = height;

    注:由于报表在计算解析成 HTML 的时候,可能会将单元格也解析成为一个 tr,所以需要遍历所有 tr 判断一下单元格是否被解析为一个 tr。

    实现如上效果,请看下面完整的页面代码。

    2.4 页面 auto.html 完整代码

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">  
    <html>  
        <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
        <title>Demo</title>  
        </head>  
        <script type="text/javascript">  
        // 由于gotoNextPage()等方法调用后,后台服务器返回结果需要一定的时间,而我们需要获得返回结果中的行  
        // 因此添加监听,contentPane.on("afterload",function(){}):当选择页加载完毕后调用 setframeHeight 方法获取行数及高度从而调整框架大小  
        window.onload=function(){  
        var contentPane = document.getElementById('reportFrame').contentWindow._g();  
        contentPane.on("afterload",function(){  
        setframeHeight();  
        });  
        }  
        function setframeHeight(){  
        var reportFrame = document.getElementById('reportFrame');  
        // 获得页面中的所有行  
        var tr = reportFrame.contentWindow.document.getElementsByTagName("tr");
      //为了避免报表加载结束后出现滚动条现象,这里将报表容器的 overflow 属性设置为 hidden
      //由于在报表容器属性的设置只能在报表计算之后,所以用 setTimeout 来设置延迟执行时间,如果数据过多,请按照具体情况修改延迟时间
      setTimeout(function(){document.getElementById('reportFrame').contentWindow.document.getElementById("content-container").style.overflow="hidden";},10)
        // 由于报表页面还存在页边距,因此框架高度是大于所有行累计的高度的,这里赋一个初始值以表示边距的大小  
        var height = 30;  
        for(var i = 0;i<tr.length;i++){  
        //由于报表页面加载完成之后,可能会将单元格也在加载成一个 tr,会导致重复计算,这里通过条件判断来获取行的 tr  
        if(tr[i].id.substring(0,1)=="r"){  
        height = height + tr[i].offsetHeight;  
        }     
        }  
        reportFrame.height = height;  
        }   
        </script> 
        <body >   
        <div id="toolbar">  
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoFirstPage();" value="首页"></input>  
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoPreviousPage();" value="上一页"></input>  
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoNextPage();" value="下一页"></input>   
        <input type="button" onclick="document.getElementById('reportFrame').contentWindow._g().gotoLastPage();" value="末页"></input>  
        </div>  
        <iframe id="reportFrame" src="../../decision/view/report?viewlet=/doc/Primary/DetailReport/Details.cpt&__showtoolbar__=false" width = 100% height = 80% frameborder="0" ></iframe>
      <p>页面其他部分</p>
      </body>
    <html>

    2.5 window.onload 无法获取 contentPane

    在实际开发中,发现 contentPane.on(event, function(){});事件无法执行,原因在于以上代码执行过程中 contenPane 这个对象是 undefined,这里我提供两种思路供大家参考。

    修改页面代码:

    <script type="text/javascript"> 
        window.onload=function(){
        //实现思路就是让这个页面加载完毕包括数据都显示的时候,再执行核心代码
        //此处的延时2s根据实际情况进行修改,页面会有些卡顿
       setTimeout(function(){
           var reportFrame = document.getElementById('reportFrame');  
              // 获得页面中的所有行  
              var tr = reportFrame.contentWindow.document.getElementsByTagName("tr");
             //为了避免报表加载结束后出现滚动条现象,这里将报表容器的 overflow 属性设置为 hidden
             //这里直接设置报表容器属性
             document.getElementById('reportFrame').contentWindow.document.getElementById("content-container").style.overflow="hidden";
               // 由于报表页面还存在页边距,因此框架高度是大于所有行累计的高度的,这里赋一个初始值以表示边距的大小  
               var height = 30;  
               for(var i = 0;i<tr.length;i++){  
               //由于报表页面加载完成之后,可能会将单元格也在加载成一个 tr,会导致重复计算,这里通过条件判断来获取行的 tr  
               if(tr[i].id.substring(0,1)=="r"){  
                   height = height + tr[i].offsetHeight;  
               }    
           }  
           reportFrame.height = height;
       }, 2000);
       }
    </script>

    注:在报表的“加载结束”中获取报表的高度,然后将报表高度传给父页面在页面初始化过程中调整 firame 的高度,页面加载会比较流畅。

    2.6 预览效果

    启动工程,输入http://localhost:8075/webroot/help/page_demo/auto.html,效果如下图:

    222

    支持在移动端查看页面,只需要将上述地址中 localhost 换成服务器 IP,然后通过 URL 在移动端访问即可。

    Screenshot_20220822_174829_com.tencent.wework.jpg

    3. 注意事项

    此文档中:2.1,2.2,2.3 为功能步骤,可先行研究其功能步骤后。再对 2.4 主页面代码进行查看看。

    附件列表


    主题: 部署集成
    已经是第一篇
    已经是最后一篇
    • 有帮助
    • 没帮助
    • 只是浏览
    中文(简体)

    鼠标选中内容,快速反馈问题

    鼠标选中存在疑惑的内容,即可快速反馈问题,我们将会跟进处理。

    不再提示

    10s后关闭



    AI

    联系我们
    在线支持
    获取专业技术支持,快速帮助您解决问题
    工作日9:00-12:00,13:30-17:30在线
    页面反馈
    针对当前网页的建议、问题反馈
    售前咨询
    采购需求/获取报价/预约演示
    或拨打: 400-811-8890 转1
    qr
    热线电话
    咨询/故障救援热线:400-811-8890转2
    总裁办24H投诉:17312781526
    提交页面反馈
    仅适用于当前网页的意见收集,帆软产品问题请在 问答板块提问前往服务平台 获取技术支持