记录打印位置

在实际项目中,经常会遇到打印的需求,而对于打印的特殊需求也越来越多,例如需要记录上次打印位置,当前打印时根据上次的打印位置继续打印的功能,像银行的存折的数据每次打印都不是用新的纸张,而是根据上次打印的位置继续打印。

 

在润乾的打印功能中如何实现上述需求呢?

 

大致思路:首先润乾提供了打印后调用的js函数runqian_printOver(),打印结束后调用runqian_printOver()计算下这次打印的最后一页高度以及报表名称等相关参数统一插入到库里。再次访问时候,根据相关的字段取出相应的记录对当前raq插入空白一行并且设置行高存成新的raq文件,然后通过标签里面的printedRaq属性打印修改后的raq。来实现记录打印的功能。

 

首先随意准备一张可以展现多页数据的报表(增加了个参数模板,通过选择不同参数产生不同数据来模拟多次打印的功能)。

因为要进行打印记录的相关数据插入到数据库,创建一张数据库表用来存放报表名称、最后一页的行高、参数、状态等信息(具体需要插入哪些参数根据具体需求决定,例子中只用报表名称作为标识进行查询),表结构如下。

REPORTNAME          VARCHAR2(20)         Y

ROWHEIGHT            NUMBER                   Y

 

在展现报表前先要进行查询是否有打印记录,如果有的话读取行高数对当前报表进行插入一行并且设置行高再另存为一张新的raq,然后通过标签中的printedRaq属性(打印的报表,此属性用于显示报表和打印报表不同)打印修改后的raq。(由于此属性只能存放具体raq,所以不能使用reportdefine的形式,需要将报表对象另存为成一个raq文件)。如果没有记录则正常流程

//查询是否有过记录,如果有过记录取得最后一页行高插入到报表第一行,然后将新报表存放在标签里的printedRaq属性

           Connect connect = new Connect();

           ResultSet res = connect

                  .executeQuery(“select * from PRINTMEMORY t where t.reportname = ‘”

                         + report + “‘”);

           //如果数据库中没有记录则代表第一次打印,如果有记录进行计算

           if (res.next()) {

              //读取历史打印位置(行高)插入到报表第一行

              reportTemp = “temp” + report;

              float rowHeight = res.getFloat(“ROWHEIGHT”);

              System.out.println(“取历史打印位置:” + rowHeight);

              ReportDefine rd = (ReportDefine) ReportUtils.read(application

                     .getRealPath(reportFileHome + File.separator + report));

              rd.insertRow(1, 1);

              rd.getRowCell(1).setRowHeight(rowHeight);

              ReportUtils.write(application.getRealPath(reportFileHome

                     + File.separator + reportTemp), rd);

           } else {

              System.out.println(“第一次打印”);

              reportTemp = report;

           }

在打印结束后会自动调用润乾内置函数runqian_printOver(),重写runqian_printOver()函数内容,通过ajax或者直接嵌入java代码进行对数据库表插入或修改行高记录。

<script language=“javascript”>

    function runqian_printOver(){

       run();

    }

    //核心对象变量

    var xmlHttp;

    //区分浏览器创建XMLHttpRequest核心对象

    function create() {

       if (window.XMLHttpRequset) {

           xmlHttp = new XMLHttpRequest();

       } else if (window.ActiveXObject) {

           xmlHttp = new ActiveXObject(“Microsoft.XMLHTTP”);

       }

    }

    //ajax核心执行方法(此处为提交到servlet处理)

    function run() {

       create();

       var URL = “../servlet/PrintMemory?report=<%=reportTemp%>”;//后台逻辑处理,将打印的报表名传到后台

       xmlHttp.open(“POST”, URL, true);

       xmlHttp.onreadystatechange = callback;

       xmlHttp.send(null);

    }

    //回调函数

    function callback() {

       if (xmlHttp.readyState == 4) {

           if (xmlHttp.status == 200) {

              var v = xmlHttp.responseText;

           }

       }

    }

</script>

在后台servlet中进行行高的计算以及数据的更改:

传入参数为打印的报表(注意不是浏览的报表)即标签中printedRaq属性的报表名称,以及相关的参数。

然后通过pagebuilder进行分页计算,取最后一页,逐行遍历获取累计行高数。

        float rowHeight = 0;

       for (int i = 1; i <= ireport.getRowCount(); i++) {

           rowHeight = rowHeight + ireport.getRowCell(i).getRowHeight();

       }

最后根据报表名判断是否是第一次打印,分别对数据库数据进行insert和update操作。

ResultSet res = connect

              .executeQuery(“select * from PRINTMEMORY t where t.reportname = ‘”

                     + reportName + “‘”);

       // 有记录update,无记录insert

       if (res.next()) {

           connect.executeUpdate(“UPDATE printmemory SET rowheight = “

                  + rowHeight + ” WHERE reportname = ‘” + reportName + “‘ “);

       } else {

           connect.executeInsert(“INSERT INTO printmemory VALUES (‘”

                  + reportName + “‘, ”, ”, ” + rowHeight + “)”);

       }

标签: