2.5        打印事件

JCP在进行网页打印时,会产生一系列的事件,如打印任务状态事件、打印页面打印事件、打印预览窗口关闭事件等等,你可以根据需要,截获这些事件进行相应处理。

2.5.1    监视打印任务状态

监控打印任务

JCP将网页打印到打印机时,系统会发送一个打印任务,到打印机的任务队列中,JCP可以将当前打印任务状态变化,通知到你的程序,比如,打印开始,结束等(这些状态,也可以从打印机的控制面板中看到)。

 

JCP使用 myDoc.onState回调函数,通知这些变化:

1.  var myDoc = {  

2.      onState : function(job) {  // 将本次 print调用所生成的打印任务状态变化,通知到 onState函数

3.          console.log(job);  

4.      },  

5.      documents : document,  

6.      copyrights : '杰创软件拥有版权  www.jatools.com'  

7.  };  

8.  getJCP().print(myDoc);  

 

onState返回一个Object对象,表示当前生成的打印任务,其属性示例如下:

1.  {  

2.      document :"杰表Print文档 @2017-12-01 12:16:38",  // 文档名称  

3.      id : 33, // 打印任务id  

4.      pagesPrinted : 0, // 已被打印页  

5.      shortDocument : "杰表Print文档"// 文档简称  

6.      status : 8, // 状态码  

7.      statusText : "进入队列 "// 状态说明  

8.      totalPages : 10, // 总页数  

9.      userName : "java9d"  // 发起打印的用户名  

10. }  

其中status就是以数值表示的状态编码,statusText是相应status的文字说明。

 

当打印任务的状态发生变化时,就会调用onState,因此,onStatus会被多次调用。

 

2.5.2    监听打印页数事件

监听打印页数事件

有时,你打印一个文档,但不知道最后打印了几页,比如,自动分页的情况,这时,你可以使用监听打印页数事件,来查询到打印的总页数:

1.  var myDoc = {  

2.      onPagePrinted : function(i, size) {  

3.          var j = i + 1;  

4.          if (j == size)  

5.              console.log('所有打印结束,总计' + size + '');  

6.          else  

7.              console.log('' + j + '页打印结束.<br>');  

8.      },  

9.      documents : document,   

10.     copyrights : '杰创软件拥有版权  www.jatools.com'   

11. };  

12. getJCP().print(myDoc);  

当你设置,myDoc.onPagePrinted属性时,JCP在每打印一页时,回调这个函数,并传两个参数,第一个参数为当前打印页,第一页为0,第二个参数为总页数。

 

提示:

这里的打印,并不是说,真的打印到打印机了,而是说打印任务新生成了一页。

 

2.5.3    监听其他事件

事件监听

你可以设置监听一些事件,比如,是否关闭了打印预览窗口:

1.  function doPrint(how) {  

2.      var myDoc = {  

3.          listener : function(e) {  

4.              console.log(decodeEvent(e));  

5.          },  

6.          documents : document,  

7.          copyrights : '杰创软件拥有版权  www.jatools.com'  

8.      };  

9.      var jcp = getJCP();  

10.     if (how == '打印预览...')  

11.         jcp.printPreview(myDoc);  

12.     else if (how == '打印...')  

13.         jcp.print(myDoc, true);  

14.     else  

15.         jcp.print(myDoc, false);  

16. }  

17. // 根据事件的类型,提取相应的参数  

18. function decodeEvent(e) {  

19.     var result = e.type + ',';  

20.     if (e.type == 'window-open') {  

21.         result += '预览窗口打开';  

22.     } else if (e.type == 'window-close')  

23.         result += '预览窗口关闭';  

24.     else if (e.type == 'doc-start')  

25.         result += '开始文档打印';  

26.     else if (e.type == 'doc-stop')  

27.         result += '结束文档打印';  

28.     else if (e.type == 'page-printed') {  

29.         result += '正在打印一页,';  

30.         result += ('页号:' + e.pageNumber + ',');  

31.         result += ('总页数:' + e.totalPages);  

32.     } else if (e.type == 'printed') {  

33.         result += '打印结束';  

34.     } else if (e.type == 'cancel-print') {  

35.         result += '打印取消,';  

36.         result += '原因:' + e.error;  

37.     } else if (e.type == 'job') {  

38.         result += (e.printerName + ' ' + e.document + ' ' + e.status + ' ' + e.statusText + ' ' + e.userName + ' ' + e.pagesPrinted + ' ' + e.totalPages + ' ' + e.size + ' ');  

39.     }  

40.     return result;  

41. }  

