前文再续,书接上一回,自从《PHP输出PDF打印HTML5+CSS3打印格式控制》以后,实现了用HTML5+CSS3直接输出成PDF文件,以知足各类奇葩的打印格式需求。这个的确给调试打印打来了各类便利,不过随着深刻使用,也碰到一些个小问题。php
其实这个是前文忘记交代的问题。把系统部署到Linux的时候就发生了,不过这个问题其实比较好解决,直接在服务器安装文泉驿的开源中文字体便可。ubunutu服务器直接:css
apt-get install ttf-wqy-zenhei
在打印CSS中,修改以下:html
@page { size: A4; margin: 12mm 10mm; padding: 0; font-family: "Wenquanyi Micro Hei", "Microsoft YaHei", Simsun, sans-serif; font-size: 10pt; }
对,加个字体生命便可,是否是很简单呢?前端
Prince和wkhtmltopdf这两个引擎,从本质上说,就是一个浏览器引擎,固然他们有比较特殊的渲染机制,尤为是实现CSS3标准的特性,而且他们能够将结果输出到PDF文件流。web
为啥要引入这个东东呢,主要的问题在于,目前主流的浏览器,在对打印部分的CSS3标准支持的还颇有限。就算我针对性的作出html的打印样式,但客户的打印格式,确定会存在一些比较特殊的要求。除此以外,直接打印html还存在一些不稳定、不肯定的地方,须要有前端的经验去进行“特制”,但这就致使了可能为了实现一个需求而进行特制,但下次就忘记了,或者要教会别的人也学会这种“特殊”方法,可能也花很多时间。因此相对而言,采用CSS3,传统html,不须要额外学习什么东西,同时,输出成PDF,输出的内容也至关的稳定。浏览器
针打纸张的尺寸比较特殊,非标准印刷纸张。但使用Chrome浏览器对PDF文件打印输出的时候,老版本的Chrome纸张尺寸只有几个标准的纸张尺寸,这问题也困扰了我一段时期。bash
国内外彷佛对这个问题,也没有比较深刻一点资料。不事后来无心中更新了Chrome到56版本,发现Chrome已经支持在选择打印机的时候,自动识别打印机里面设置的特殊纸张格式,你能够在选择了打印机之后,找到这个特殊的纸张格式。服务器
因此,你要作的只有两件事:ide
1. 在打印机首选项里面,添加你的针打纸张尺寸,多数针打都支持:布局
2. 在Chrome(具体是什么版本支持的,我没去细究了)打印的时候,选好对应的打印机:
至此,整个ERP系统的全部打印需求都已知足了,合同、发票、出入库单、送货单、物料编码不干胶。
下一阶段,打算基于nw.js或者Electron.js,将整个客户端打包,主要是想经过客户端发起webscoekt来实现实时的消息推送,若是基于浏览器窗口的话,很差管理webscoekt客户端链接数。
除此以外,由于已经彻底是纯JS前端的APP应用了,单个窗体过程,存在一个数据对象太多的问题。由于整个界面都是无刷新的,因此各类类型的数据获取之后,靠客户端的窗口进程来维持着大量的数据对象,Chrome也是有极限的。一些不常更新的数据,其实能够做为本地持久化保存的方案进行处理。
回到正题了,其实CSS3控制打印,也没有什么特别神秘的东西。
基础的技巧,我就不说了,能够直接看这篇教程《Designing For Print With CSS》,老外介绍的很详细了。
由于在调试的时候,能够直接用html预览基本效果,因此调试过程也至关的轻松。不过有几点值得注意的:
1. 在打印调试的时候,使用mm或者cm,比较易于控制实际的打印效果,px时不太适合的。
2. em、rem属性一样适用于打印的样式,他们真的很方便,很是符合设计要求。
3. 字体使用pt单位。字号和具体的mm尺寸转换表(原谅我图找得有点崩):
4. 最后的最后,奇淫巧技时间到。就算利用到了CSS三、输出到PDF,可是客户的打印需求可能仍是存在一些比较特殊的状况,这里仍是就要利用table来实现。
有个这样的需求:
送货单的样式,页头有送货单抬头、客户信息、送货信息、付款说明等,内容部分是一个Table,里面是送货单的明细,页脚附有一段说明文字,以后是签名栏。
当Table的明细内容超多的时候,要展示到第二页(这不是废话吗,还有第3、4、五等等),可是要求Table表头能在每一页都展示。
同时,第二页也要求有页头、页脚(也就是重复出现)。
最终的打印输出结果要求以下图:
首先,重复表头,咱们并不须要分隔输出这个Table,只要利用CSS3的特性便可:
table { page-break-inside: auto } tr { page-break-inside: avoid; page-break-after: auto } thead { display: table-header-group } tfoot { display: table-footer-group }
其次,对于页头、页脚的多页展示。虽然在@page,支持有@top-center、@bottom-center等,容许你设置具体的方位上的页头页脚内容,好比:
@page { @top-left { content: "手写单号#<?php echo $deliveryCode; ?>"; } @top-right { content: "<?php echo $delivery->code; ?>"; } }
可是显然,这种方式并不支持设置包含html的内容,虽然你能够经过css控制他们的位置,宽度等。因此须要放一些包含html标签的内容的画,咱们就须要考虑用别的办法了,那么究竟是什么办法呢?其实什么特别的都不用作,只要利用回上述的table部分的样式便可,也就是说,直接利用css控制table的thead和tfoot的重复渲染特性来实现。
因此,咱们又回到了table布局的年代:
<table border="0" width="100%" cellpadding="0" cellspacing="0"> <thead> <tr> <td class="delivery-thead">页头</td> </tr> </thead> <tbody> <tr> <td class="delivery-tbody">明细</td> </tr> </tbody> <tfoot> <tr> <td class="delivery-tfoot">页脚</td> </tr> </tfoot> </table>
就这样,你只要将具体内容,放入delivery-tbody中便可完成整个需求,很简单,对不对?