vue-pdf实现pdf预览、分页、下载、打印
vue-pdf-app(功能完整内嵌组件):
https://www.npmjs.com/package/vue-pdf-app
vue-pdf使用(参考地址):
https://www.jianshu.com/p/a640ce9d4882
https://blog.csdn.net/weixin_43837268/article/details/103746743
vue-pdf下载 (参考地址):
https://www.jianshu.com/p/56680ce1cc97
vue-pdf-demo(参考项目):
https://github.com/shengbid/vue-demo/blob/master/src/views/pdf/index.vue
---------------------------------------------------------------------------(分割线)--------------------------------------------------------------------
1、pdf预览、分页实现
- vue-pdf组件排坑: 中文字体不显示 参考地址(一): https://www.jianshu.com/p/1461d8e4ca62 参考地址(二): https://blog.csdn.net/chenzhiyong12/article/details/109410200 解决方案:用一位大佬封装好的 vue-pdf-signature 替代vue-pdf
代码如下:
npm install --save vue-pdf-signature <el-dialog
title="pdf预览"
width="75%"
>
<div >
<div >
<div >
<span>{{ currentPage }}</span>
<span>/</span>
<span>{{ numPages }}</span>
</div>
<span />
<div >
<img src="../../static/image/reduce.png" alt="" >
<span>120%</span>
<img src="../../static/image/plus.png" alt="" >
</div>
</div>
<div >
<!-- <div @click="handleDownfile(index)"> -->
<div >
<img src="../../static/image/download.png" alt="" @click="downPdf()" >
<span>下载</span>
</div>
<el-button @click.stop="print">
<span />
<span>打印</span>
</el-button>
</div>
</div>
<div >
<div >
<el-scrollbar >
<pdf
v-for="currentPage in numPages"
id="pdf"
ref="pdf"
:src="pdfSrc"
:page="currentPage"
@num-pages="pageNum = $event"
@progress="loadedRatio = $event"
@loaded="loadPdfHandler = $event"
/>
</el-scrollbar>
</div>
<div />
</div>
</el-dialog>import pdf from ''vue-pdf-signature''
import CMapReaderFactory from ''vue-pdf-signature/src/CMapReaderFactory''
export default {
compoents: {
pdf
},
data() {
return {
pdfSrc: '''', // pdf绑定的url链接
numPages: null, // 循环的pdf总页数
pageNum: 4, // pdf总页数
}
},
methods: {
seePdf(index) {
this.dialogVisible = true
this.$http.queryRegionlist('''', this.filterDateTime, this.region, this.filterDateTime).then(res => {
this.currentPage = res.data.current
this.pdfSrc = pdf.createLoadingTask({ //接口中的url用createLoadingTask方法
url: res.data.records[index].url,
cMapPacked: true,
CMapReaderFactory
})
// 计算总页数实现分页展示多页
this.pdfSrc.promise
.then(pdf => {
this.numPages = pdf.numPages
})
.catch(err => {
console.error(''pdf 加载失败'', err)
})
})
},
}
}2、pdf下载功能实现
后端返回的pdf为文件流形式,下载方式有三种方式:
2.1、window.open(url)
downPdf() {
window.open( url ) // url代表接口中后端给的pdf的url
}2.2、HTML5中a标签的download属性实现下载,download.js已经封装好直接用。
import download from ''downloadjs'' //引入download.js// 下载pdf
downPdf() {
this.$http.downloadFile(this.ids).then(data => {
download(data)
})
}2.3、使用html2canvas和jspdf插件实现
2.3.1 下载安装模块
npm install html2canvas jspdf --save2.3.2 定义功能实现方法undefined
在项目工具方法存放文件夹utils中创建htmlToPdf.js文件,代码如下:
// 导出页面为PDF格式
import html2Canvas from ''html2canvas''
import JsPDF from ''jspdf''
export default{
install (Vue, options) {
Vue.prototype.getPdf = function () {
var title = this.htmlTitle
html2Canvas(document.querySelector(''#pdfDom''), {
allowTaint: true
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL(''image/jpeg'', 1.0)
let PDF = new JsPDF('''', ''pt'', ''a4'')
if (leftHeight < pageHeight) {
PDF.addImage(pageData, ''JPEG'', 0, 0, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, ''JPEG'', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save(title + ''.pdf'')
}
)
}
}
}2.3.3 全局引入实现方法 在项目主文件main.js中引入定义好的实现方法,并注册
import htmlToPdf from ''@/components/utils/htmlToPdf''
// 使用Vue.use()方法就会调用工具方法中的install方法
Vue.use(htmlToPdf)2.3.4 在相关要导出的页面中,点击时调用绑定在Vue原型上的getPdf方法,传入id即可
//html
<div id="pdfDom">
<!-- 要下载的HTML页面,页面是由后台返回 -->
<div v-html="pageData"></div>
</div>
<el-button type="primary" size="small" @click="getPdf(''#pdfDom'')">点击下载</el-button>
//js
export default {
data () {
return {
htmlTitle: ''页面导出PDF文件名''
}
}
}3、pdf打印功能实现
- 在vue-pdf组件上绑定ref属性,再到方法中使用$refs获取DOM文本,调用原型方法print()
// 打印
print() {
console.log(this.$refs.pdf) // 这儿的console.log 仅用于测试打印出多个结果
this.$refs.pdf.print()
},