学习内容:批量导出pdf
在main.js中导入并注册
import PrintPdf from'@/views/registration/system/admissionticketprint/apllyMsgAct/pdf'
Vue.use(PrintPdf)
2.pdf.js
const Print = function (dom, options) {
if (!(this instanceof Print)) return new Print(dom, options)
this.options = this.extend({
noPrint: '.no-print',
onStart: function () {},
onEnd: function () {}
}, options)
if ((typeof dom) === 'string') {
this.dom = document.querySelector(dom)
} else {
this.dom = dom
}
this.init()
}
Print.prototype = {
init: function () {
let content = this.getStyle() + this.getHtml()
// TODO
this.writeIframe(content)
},
extend: function (obj, obj2) {
for (let k in obj2) {
obj[k] = obj2[k]
}
return obj
},
getStyle: function () {
let str = ''
let styles = document.querySelectorAll('style,link')
for (let 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>' + '@page' + '{margin-bottom: 1mm; margin-top: 1mm;} </style>'
return str
},
getHtml: function () {
let inputs = document.querySelectorAll('input')
let textareas = document.querySelectorAll('textarea')
let selects = document.querySelectorAll('select')
for (let 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 (let k2 in textareas) {
if (textareas[k2].type === 'textarea') {
textareas[k2].innerHTML = textareas[k2].value
}
}
for (let k3 in selects) {
if (selects[k3].type === 'select-one') {
let child = selects[k3].children
for (let i in child) {
if (child[i].tagName === 'OPTION') {
if (child[i].selected === true) {
child[i].setAttribute('selected', 'selected')
} else {
child[i].removeAttribute('selected')
}
}
}
}
}
return this.dom.outerHTML
},
writeIframe: function (content) {
let w
let doc
let iframe = document.createElement('iframe')
let f = document.body.appendChild(iframe)
iframe.id = 'myIframe'
iframe.style = 'position:absolute;width:0;height:0;top:-10px;left:-10px;'
w = f.contentWindow || f.contentDocument
doc = f.contentDocument || f.contentWindow.document
doc.open()
doc.write(content)
doc.close()
// TODO
this.toPrint(w, function () {
document.body.removeChild(iframe)
})
},
toPrint: function (w, cb) {
let _this = this
w.onload = function () {
try {
setTimeout(function () {
w.focus()
typeof _this.options.onStart === 'function' && _this.options.onStart()
if (!w.document.execCommand('print', false, null)) {
w.print()
}
typeof _this.options.onEnd === 'function' && _this.options.onEnd()
w.close()
cb && cb()
})
} catch (err) {
console.log('err', err)
}
}
}
}
const MyPlugin = {}
MyPlugin.install = function (Vue, options) {
// 添加实例方法
Vue.prototype.$print = Print
}
export default MyPlugin
3.页面模板(eg)
通过设置ref来控制节点,admissionData为后端返回的数组,类名为pdfDom的节点为一个pdf页面
<div ref="printDom" class="printContainer">
<div class="pdfDom" v-for="(item,index) in admissionData" :key="index"></div>
</div>
4.样式设置
将页面藏在当前页面底部
.printContainer{
position: absolute;
left: 0px;
top:0px;
opacity: 1;
z-index: -1;
}
5.数据响应并渲染页面
async onPrint() {
let ids = ''
for (var a = 0; a < this.selectedRowKeys.length; a++) {
ids += this.selectedRowKeys[a] + ','
}
await admissionData({ ids }).then(data => {
this.admissionData = data.result
})
this.$print(this.$refs.printDom, {
noPrint: '.noPrint',
onStart: () => {
console.log('打印开始')
},
onEnd: () => {
// 打印结束后将数组置空,页面节点清零
this.admissionData = []
console.log('打印完成')
}
})
},