vue实现pdf打印开单
使用vue实现PDF打印开单功能
安装依赖库
需要安装html2canvas和jspdf两个库用于将HTML转换为PDF
npm install html2canvas jspdf --save
创建打印组件
创建一个可复用的PDF打印组件,包含需要打印的内容区域和打印按钮

<template>
<div>
<div id="printArea" class="print-content">
<!-- 这里是需要打印的内容 -->
<h1>销售单据</h1>
<table>
<tr>
<th>商品名称</th>
<th>数量</th>
<th>单价</th>
<th>金额</th>
</tr>
<tr v-for="(item, index) in items" :key="index">
<td>{{ item.name }}</td>
<td>{{ item.quantity }}</td>
<td>{{ item.price }}</td>
<td>{{ item.price * item.quantity }}</td>
</tr>
</table>
</div>
<button @click="generatePDF">打印单据</button>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
export default {
data() {
return {
items: [
{ name: '商品A', quantity: 2, price: 100 },
{ name: '商品B', quantity: 1, price: 200 }
]
}
},
methods: {
generatePDF() {
const element = document.getElementById('printArea')
html2canvas(element).then(canvas => {
const imgData = canvas.toDataURL('image/png')
const pdf = new jsPDF('p', 'mm', 'a4')
const imgWidth = 190
const imgHeight = canvas.height * imgWidth / canvas.width
pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight)
pdf.save('销售单据.pdf')
})
}
}
}
</script>
<style>
.print-content {
width: 100%;
padding: 20px;
background: white;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
</style>
优化打印样式
为打印内容添加专用样式,确保打印效果符合预期
@media print {
body * {
visibility: hidden;
}
#printArea, #printArea * {
visibility: visible;
}
#printArea {
position: absolute;
left: 0;
top: 0;
width: 100%;
}
}
添加打印参数配置
扩展生成PDF方法,支持自定义文件名、纸张方向和边距

generatePDF(fileName = '销售单据', orientation = 'p', margin = 10) {
const element = document.getElementById('printArea')
html2canvas(element, {
scale: 2,
logging: false,
useCORS: true
}).then(canvas => {
const imgData = canvas.toDataURL('image/png')
const pdf = new jsPDF(orientation, 'mm', 'a4')
const imgWidth = pdf.internal.pageSize.getWidth() - margin * 2
const imgHeight = canvas.height * imgWidth / canvas.width
pdf.addImage(imgData, 'PNG', margin, margin, imgWidth, imgHeight)
pdf.save(`${fileName}.pdf`)
})
}
处理长内容分页
对于超出一页的内容,自动分页处理
generatePDF() {
const element = document.getElementById('printArea')
const pdf = new jsPDF('p', 'mm', 'a4')
const margin = 10
const pageWidth = pdf.internal.pageSize.getWidth()
const pageHeight = pdf.internal.pageSize.getHeight()
html2canvas(element, {
scale: 2
}).then(canvas => {
const imgData = canvas.toDataURL('image/png')
const imgWidth = pageWidth - margin * 2
const imgHeight = canvas.height * imgWidth / canvas.width
let heightLeft = imgHeight
let position = margin
let page = 1
pdf.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight)
heightLeft -= pageHeight
while (heightLeft >= 0) {
position = heightLeft - imgHeight
pdf.addPage()
pdf.addImage(imgData, 'PNG', margin, position, imgWidth, imgHeight)
heightLeft -= pageHeight
page++
}
pdf.save('销售单据.pdf')
})
}
使用注意事项
确保打印区域的内容在DOM加载完成后才执行转换操作,避免内容未完全渲染导致的打印不完整问题。对于动态数据,建议在数据加载完成后再触发打印操作。
打印样式建议使用固定单位(如mm、pt)而非响应式单位(如%、vw),以确保打印尺寸的准确性。测试不同浏览器的兼容性,特别是IE浏览器可能需要额外的polyfill支持。