如果你设置 myDoc.listener回调,相关事件发生时,JCP会调用listener,并传入一个参数,该参数是一个Object对象,其中type属性指明事件类型,可能取值有:

Type属性值

说明

其他属性

window-open

预览窗口打开

 

window-close

预览窗口关闭

 

doc-start

开始文档打印

 

doc-stop

结束文档打印

 

page-printed

正在打印一页

pageNumber:页号

totalPages:总页数

printed

打印结束

 

cancel-print

打印取消

error:原因

job

打印任务状态变化

document :文档名称 

id :打印任务id 

pagesPrinted :已被打印页 

shortDocument :文档简称 

status:状态码 

statusText :状态说明 

totalPages :总页数 

userName :发起打印的用户名 

 

2.6        自动分页

最简单的自动分页

web打印中,我们经常需要打印一些长的表格<table>,可能跨好几页,对于这种长表格,用浏览器打印,和JCP的预分页方式(即做若干div,每个div为一页),都不能理想地解决表格分页打印问题。

 

如果用浏览器的window.print方法打印,经常会出现在分页处断行,断线现象,如下:

 

当然,现在也有print css,但各浏览器厂商对该标准支持程度不一样,在不同的浏览器上打印,可能样式有很大差异。

 

能不能将大表格分成多个<table>,然后,用前面所说的方法,把它们放在一个个div页上,再用JCP来打印?

 

如果是行高一样的表格,上述方法可行,只需要算出每页合适的行数就行了,但如果类似简历这种表格,有很多的合并单元格,行高不一样,比如,工作经历一行,经历丰富的可以有好几页,刚毕业的可能是空白。这样,就无法知道,该在哪里分页了,如果再考虑有单元格上的段落文字,也需要分页的情况,那就更复杂了。

 

JCP针对上述问题,引入了自动分页功能,它可以很好地解决表格分页断线的问题,也可以解决行高不等表格的自动分页,另外,你也可以使用JCP有关分页的加强功能,比如,合并单元格表格分页、大单元格文字分页的问题,表头表尾保留,合计、本页小计等计算。

 

JCP即可以对表格元素<table>进行自动分页,也可以对HTML的其它容器对象,比如,<div><p><ul>等进行自动分页。

 

如果某个div页中的内容,需要自动分页,则只需要在该 div 上,设置控制样式类 breakable即可,如下所示:

1.  <script>  

2.     var myDoc = {  

3.      documents : document,   

4.      copyrights : '杰创软件拥有版权  www.jatools.com'   

5.     };  

6.     getJCP().print(myDoc);  

7.  </script>  

8.    

9.  <div id="page1" class="breakable"> 本页内容较多,有可能打印不下,请自动分页之,blablalbla...</div>  

10. <div id="page2" > 不需要自动分页</div>  

11. <div id="page3" class="breakable">请将我自动分页,blablalbla...</div>  

 

没设置breakable样式类的page div,仍然按预分页方式打印,即如果有一页打印不下的部分,会被截去。

 

要自动分页,不需要在myDoc参数中作任何额外设置。

 

JCP总是检查 page div上的样式类,有则分之。

 

JCP的分页算法,总是尽可能地利用可打印区域:

可打印区域=打印纸张大小-边距-页眉高度-页脚高度

 

2.6.1    窗口式分页(只对页内指定元素分页,其余保留)

窗口式分页(只对页内指定元素分页,其余保留)

先看一下,窗口式分页的图解:

JCP发现page div 上有breakable样式类,就准备自动分页,当发现同时有break-window属性时,则只对该属性指定的对象进行分页,该page div其余部分则每页打印。

 

break-window就象是给page div开了一个窗,窗内的内容执行自动分页,窗外的内容复制到每页。

 

