一,Print.js介绍
Print.js主要是为了帮助我们在应用程序中直接打印PDF文件,而不需要离开界面,也不需要使用嵌入。对于用户不需要打开或下载PDF文件的特殊情况,只需要打印即可。
例如,当用户请求打印在服务器端生成的报告时,这是有用的一种情况。这些报告以PDF文件的形式发回。打印这些文件之前无需打开这些文件。Print.js提供了一种在我们的应用程序中快速打印这些文件的方法。
PDF文件必须与您的应用程序所在的域相同。Print.js在打印文件之前使用iframe加载文件,因此,它受到同源策略的限制。这有助于防止跨站点脚本(XSS)攻击。
- 原生js,不依赖其它库
- 可指定打印(或不打印)区域
- 支持css样式(内联、外联、嵌入)
- 支持input(radio/checkbox/text)、select、textarea值获取
二,下载安装
Print.js下载地址:https://download.csdn.net/download/weixin_43025151/87606898
或者使用npm安装
npm install print-js --save
引入到自己的项目中:
import print from 'print-js'
三,配置项
Print.js将接受一个对象作为参数,您可以在其中配置一些选项:
四,实现思路与项目示例
实现思路:将目标区域的dom/css添加到空iframe中,打印该iframe。
1) pdf的打印
<button type="button" onclick="printJS('docs/printjs.pdf')"> Print PDF </button>
2)base64
<button type="button" onclick="printJS({printable: base64, type: 'pdf', base64: true})"> Print PDF with Message </button>
3)html的打印
<form method="post" action="#" id="printJS-form"> ... </form> <button type="button" onclick="printJS('printJS-form', 'html')"> Print Form </button>
4)图片的打印
<img src="images/print-01.jpg" /> printJS('images/print-01-highres.jpg', 'image') //打印多张图片 printJS({ printable: ['images/print-01-highres.jpg', 'images/print-02-highres.jpg', 'images/print-03-highres.jpg'], type: 'image', header: 'Multiple Images', imageStyle: 'width:50%;margin-bottom:20px;' })
5)打印json
someJSONdata = [ { name: 'John Doe', email: 'john@doe.com', phone: '111-111-1111' }, { name: 'Barry Allen', email: 'barry@flash.com', phone: '222-222-2222' }, { name: 'Cool Dude', email: 'cool@dude.com', phone: '333-333-3333' } ] <button type="button" onclick="printJS({printable: someJSONdata, properties: ['name', 'email', 'phone'], type: 'json'})"> Print JSON Data </button>
整个vue文件:
<template> <div id="app"> <div id="divPrint" class="mainbox print"> <!-- <div style="font-size: 25px; margin-top: 80px" align="center"> 整改通知单 </div> --> <div align="center" style="margin: 0; padding: 0; width: 100%"> <table> <tr style="border: none"> <td colspan="2">工程项目:xx</td> <td style="text-align: right; padding-left: 10px;" colspan="2">编号:xx</td> </tr> <tr style="border: none"> <td colspan="2">整改单位:xx</td> <td style="text-align: right; padding-left: 10px;" colspan="2">编号:xx</td> </tr> <tr style="border: none"> <td colspan="2">整改内容:xx</td> <td style="text-align: right; padding-left: 10px;" colspan="2">编号:xx</td> </tr> </table> </div> </div> <div style="margin-top: 20px; text-align: center"> <button @click="print()">pdf打印</button> </div> </div> </template> <script> import printJS from "print-js"; export default { name: "printing", data() { return {}; }, methods: { print() { printJS({ printable: "divPrint", // 标签元素id type: "html", // 打印类型 header: "整改通知单", // '表单名称', targetStyles: ["*"], style: "@page {margin:0 10mm};", // 可选-打印时去掉眉页眉尾 ignoreElements: ["no-print"], // 接受打印父 html 元素时应忽略的 html id 数组。 properties: null, }); }, }, }; </script> <style lang="scss"> #app { width: 100%; font-family: "Avenir", Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; .mainbox { width: 100%; margin: 0 auto; } } </style>
点击打印按钮后,出现PDF预览。
五,分析:
经过多次实战演练:
如果要打印的样式比较复杂,并且有字体图标等,建议选择第一种;
如果打印表格数据,比如element表格,还可以按需勾选进行打印,选择第二种打印方式比较好。
再分享一个强制分页打印,每页只打印固定的内容:
只需要在要分页打印的末尾加上:
<div style="page-break-after:always"></div>
即可
代码如下:
<div id="printTable" v-for="(arr, i) in saveListArray" :key="i" style="position: relative; background-color:rgb(236,230,232);margin-top:5px;" :class="printWay == 3 ? 'printTableActive' : ''" :style="{ width: containerWidth + 'mm', height: containerHeight + 'mm', }"> <el-container v-for="(item, index) in arr" :key="index"> <div id="printColor" v-bind:style="{ width: Number(item.GoodInvoiceDetailWidth) + 'mm', height: item.GoodInvoiceDetailHeight + 'mm', 'line-height': item.GoodInvoiceDetailHeight + 'mm', left: Number(item.GoodInvoiceDetailCoordinateX) + Number(x) + 'mm', top: Number(item.GoodInvoiceDetailCoordinateY) + Number(y) + 'mm', color: item.GoodInvoiceDetailColour + '', 'font-size': item.GoodInvoiceDetailSize + 'mm', 'font-family': item.GoodInvoiceDetailFont + '', 'text-align': item.GoodInvoiceDetailPosition + '', 'border-top': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderTcolor, 'border-bottom': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderBcolor, 'border-left': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderLcolor, 'border-right': item.GoodFramSize*0.1+0.1 + 'mm' + item.GoodFramSolidlineIf + item.borderRcolor, overflow: item.overflow, }" style=" display: inline-block; text-align:left; position: absolute; cursor: move;"> <div v-if="item.GraphContent"><img :src="item.GraphContent" style="width:100%;height:100%;margin-top:4px;"></div> <div v-else style="margin-right:3px;margin-left:3px;">{{ item.GoodInvoiceDetailName }}</div> </div> </el-container> <div style="page-break-after:always"></div> </div>
下面展示两种图片:(一张没有加分页的,和加了分页的区别)
六,注意
不支持background-color背景色打印,试试用background-image代替,只在浏览器中预览打印,未实际打印过, 公司无公用打印机,低级浏览器兼容性待验证。