在这里记录一下vue实现不预览打印pdf功能,要是有更好的方法,希望能指点一二
踩坑:
通过后端接口返回服务器上PDF的地址,前端通过隐藏的iframe标签中src可实现预览功能,但是需要用户点击打印按钮,多了一步操作,如果直接调用print()则存在跨域的问题无法直接调用。报(Blocked a frame with origin "http://localhost:8080" from accessing a cross-origin frame.)错误
解决方法:
方法一:通过fetch()将PDF地址转化为blob
<template>
<div>
<div @click="print">打印</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
print() {
let url = 'http://xxxxx.pdf'//获取的url地址
fetch(url).then(res => {
return res.blob() //将url地址转化为blobd
}).then(res => {
var iframe = document.createElement('iframe')
iframe.style.frameborder = 'no'
iframe.style.display = 'none'
iframe.style.pageBreakBefore = 'always'
iframe.setAttribute('id', 'printPdf')
iframe.setAttribute('name', 'printPdf')
iframe.src = window.URL.createObjectURL(res) //创建一个包含指定对象的URL
document.body.appendChild(iframe)
this.doPrint('printPdf')
window.URL.revokeObjectURL(iframe.src) //释放url
})
},
doPrint(val) {
var ordonnance = document.getElementById(val).contentWindow
setTimeout(() => {
ordonnance.print()
}, 500)
},
}
}
</script>
方法二:采用文档流的形式解决跨域的问题
<template>
<div>
<div @click="print">打印</div>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
print() {
// res为接口获取到的pdf文档流数据
const blob = new Blob([res], {
type: 'application/pdf'
})
var iframe = document.createElement('iframe')
iframe.style.frameborder = 'no'
iframe.style.display = 'none'
iframe.style.pageBreakBefore = 'always'
iframe.setAttribute('id', 'printPdf')
iframe.setAttribute('name', 'printPdf')
iframe.src = window.URL.createObjectURL(blob) //创建一个包含指定对象的URL
document.body.appendChild(iframe)
this.doPrint('printPdf')
window.URL.revokeObjectURL(iframe.src) //释放url
},
doPrint(val) {
var ordonnance = document.getElementById(val).contentWindow
setTimeout(() => {
ordonnance.print()
}, 500)
},
}
}
</script>
以上两种方法实现的原理是相同的
pdf链接地址下载pdf
在这里补充记录一下如何实现pdf链接地址下载pdf的问题,在实际开发中会出现后端接口直接返回服务上的pdf链接地址,这时候浏览器会直接打开预览,并不会实现下载的功能,这时候我们只需要将pdf链接地址转化成为blob,在通过window.URL.createObjectURL()转化为临时的地址就可以实现了,话不多说直接上代码
dowLoad(){
let url = http://xxxxxx.pdf//接口返回的地址
fetch(url).then(res => {
return res.blob()
}).then(res => {
const a = document.createElement('a')
a.style.display = "none";
a.download = '下载.pdf';
const url = window.URL.createObjectURL(res)
a.href = url
a.click();
})
}