JCP通过 jquery find方法,找到需要分页的指定对象,因此,合法的css selector表达式均可,图例中的"#win" 指的是找到idwin的对象进行分页。

 

break-window指定的分页对象不能多于一个。

 

窗口式分页适合每页需要打印头尾部分,只对中间部分进行分页的需求,比如,每页需要打印title

提示:

jquery 被内置在 JCP里面,你的代码中不必引入jquery

 

2.6.2    简单的表格保留表头、表尾分页

表格打印,表头每页可见

如果有表格要自动分页的同时,还需要每页打印将该表格的表头,则需要在page div 设置breakable样式类,和break-window属性,在<table>上设置 headerRows属性:

1.  <div id="page1"  class="breakable" break-window='#break-table'>  

2.          <table id="break-table" headerRows='1' >  

3.          <tr>  

4.             工资表  

5.          </tr>  

6.          ...  

7.          </table>  

8.  </div>  

headerRows表示表格的起始多少行<tr>作为表格的表头,JCP会每页打印该表头。如果不设置这个属性,或者为0,则表示不存在表头。

 

2.6.3    长单元格跨多页

长单元格分页

长单元格,就是内容较多,可能跨几页的单元格,如下:

1.  <div id="page1" class="breakable">    

2.          <table>    

3.          <tr>    

4.             <td>长单元格,内容可能跨多页,。。。</td>  

5.          </tr>    

6.          ...    

7.          </table>    

8.  </div>   

对于这种长单元格,JCP会自动发现,你不必在HTMLjs中,作特别的设置。

 

2.6.4    带合并单元格的表格自动分页

含合并单元格的表格自动分页

带合并单元格的表格,即是指,存在跨多行(跨多列的单元格,不影响分页)的单元格,且有可能在合并单元格中间处分页的表格。如下所示:

 

图中,红色部分即是合并单元格分页后的效果。

JCP会自动发现这种合并单元格,你不必在HTMLjs中,作特别的设置。

 

2.6.5    表格自动分页时的小计、合计

表格分页时的本页小计,累计,合计

表格总计值,可以事先计算出,并放在表格末尾,但经过分页的表格,每页行数不定,这时,如果又想计算出每页的本页小计,本页累计,怎么办? 你需要设置一个特殊的 tbody用来显示每页页尾,如:

1.   <div id="page1" class="breakable">  

2.   <table>  

3.   <tbody>  

4.   ...  

5.   <tbody>  

6.   <tbody class='every-footer' style="display: none">  

7.      <tr>  

8.          <td colspan="4">本页最高收益:{lookup(4,pageMax(4),2)}({pageMax(4)})</a></td>  

9.          <td colspan="4">本页最低收益:{pageMin(4)}</nobr></td>  

10.         <td colspan="3">本页营收累计:{decimal(subSum(5),2)}</td>  

11.     </tr>  

12.  </tbody>  

13.  </table>  

14.  </div>  

 

效果是这样:

 

JCP发现,有 every-footer样式类的 <tbody>时,就会在表格分页完了以后,计算这个<tbody>里,所有含有{}里的内容,并替换,最后将替换后的内容,添加到当前页表格的后面,如图所示。

 

因为tbody.every-footer ,仅在JCP的打印预览及打印中,会起作用,而显示在浏览器上时,不应该显示该<tbody>,因此,一般设置为不显示display:noneJCP内部会将该<tbody>改为显示。

 

JCP在计算{}时,有当前列的概念,当前列指的是公式所在的列,比如:

 

{}中,可以使用的方法见下表,JCP在计算{}时,有当前列的概念,当前列指的是公式所在的列。参数中有关行、列都是0为底,即第一行,第一列,都为0:

方法

名称

描述

sum(col, from, to)

合计,

 

col:计算哪一列数据,默认为当前列

from:从表格的第几行开始计算,默认为0,

to: 到表格的第几行结束,默认为最后一行

min (col, from, to)

最小值

同上

max (col, from, to)

最大值

同上

count ()

行数

表格总行数

pageSum (col)

本页合计

col:计算哪一列数据,默认为当前列

pageMin (col)

本页最小值

同上

pageMax (col)

本页最大值

同上

pageCount (col)

本页行数

