浏览器打印方案调研

写在前面

写这篇文章的源头,要从公司的快递面单打印提及。最近指定了我来主要负责这一块内容。能够说之前对打印是一无所知,对打印暴露出来的问题简直就是小白啊,问题分析不清楚、缘由找不到、猜都没有方向。。。javascript

先说一下以前前端 web 打印咱们使用的方案吧,一直是用部门本身封装的打印npm包,封装的不复杂,就是对浏览器 window.print()没有的两个功能进行补充:自动分页和页面指定内容区域打印。由于咱们知道直接调用window.print()只能进行整个网页内容的打印。css

可是这个打印方案最近暴露出来比较多的问题,一样的纸张换了打印机以后就不行了,一样的内容样式在不一样打印机上面结果相差大等等。html

因此这就有问题了:
一、是打印机对样式属性的支持状况良莠不齐?
二、是否有一套打印执行标准是咱们不知道的?
三、选了不一样纸张以后预览页面的不一样程度拉伸收缩是咱们写样式的问题吗?
四、不一样的打印机型号会对打印有什么影响?
五、打印是否会对页面内容作拉伸?
六、打印对单位的支持?
七、打印识别纸张?是否能够提早获取打印机的型号?






前端

带着这些疑问,小白开启了一轮打印知识的疯狂充电🔋。vue

打印相关常识

这一部分见小白的上一片文章:浏览器打印知识扫盲java

当前 web 前端打印方案调研

一、浏览器的右键菜单打印功能

这是最简单的,只需点击页面上的打印菜单,可是也是问题最多的,基本上是不能知足用户须要。react

💣好比:jquery

  1. 不能精确分页,有出现打出半行字的风险;
  2. 改变纸型后打印出的格式和页面显示的格式相差太大;
  3. 页眉页脚也须要从菜单中去设置,等等。

这种方案最大的优点就是不须要作任何代码,点击打印就能够了。linux

window.print()
// or
document.execCommand('print')
复制代码

这实际上,是浏览器打印功能菜单的一种程序调用。与点击打印功能菜单同样,不能精确分页,不能设置纸型,套打的问题更加无从谈起,只不过,可让用户不用去点菜单,直接点击网页中的一个按钮,或一个连接里面调用罢了。git

须要指出的是这种方法提供一个打印前和打印后的事件 onbeforeprintonafterprint。能够在打印前的时候从新编辑一些格式,专门送去打印,打印后又处理回来。

function .onbeforeprint() {}
function .onafterprint() {
  //放开隐藏的元素
}
复制代码

事实上,不少用户都是采用这种方式打印,window.print() 方法很是不方便的地方是没法经过传参的方式对打印操做进行设置,须要在 css 中进行设置。

二、使用 print css

使用print css,对要打印的页面书写两套 css,一套用于浏览器页面显示,一套用于纸张打印。

这种方法经过在 html 文档中,嵌入打印相关的 css 样式,来实现对html文档输出打印的控制,好比设置纸张大小,纸张纵横方向,打印边距,分页等。

这一种比第一种直接调用浏览器的打印功能打印好一点,等于说是加了一些打印的样式以后,再传递给打印机打印。

🍒优势:

  1. 这种方式成本小,不须要下载任何插件,并且跨平台性很是好;
  2. 可能能适配 90% 以上的打印,但不敢说 100%

💣缺点:

  1. print css 推出已经有些时日,但遗憾的是,至今没有一个厂商的浏览器很好地实现了这些标准,这使得程序员目前还不能利用print css 进行实际的开发。

ps:这其实就是咱们如今使用的打印方案,可是咱们作的比较差劲。

  1. 咱们的样式单位使用的都是相对单位px,这在打印中很容易出问题;
  2. 是由于咱们的有纸张适配需求,可是咱们的纸张打印样式都是只写了一套,并无针对不一样的纸张尺寸去写一套样式,因此咱们的打印始终脱离不了打印机,始终不能真正作到只适配打印纸张。

🌟结论:就是若是咱们最后仍是使用这种打印的话,须要注意:

  1. 最好是针对每一种打印纸张写一份打印样式,不要再采用原来一份样式兼容二者这种;
  2. 使用 print css,单位都是用绝对单位;
  3. 不要使用浮动定位;
  4. 。。。

✅hiprint

🌟🌟🌟这里调研到有一个使用 print css 实现 web 端打印的免费的 js 库,依赖于 jquery 实现。官网:hiprint.io/。

hiprint 是一个web 打印的js组件,无需安装软件。支持windowsmacOSlinux 系统,支持移动端,PC 端浏览器,angularvuereact 等 分页预览,打印,操做简单,运行快速。预览界面为 css+html 。支持数据分组,批量预览。生成 pdf,图片更方便。

