如何在 Vue 中打印页面:直接用 web-print-pdf(npm 包)
这篇文章只讲一件事:在 Vue 项目里打印,用 web-print-pdf(npm 包)就够了。下面给出做法和可复用代码。
为什么不直接用 window.print
- 需要用户点确认,不适合静默/批量
- 不能可靠指定打印机、纸张、边距
- 多浏览器差异大,行为不稳定
为什么用 web-print-pdf
- 安装 npm 包,调用 API 即可
- 支持 PDF / HTML / 图片
- 可指定打印机、纸张、边距、份数、单双面
- 支持静默与批量队列
- 配合本地服务规避浏览器限制
在 Vue 项目中 5 分钟接入
1)安装依赖
npm i web-print-pdf
2)基础用法:打印当前页面渲染的 HTML(优先)
把需要打印的 DOM 转成 HTML 字符串(或独立路由),优先使用 webPrintPdf.printHtml
;对于可访问页面也可使用 printHtmlByUrl
。
// src/views/Order.vue(示例)
import { printHtml, printHtmlByUrl } from 'web-print-pdf';export default {name: 'OrderView',methods: {async handlePrint() {const target = this.$refs.printArea; // 需要打印的 DOM 区域const html = `<!doctype html><html><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><style>/* 可内联必要样式,保证版式一致 */</style></head><body>${target.outerHTML}</body></html>`;await printHtml({content: html,printer: '', // 不填走系统默认打印机paper: 'A4',silent: true,});// 或:await printHtmlByUrl({ url: '/print/page.html', paper: 'A4', silent: true });},},
};
模板:
<template><div class="page"><div ref="printArea" class="print-container"><h2>订单 #10086</h2><p>客户:张三</p><p>金额:¥199.00</p></div><button @click="handlePrint">打印</button></div>
></template>
3)打印 PDF(推荐生产使用)
将页面数据渲染为 PDF(后端或前端生成),用 printPdfByUrl
输出:
import { printPdfByUrl } from 'web-print-pdf';await printPdfByUrl({url: '/api/order/10086.pdf',printer: 'HP-LaserJet',paper: 'A4',silent: true,
});
4)打印图片/标签
import { printImageByUrl } from 'web-print-pdf';await printImageByUrl({ url: '/static/label.png', silent: true });
样式与排版
- 准备打印专用 CSS:边距、分页符、隐藏交互元素
- 字体就近可用:确认中文字体可用;PDF 更稳
- 纸张与驱动一致:A4、80mm、小标签要匹配
场景举例
- 面单/拣货单/出库单:批量静默,队列防阻塞
- 门店小票/价签/标签:默认打印机直打
- 医疗/政务表单:严格纸张与边距
常见问题
- 样式错乱?独立模板或内联关键样式,少用复杂动画
- 要静默?前端调 web-print-pdf,由本地服务执行
- 选打印机/纸张?用
printer
、paper
,以驱动能力为准 - 批量会卡?有队列与并发控制,必要时分批
结语
总结:生产环境建议“后端生成 PDF + 前端用 web-print-pdf 打印”。够稳、够省心。
生成 PDF 的方案对比(后端 vs 前端)
当你选择“打印 PDF”路径时,通常有两类生成方式:
— 后端生成(Puppeteer/Playwright/Electron)
- 稳定,字体与版式一致;适合批量/离线;可审计
- 需要规划算力与并发,打包字体与静态资源
— 前端生成(DOM→PDF,如 html2pdf、jsPDF+html2canvas)
- 前端自给自足,所见即所得
- 复杂页面有偏差风险;大页面性能有限;浏览器差异明显
结论:生产用后端生成;轻量导出可用前端,但要评估样式与性能。
Vue 2 示例(Options API)
<template><div class="page"><div ref="printArea" class="print-container"><h2>订单 #10086</h2><p>客户:张三</p><p>金额:¥199.00</p></div><button @click="handlePrint">打印</button></div>
</template><script>
import { printHtml, printPdfByUrl } from 'web-print-pdf';export default {name: 'OrderView',methods: {async handlePrint() {const target = this.$refs.printArea;const html = `<!doctype html><html><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><style>body{margin:0;padding:0}.print-container{padding:16px}</style></head><body>${target.outerHTML}</body></html>`;await printHtml({ content: html, paper: 'A4', silent: true });},async handlePrintPdf() {await printPdfByUrl({ url: '/api/order/10086.pdf', paper: 'A4', silent: true });},},
};
</script><style scoped>
.print-container { background: #fff; color: #222; }
</style>
Vue 3 + setup 示例(Composition API)
<template><div class="page"><div ref="printArea" class="print-container"><h2>订单 #10087</h2><p>客户:李四</p><p>金额:¥299.00</p></div><button @click="handlePrint">打印 HTML</button><button @click="handlePrintPdf">打印 PDF</button></div>
</template><script setup>
import { ref } from 'vue';
import { printHtml, printPdfByUrl } from 'web-print-pdf';const printArea = ref(null);async function handlePrint() {const target = printArea.value;const html = `<!doctype html><html><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><style>body{margin:0;padding:0}.print-container{padding:16px}</style></head><body>${target.outerHTML}</body></html>`;await printHtml({ content: html, paper: 'A4', silent: true });
}async function handlePrintPdf() {await printPdfByUrl({ url: '/api/order/10087.pdf', paper: 'A4', silent: true });
}
</script><style scoped>
.print-container { background: #fff; color: #222; }
</style>