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属性指明事件类型,可能取值有:
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" 指的是找到id为win的对象进行分页。
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会自动发现,你不必在HTML和js中,作特别的设置。
2.6.4 带合并单元格的表格自动分页含合并单元格的表格自动分页 带合并单元格的表格,即是指,存在跨多行(跨多列的单元格,不影响分页)的单元格,且有可能在合并单元格中间处分页的表格。如下所示:
图中,红色部分即是合并单元格分页后的效果。 JCP会自动发现这种合并单元格,你不必在HTML和js中,作特别的设置。
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:none,JCP内部会将该<tbody>改为显示。
JCP在计算{}时,有当前列的概念,当前列指的是公式所在的列,比如:
在{}中,可以使用的方法见下表,JCP在计算{}时,有当前列的概念,当前列指的是公式所在的列。参数中有关行、列都是0为底,即第一行,第一列,都为0:
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属性来设置收缩比例,取值范围:
提示: 收缩功能可与自动分页功能同时使用。
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样式类。
|