🍒优势:

  1. 可以 cover 如今咱们的页面打印元素的要求;
  2. 批量打印也支持;
  3. 将咱们以前写 html + css 的方式 改成写 json 模板和 打印数据 json 的方式;
  4. 使用的是绝对定位和绝对单位,这都是很是古老的 css,基本没有打印机会不支持;
  5. 免费;

💣缺点:

  1. 须要引入 jquery
  2. 配置项比较多,可是写过一个面板以后其实就还好。

结论:hiprint 可使用,可以解决目前咱们打印的问题和需求。

三、导出 excel 导出 pdf 文件的打印

这种方案是经过从服务端返回文件流,将打印的数据导出成 excel 文档或者 pdf 文件,而后在客户端打开文件进行打印。

🍒优势:

  1. 可以实现精确的打印;
  2. 套打也能实现;

💣缺点:

  1. 须要客户端配合安装 excel 后者 adobe 软件;
  2. 处处的 excel 可能会被从新修改编辑,不安全;
  3. 须要服务端配合,代价也是有的;

四、applet 方式

采用 applet 方式,分页或精确打印,均可以作到完美,但缺点也很明显,表如今:

  1. 安装 applet 成本巨大。须要下载十几 MB 的文件。
  2. applet 自己可能并不大,但运行 applet 所需的 jre 通常 >10m。用户须要极大的耐心,来进行打印。
  3. 打印报表时,须要从新向服务器检索数据,效率低。
  4. 由于 applet 方案,通常采用 html 方式呈现数据,打印时 applet 必须向服务器检索同一张票据的数据,看上去,是打印了当前页的票据,实际上,applet 根本不会用当前 html 页的数据来打印,而是向服务器下载数据到 applet 中来打印。也就是说,打印的话,必须两次请求,一次 html 呈现,一次用来打印。
  5. 市场上 java 类的报表工具,通常推荐 applet 方式来实现打印。

PS:这一种技术感受没看懂也不知道咋用用😂。

五、纯 activex 控件

这种方案其实就是编写一个 c/s 的打印控件,而后经过 <object> 标签内嵌入到页面里面,将要打印的数据装入到控件中,而后打印。

🍒优势:打印精度高,分页,设置打印参数等等都能实现。

💣缺点:也是很明显的,嵌入 activex 控件破坏了 web 应用的总体 html 风格,且这样的控件一般都比较大,通常都超过 1m,下载很慢。

六、轻量级的-activex-插件+-dhtml-+-javascript-+后台代码(动态获取数据)

轻量级的 activex 插件:可以设置打印参数,好比预约义纸型、设置打印方向、打印边距、指定打印机、静默打印等等。

Dhtml + javaScript:富文本编辑,支持编辑打印数据的展示格式,实现格式的自定义。

后台代码:能够实现打印数据的动态获取,好比 websocket 协议链接等等。

下面是业界主流的几种轻量级的 activex 插件。

  1. Lodop:有免费和收费两种,免费的有水印,免费提供的功能已经差很少够用;
  2. jatoolsPrinter:收费。
  3. ScriptX:收费,提供的免费功能比较少,免费的功能主要有页面边距设置等,咱们的需求使用免费版本应该就能够了。
  4. PAZU:PAZU 我的或者商业使用均真正免费受权,无IP或者域名限制。可是须要申请绑定IP或域名和4Fang网站。??? 可是申请时,必须有肯定的IP地址或者域名(主机名),PAZU是绑定IP或者域名的,IP或域名还没有肯定的咱们不能颁发受权,另外,受权一经颁发就不能修改绑定。 绑定的IP和域名必须是最终用户的,因此,最终用户的应用网站必须和4Fang网站作好连接,不然 PAZU会由于没法验证受权的合法性而不能正常工做(内网应用除外)。

🌟结论:Lodop这个用的比较多,提供的免费功能不少,自定义纸张、页面边距、批量打印等等,须要客户端配合提早安装软件使用。

调研结论

综合上面对浏览器打印的调研,咱们最后仍是决定使用hiprint这个js库作咱们的打印,可以解决咱们如今遇到的问题:

  1. 🍒批量打印;
  2. 🍒自定义分页;
  3. 🍒个性化打印内容;
  4. 🍒打印内容样式屏蔽打印机差别;
  5. 🍒免费

哈哈哈哈哈哈。真香!!!!!

easy-print 破壳🐣

如今npm包的大成之势,为了方便 hiprint 在项目中引入和使用,小白在 hiprint 的基础上面进行了封装,发布了npm包 easy-print 目前已发布,附带详细的使用demo。

🍒🍒easy-print 的github地址: easy-print

👏👏👏�欢迎感兴趣的小伙伴多多star!!!!

相关文章
相关标签/搜索