一. 需求
1. 点击文档列表中的【打印】按钮,获取后台生成的PDF的url,弹窗进行预览:
2. 点击【打印】按钮,进行打印预览和打印:
二. 需求实现
首先后台给的是word文档,研究了一圈后发现暂时无法实现(需要跳转谷歌预览、格式错乱等问题),于是要求后台大佬给换成pdf。
非常感谢大佬dearmrzhang的分享,这篇文章实现的需求比本文复杂的多,我这里只是单页pdf的预览和打印,大佬的分享则涉及img和pdf的分别处理、分页等,原文:手摸手系列之前端Vue实现PDF预览及打印的终极解决方案
我的代码比较简单,注意首先需要在项目引入这两个库:
vue-pdf
print-js
1. 模版
<template>
<div class="main">
<div style="padding: 20px">
<a-form layout="inline" style="color: black; margin-bottom: 22px">
<a-row :gutter="48">
<a-col>
<a-form-item label="运单号" style="margin-right: 30px">
<a-input placeholder="请输入运单号" allow-clear size="large" v-model="queryParam.waybillNo"></a-input>
</a-form-item>
<sava-button class="button" @click="doSearch">查询</sava-button>
</a-col>
</a-row>
</a-form>
<a-table
ref="table"
:columns="columns"
:dataSource="loadData"
:loading="loading"
:row-key="(record) => record.id"
:pagination="pagination"
@change="handleTableChange"
style="margin-top: 10px"
>
<span slot="action" slot-scope="text, record">
<!-- <a @click="handleEdit(record)" style="color: #2b79c2">编辑</a> -->
<a @click="viewDetail(record)" style="color: #2b79c2; margin-left: 10px">查看</a>
<a @click="printBill(record)" style="color: #2b79c2; margin-left: 10px">打印</a>
</span>
</a-table>
<a-modal :visible="previewVisibleForAll" :footer="null" @cancel="handleCancelAll" :width="800">
<div style="overflow-y: auto; overflow-x: hidden">
<a-button shape="round" icon="file-pdf" @click="handlePrint(printData)" size="small">打印</a-button>
<div id="printFrom">
<pdf ref="pdf" :src="previewFileSrc"></pdf>
</div>
</div>
</a-modal>
</div>
</div>
</template>
2. 核心业务逻辑
<script>
// 两个库引入
import pdf from 'vue-pdf'
import printJS from 'print-js'
// 接口
import { reqWayBillList, reqBillReport } from '@/api/DigitalWayBill/DigitalWayBill'
export default {
components: {
pdf,
},
data() {
return {
queryParam: {
waybillNo: '',
},
columns: [
],
loadData: [],
loading: false,
pagination: {},
mdl: null,
enterpriseInfo: [],
inspectorInfo: [],
fenceParam: {},
pdfUrl: '', // 你的 PDF 文件 URL
progress: 0,
printData: {
printable: 'printFrom',
header: '',
ignore: ['no-print'],
},
previewVisibleForAll: false,
pageTotal: null,
previewFileSrc: '',
}
},
created() {
this.doSearch()
},
methods: {
doSearch() {
this.loading = true
reqWayBillList(this.queryParam).then((res) => {
console.log('way bill list', res)
this.loadData = res.records
this.loading = false
})
},
handleTableChange(pagination) {
const pager = { ...this.pagination1 }
pager.current = pagination.current
this.pagination1 = pager
this.queryParam1.pageIndex = pagination.current
this.doSearch()
},
viewDetail(record) {
console.log('click view')
this.mdl = { ...record }
// 将获取的信息传递到新页面
this.$router.push({
path: '/bill/detail',
query: {
data: JSON.stringify(this.mdl),
},
})
},
printBill(record) {
this.$message.success('生成文档需要一些时间, 请稍候...', 10)
reqBillReport(record.waybillNo)
.then((res) => {
console.log('pdf url', res)
this.previewFileSrc = res
this.previewVisibleForAll = true
})
.catch((err) => {
this.$message.error(`获取文档失败: ${err}`)
})
},
handlePrint(params) {
printJS({
printable: params.printable, // 'printFrom', // 标签元素id
type: params.type || 'html',
header: params.header, // '表单',
targetStyles: ['*'],
style: '@page {margin:0 10mm};', // 可选-打印时去掉眉页眉尾
ignoreElements: params.ignore || [], // ['no-print']
properties: params.properties || null,
})
},
printPdf() {
this.$refs.pdf.print()
// window.print()
},
handleCancel() {
this.previewVisible = false
},
handleCancelAll() {
this.previewVisibleForAll = false
},
},
}
</script>
3. 样式
没有额外的样式,都写在模版标签里了
三. 总结
市面上有一些pdf预览和打印的库,正如dearmrzhang大佬讲的,都有一些不足;通过与print-js的组合使用,才完美解决了预览和打印的需求。
感谢观看,希望本文能帮助您解决相关需求问题。