如何在 Vue 中打印页面:直接用 web-print-pdf(npm 包)

这篇文章只讲一件事:在 Vue 项目里打印,用 web-print-pdf(npm 包)就够了。下面给出做法和可复用代码。

为什么不直接用 window.print

  • 需要用户点确认,不适合静默/批量
  • 不能可靠指定打印机、纸张、边距
  • 多浏览器差异大,行为不稳定

为什么用 web-print-pdf

  • 安装 npm 包,调用 API 即可
  • 支持 PDF / HTML / 图片
  • 可指定打印机、纸张、边距、份数、单双面
  • 支持静默与批量队列
  • 配合本地服务规避浏览器限制

在 Vue 项目中 5 分钟接入

1)安装依赖
bash 复制代码
npm i web-print-pdf
2)基础用法:打印当前页面渲染的 HTML(优先)

把需要打印的 DOM 转成 HTML 字符串(或独立路由),优先使用 webPrintPdf.printHtml;对于可访问页面也可使用 printHtmlByUrl

js 复制代码
// 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 });
    },
  },
};

模板:

vue 复制代码
<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 输出:

js 复制代码
import { printPdfByUrl } from 'web-print-pdf';

await printPdfByUrl({
  url: '/api/order/10086.pdf',
  printer: 'HP-LaserJet',
  paper: 'A4',
  silent: true,
});
4)打印图片/标签
js 复制代码
import { printImageByUrl } from 'web-print-pdf';

await printImageByUrl({ url: '/static/label.png', silent: true });

样式与排版

  • 准备打印专用 CSS:边距、分页符、隐藏交互元素
  • 字体就近可用:确认中文字体可用;PDF 更稳
  • 纸张与驱动一致:A4、80mm、小标签要匹配

场景举例

  • 面单/拣货单/出库单:批量静默,队列防阻塞
  • 门店小票/价签/标签:默认打印机直打
  • 医疗/政务表单:严格纸张与边距

常见问题

  • 样式错乱?独立模板或内联关键样式,少用复杂动画
  • 要静默?前端调 web-print-pdf,由本地服务执行
  • 选打印机/纸张?用 printerpaper,以驱动能力为准
  • 批量会卡?有队列与并发控制,必要时分批

结语

总结:生产环境建议"后端生成 PDF + 前端用 web-print-pdf 打印"。够稳、够省心。

生成 PDF 的方案对比(后端 vs 前端)

当你选择"打印 PDF"路径时,通常有两类生成方式:

--- 后端生成(Puppeteer/Playwright/Electron)

  • 稳定,字体与版式一致;适合批量/离线;可审计
  • 需要规划算力与并发,打包字体与静态资源

--- 前端生成(DOM→PDF,如 html2pdf、jsPDF+html2canvas)

  • 前端自给自足,所见即所得
  • 复杂页面有偏差风险;大页面性能有限;浏览器差异明显

结论:生产用后端生成;轻量导出可用前端,但要评估样式与性能。

Vue 2 示例(Options API)

vue 复制代码
<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)

vue 复制代码
<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>
相关推荐
web打印社区3 小时前
最简单的 Web 打印方案:用 5 分钟上手 web-print-pdf(npm 包)
前端·pdf·npm
转转技术团队3 小时前
AI在前后端联调提效的实践
前端·后端
小码编匠3 小时前
基于 Spring Boot + Vue 的轻量级进销存系统
vue.js·spring boot·后端
UrbanJazzerati3 小时前
使用Mockoon快速搭建Mock API:从入门到实战
前端·面试
林太白3 小时前
NestJS-身份验证JWT的使用以及登录注册
前端·后端·前端框架
Cache技术分享3 小时前
200. Java 异常 - Throwing Exceptions: 指定方法抛出的异常
前端·后端
Mintopia3 小时前
🚀 cesium-kit:让 Cesium 开发像写 UI 组件一样简单
前端·前端框架·cesium