本页行数

subSum (col)

本页累计

col:计算哪一列数据,默认为当前列

subMin (col)

至本页最小值

同上

subMax (col)

至本页最大值

同上

subCount ()

至本页行数

 

lookup (col, val, ret)

 

取得某一列值

col:查找哪一列数据,必须

val:值

ret: 要取哪一列上的值

{lookup(0,12,3)}//找到第一列,值为12的行,并返回该行的第4列的值

decimal (num, v)

保留小数位

num:

v:小数位

rmb (num)

人民币大写

num:

 

2.6.6    多表自动分页

多表自动分页

1.   <div id="page1" class="breakable">  

2.   <table>  

3.   ...  

4.   </table>  

5.   <table>  

6.   ...  

7.   </table>  

8.   <table>  

9.   ...  

10.  </table>  

11.  </div>  

你可以在一个page div中,包含多个表格,并设置breakable类,JCP会自动发现需要分页的表格并分页。

 

2.6.7    表格横向自动分页

表格列太多时,自动横向分页

如果你有很宽的表格,需要根据纸张宽度,自动按列分页,比如:

分成:

 

这种情况,你需要将窗口分页对象,设置到该表格,并在该表格上,添加样式类column-breakable,如下所示:

1.   <div id="page1" class="breakable" break-window='.column-breakable'>  

2.       <table class="column-breakable" >  

3.       ...       

4.      </table>  

5.   </div>  

JCP发现有 column-breakable样式类的<table>,会执行横向按列分页。

 

 

2.6.8    非表格元素,如<p><div>的自动分页

非表格元素,如<p>,<div>的自动分页

你也可以对其他 HTML容器,如<div><p><ul>进行分页:

1.   <div id="page1" class="breakable" style="width: 600px; margin: 0 auto;">  

2.       <div>  

3.           <p >  

4.               <span>文本编码:C-A-10</span>  

5.           </p>  

6.           ...  

7.       </div>  

8.   </div>  

容器对象可以互相嵌套,层次不限。

 

2.7        收缩打印

如果打印内容,超过纸张大小时,会发生什么?分两种情况,超高和超宽。

1. 超高,对于超高你可以使用JCP的自动分页功能,将超高部分打印在另一页。参照上一章自动分页。

2. 超宽,你可以使用 JCP的自动收缩功能,将打印内容缩到页宽能打印得下即可。

 

你可以用 myDoc.scale属性来设置收缩比例,取值范围:

0 1.0之间的小数

指示收缩到指定比例

"on-width"

页面宽度够,不收缩,宽度不够执行收缩,直到够宽

"single"

将打印内容收缩到一页。考虑高宽,即只要不够宽,不够高都执行收缩

 

提示:

收缩功能可与自动分页功能同时使用。

 

2.7.1    指定缩放比例打印

指定缩放比例

1.   <script>  

2.       var myDoc = {  

3.           scale :0.5, // 指定收缩比例为50%  

4.           documents : document,  

5.           copyrights : '杰创软件拥有版权  www.jatools.com'   

6.       };  

7.       getJCP().print(myDoc);  

8.       ...   

9.   </script>  

10.  <div id="page1" class="breakable" >  

11.    ...  

12.  </div>  

 

2.7.2    自动宽度缩放打印

表格分页+自动缩放

1.   <script>  

2.       var myDoc = {  

3.           scale :'on-width', // 按宽度自动计算收缩比例  

4.           documents : document,  

5.           copyrights : '杰创软件拥有版权  www.jatools.com'   

6.       };  

7.       getJCP().print(myDoc);  

8.       ...   

9.   </script>  

10.  <div id="page1" class="breakable" >  

11.    ...  

12.  </div>  

 

2.7.3    单页缩放打印

单页缩放打印

1.   <script>  

2.       var myDoc = {  

3.           scale :'single', // 按单页收缩  

4.           documents : document,  

5.           copyrights : '杰创软件拥有版权  www.jatools.com'   

6.       };  

7.       getJCP().print(myDoc);  

8.       ...   

9.   </script>  

10.  <div id="page1" >  

11.    ...  

12.  </div>  

单页收缩时,不需要指定breakable样式类。