阅读量:0
1.安装print.js
npm install print-js --save
2.在main.js文件中引入并注册(我使用的是print.js的源码文件,并且做了一修改)
//引入 import Print from './utils/print' //注册 Vue.use(Print); //注册
3.在页面中使用
<template> <div class="detailsPrint"> <div class="move" ref="pdfContent" id="pdfContent"> 需要打印的内容 </div> <el-button type="primary" @click="printPDF">打 印</el-button> </div> </template> <script> export default { name: "", data() { return { }; }, methods: { // 打印PDF printPDF() { this.$nextTick(() => { this.$print(this.$refs.pdfContent, { watermark: { companyName: '公司名称', name: '姓名', date: '2024-08-01', } }); } }, }; </script> <style scoped> //我希望打印出来的格式是A4纸的格式 @media print { @page { size: B5(JIS); margin: 10mm 16mm; margin-top: 8mm; margin-bottom: 8mm; } } </style>
4.在utils下新增print.js
/* eslint-disable */ const Print = function (dom, options) { if (!(this instanceof Print)) return new Print(dom, options); this.options = this.extend({ 'noPrint': '.no-print', 'watermark': {} // 接受单个水印数据对象 }, options); if ((typeof dom) === "string") { this.dom = document.querySelector(dom); } else { this.dom = dom; } setTimeout(() => { this.init(); }, 2000); }; Print.prototype = { init: function () { var content = this.getStyle() + this.getHtml(); this.writeIframe(content); }, extend: function (obj, obj2) { for (var k in obj2) { obj[k] = obj2[k]; } return obj; }, getStyle: function () { var str = "", styles = document.querySelectorAll('style,link'); for (var i = 0; i < styles.length; i++) { str += styles[i].outerHTML; } str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>"; str += ` <style> .watermark { position: absolute; top: 0; left: 0; width: 100%; height: 100%; opacity: 0.2; pointer-events: none; } .watermark-content { color:rgba(0,0,0,0.4) text-align: center; transform: rotate(-45deg); font-size: 24px; } /* 打印样式 */ @media print { body, html { width: 100%; height: 100%; margin: 0; padding: 0; } .watermark { opacity: 0.2; pointer-events: none; position: fixed; /* 修正水印固定位置 */ } .watermark-content { text-align: center; transform: rotate(-45deg); font-size: 24px; color:rgba(0,0,0,0.4) } /* 隐藏不需要打印的内容 */ ${this.options.noPrint} { display: none !important; } /* 设置A4纸大小和页边距 */ @page { size: B5(JIS); margin: 10mm 16mm; margin-top: 8mm; margin-bottom: 8mm; } } </style> `; return str; }, getHtml: function () { var inputs = document.querySelectorAll('input'); var textareas = document.querySelectorAll('textarea'); var selects = document.querySelectorAll('select'); for (var k in inputs) { if (inputs[k].type == "checkbox" || inputs[k].type == "radio") { if (inputs[k].checked == true) { inputs[k].setAttribute('checked', "checked") } else { inputs[k].removeAttribute('checked') } } else if (inputs[k].type == "text") { inputs[k].setAttribute('value', inputs[k].value) } } for (var k2 in textareas) { if (textareas[k2].type == 'textarea') { textareas[k2].innerHTML = textareas[k2].value } } for (var k3 in selects) { if (selects[k3].type == 'select-one') { var child = selects[k3].children; for (var i in child) { if (child[i].tagName == 'OPTION') { if (child[i].selected == true) { child[i].setAttribute('selected', "selected") } else { child[i].removeAttribute('selected') } } } } } // 使用传递的单个水印数据对象生成多个随机位置的水印 var watermarkHtml = ''; var numWatermarks = 12; // 生成的水印数量 var leftStart = -50; // 修改此处,从最左边开始的起始位置(百分比) var leftEnd = 95; // 最右边的结束位置(百分比) var topPositions = ['20%', '40%', '60%', '80%']; // 垂直方向的位置 var step = (leftEnd - leftStart) / (numWatermarks - 1); // 计算步长 for (var i = 0; i < numWatermarks; i++) { var leftPosition = `${leftStart + i * step}%`; var topPosition = topPositions[i % topPositions.length]; watermarkHtml += ` <div class="watermark" style="top: ${topPosition}; left: ${leftPosition};"> <div class="watermark-content"> <div> ${this.options.watermark.companyName}</div> <div> ${this.options.watermark.name}</div> <div> ${this.options.watermark.date}</div> </div> </div> `; } return this.dom.outerHTML + watermarkHtml; }, writeIframe: function (content) { var iframe = document.createElement('iframe'); iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;"; document.body.appendChild(iframe); var doc = iframe.contentDocument || iframe.contentWindow.document; doc.open(); doc.write(content); doc.close(); this.toPrint(iframe.contentWindow); setTimeout(function () { document.body.removeChild(iframe); }, 100); }, toPrint: function (frameWindow) { try { setTimeout(function () { frameWindow.focus(); try { if (!frameWindow.document.execCommand('print', false, null)) { frameWindow.print(); } } catch (e) { frameWindow.print(); } frameWindow.close(); }, 10); } catch (err) { console.log('err', err); } } }; const MyPlugin = {}; MyPlugin.install = function (Vue, options) { Vue.prototype.$print = Print; }; export default MyPlugin;