Vue3 发票静默打印,我这边能跑通的一版

管理后台订单页,财务要打发票:别弹浏览器框,样式用现有 HTML。后端能不动就不动。

浏览器自己搞不定静默,得本机挂打印客户端,前端用 npm 发包。我用的是 web-print-pdf:

https://www.npmjs.com/package/web-print-pdf

bash 复制代码
npm install web-print-pdf
# 或 pnpm add web-print-pdf

抽了个小函数

ts 复制代码
// useSilentPrint.ts
import webPrintPdf from 'web-print-pdf'

export async function printInvoiceHtml(
  html: string,
  opts: { printerName?: string; copies?: number; preview?: boolean } = {}
) {
  return webPrintPdf.printHtml(
    html,
    {
      paperFormat: 'A4',
      margin: { top: '15mm', bottom: '15mm', left: '12mm', right: '12mm' },
      printBackground: true,
    },
    {
      printerName: opts.printerName,
      paperFormat: 'A4',
      copies: opts.copies ?? 1,
    },
    { action: opts.preview ? 'preview' : 'print' }
  )
}

页面里

打印区和屏幕展示区不必同一个 DOM,拿数据拼字符串我更稳,少被页面上的按钮、侧栏污染。

vue 复制代码
<script setup lang="ts">
import { ref } from 'vue'
import { printInvoiceHtml } from '@/composables/useSilentPrint'

const props = defineProps<{ order: any }>()
const loading = ref(false)
const error = ref('')

function buildHtml() {
  const rows = props.order.items
    .map((i: any) => `<tr><td>${i.name}</td><td>${i.qty}</td><td>¥${i.price}</td></tr>`)
    .join('')
  return `
    <div style="font-family:sans-serif">
      <h1 style="font-size:18px">销售发票</h1>
      <p>单号:${props.order.id}</p>
      <p>客户:${props.order.customer}</p>
      <table width="100%" cellpadding="8" cellspacing="0">${rows}</table>
      <p style="text-align:right;font-weight:600">合计:¥${props.order.amount}</p>
    </div>`
}

async function onPrint(preview: boolean) {
  loading.value = true
  error.value = ''
  try {
    await printInvoiceHtml(buildHtml(), { preview })
  } catch (e: any) {
    error.value = e?.message || '打印失败,先看本机客户端开了没'
  } finally {
    loading.value = false
  }
}
</script>

按钮两个:一个 preview,一个真正 print。版式问题别和「连不上」搅在一起查。

联调时我真正在看的

客户端托盘在不在。

CSS 背景要 printBackground。

多机写死 printerName。

批量别自己 for 裸奔,先看文档 batchPrint。

React 也一样,换个按钮 onClick 而已。框架不是瓶颈,客户端在不在才是。

能接受弹窗的低频打印,Print.js 就够。必须静默再上这套。Print.js 的 issue 里也有人要 silent,维护者说过纯前端不行------别再找开关了。

相关推荐
雪芽蓝域zzs6 小时前
第 2 节:基础扩展 - 下拉弹窗常用原生属性
vue.js·elementui
扶风ff7 小时前
新品知识更新太快?用练题簿在线刷题,安排企业培训的小测与复盘
前端·学习·小程序
对空六课7 小时前
支持注意力分析的热力图工具有哪些?
前端·数据库·数据分析
Csvn8 小时前
Vue3 响应式与编译:依赖收集如何升级为节点级靶向更新
前端
星栈9 小时前
pnpm 12 升级实测
前端·javascript
Sirens.10 小时前
Java并发锁详解:六类锁策略与 synchronized 底层原理
java·前端·算法
Ai-_Man10 小时前
您您这可以把Microsofat Copilot的多个会话比如说。左侧的多个会话一次性导出吗?不是单条会话里面的多次会对话。AI导出鸭
javascript·人工智能·ai·小程序·电脑·copilot
特创数字科技11 小时前
一个纯本地运行的图片处理工具:压缩 / 裁剪 / 九宫格 / 圆角 / 滤镜 / 拼图 / 水印,终生使用
前端
IT_陈寒12 小时前
Vue的v-if和v-for混用居然是个天坑
前端·人工智能·后端
天衍四九-12 小时前
【无标题】
前端·spring boot·mysql·nginx·docker