web 批量静默打印怎么做?batchPrint 从入门到排坑

柜面连打三张凭证、仓库一次打五张面单、窗口批量补打历史单据------单张 printHtml 循环调用看似简单,实则容易踩 并发、顺序、预览混用 等坑。

本文以 npm 包 web-print-pdfbatchPrint 为核心,说明批量静默打印的正确用法、合并规则与常见错误;终端需安装并运行 Web打印专家 本地客户端。

资源 链接
官网 http://webprintpdf.com/
客户端下载 http://webprintpdf.com/downloadApp/
npm 包 https://www.npmjs.com/package/web-print-pdf
GitHub https://github.com/weixiaoyi/web-print-pdf

1. 为什么不要自己 for 循环调 printHtml

手写循环的问题:

自己循环 batchPrint
N 次 WebSocket 往返,延迟叠加 一次请求,服务端编排
难以保证 PDF 全部生成后再统一出纸 先并行转 PDF,再按任务打印
预览 / 打印 action 容易混在一批里 服务端强制校验 action 一致
前端要自己处理部分失败 统一错误返回,日志在客户端

结论 :批量场景应优先 batchPrint,而不是 for + printHtml


2. batchPrint 在架构里的位置

复制代码
业务页 batchPrint(printTaskList, ...)
        │  WebSocket 一条消息 type: batchPrint
        ▼
Web打印专家
   ├─ 并行:各 task → HTML/PDF 生成(generatePdf 队列)
   └─ 串行/并发:各 PDF → 打印子进程(printPdf 队列)
        ▼
   本地打印机(Windows Spooler / CUPS)

客户端内部对 PDF 生成打印下发 各有一套 TaskQueue,根据 CPU / 内存动态控制并发,避免连点「批量打印」把机器打满。


3. 快速上手

3.1 最小示例:连打两张 HTML

javascript 复制代码
import webPrintPdf from "web-print-pdf";

const pdfOptions = {
  paperFormat: "A4",
  margin: { top: "10px", bottom: "10px", left: "10px", right: "10px" },
  printBackground: true,
};

const printOptions = {
  printerName: "你的打印机名", // 建议 getPrinterList() 动态获取
  paperFormat: "A4",
  copies: 1,
};

const extraOptions = { action: "print" };

await webPrintPdf.batchPrint(
  [
    { data: "<div><h1>凭证一</h1></div>", type: "printHtml" },
    { data: "<div><h1>凭证二</h1></div>", type: "printHtml" },
  ],
  pdfOptions,
  printOptions,
  extraOptions
);

3.2 混合类型:HTML + 远程 PDF

javascript 复制代码
await webPrintPdf.batchPrint(
  [
    { data: "<div>小票 HTML</div>", type: "printHtml" },
    { data: "https://intranet/reports/1001.pdf", type: "printPdfByUrl" },
    { data: "https://intranet/label.png", type: "printImageByUrl" },
  ],
  pdfOptions,
  printOptions,
  extraOptions
);

3.3 支持的 task.type

type data 含义
printHtml HTML 字符串
printHtmlByUrl 可访问的报表 URL
printHtmlByBase64 Base64 编码的 HTML
printPdfByUrl PDF 文件 URL
printPdfByBase64 Base64 PDF
printImageByUrl 图片 URL
printImageByBase64 Base64 图片

4. 参数合并规则(必看)

调用签名:

javascript 复制代码
batchPrint(printTaskList, pdfOptions, printOptions, extraOptions)

浅合并 :全局的 pdfOptions / printOptions / extraOptions 会与每个 task 上的同名字段合并,task 级优先

javascript 复制代码
await webPrintPdf.batchPrint(
  [
    {
      data: "<div>A</div>",
      type: "printHtml",
      printOptions: { copies: 2 }, // 覆盖全局 copies
    },
    {
      data: "<div>B</div>",
      type: "printHtml",
      printOptions: { printerName: "二楼打印机" }, // 单独指定打印机
    },
  ],
  { paperFormat: "A4", printBackground: true },     // 全局 pdfOptions
  { paperFormat: "A4", copies: 1 },                 // 全局 printOptions
  { action: "print", requestTimeout: 30 }
);

4.1 硬约束:action 必须一致

合并后,所有 task 的 extraOptions.action 必须相同 (要么全是 print,要么全是 preview)。若一批里既有静默又有预览,服务端直接抛错:

text 复制代码
every printTask's extraOptions.action must be equal in printTaskList when after shallow merged!

排坑 :全局 extraOptions.action = 'print',某个 task 误设 action: 'preview' → 整批失败。

4.2 预览模式

全局或 task 设 action: 'preview' 时,不会出纸 ,返回 printPreviewUrlpdfs 列表,供联调版式。


5. 业务场景配方

5.1 柜面连打「受理单 + 回执 + 清单」

javascript 复制代码
const tasks = [
  { data: receiptHtml, type: "printHtml" },
  { data: ackHtml, type: "printHtml" },
  { data: listHtml, type: "printHtml" },
];
await webPrintPdf.batchPrint(tasks, pdfOptions, printOptions, { action: "print" });

三份 HTML 建议各自内联样式,减少对外部 CSS 依赖。

5.2 不同打印机(task 级 printOptions)

javascript 复制代码
await webPrintPdf.batchPrint(
  [
    { data: customerCopy, type: "printHtml", printOptions: { printerName: "前台激光" } },
    { data: archiveCopy, type: "printHtml", printOptions: { printerName: "办公室 A4" } },
  ],
  pdfOptions,
  {},
  extraOptions
);

5.3 内网 URL 批量(带登录态)

全局 extraOptions 传 cookie / header:

javascript 复制代码
const extraOptions = {
  action: "print",
  requestTimeout: 30,
  cookies: { SESSION: "xxx" },
  httpHeaders: { Authorization: "Bearer token" },
};

await webPrintPdf.batchPrint(
  urls.map((url) => ({ data: url, type: "printHtmlByUrl" })),
  pdfOptions,
  printOptions,
  extraOptions
);

6. 排坑清单

现象 常见原因 处理
整批报错 action 不一致 task 与全局 action 混用 统一为 printpreview
只打了第一张 前端循环误用 await 顺序 / 客户端未启动 改用 batchPrint;确认 Web打印专家在运行
后面几张空白 HTML 无 @media print / 字体缺失 内联样式;安装字体
队列堆积不出纸 打印机卡纸、驱动异常 见《故障排查手册》08 篇
批量很慢 单 task 的 URL 超时;PDF 队列满 requestTimeout;减少单次 batch 数量
printerName 报错 硬编码开发机名称 getPrinterList() 动态取

6.1 批量大小建议

  • 单次 5~20 张 较稳妥(视 HTML 复杂度与机器配置)
  • 超大 batch 建议业务侧拆批,并在 UI 上显示「打印队列处理中」
  • 客户端可通过日志 API 查看 PDF / 打印阶段耗时

6.2 不要用 batchPrint 冒充「严格顺序保证」

PDF 生成阶段是 Promise.all 并行 ;打印阶段也是并行触发多个 printPdf.print。若业务要求 严格先 A 后 B 的物理顺序,应在应用层拆成两次调用,或与运维确认打印机队列 FIFO 行为。


7. 与单张 API 的选型

场景 推荐 API
单张凭证 printHtml
单张远程 PDF printPdfByUrl
连打多张 / 混合类型 batchPrint
服务端推任务 远程打印 / _printByRawMessage

8. 小结

  • 批量静默打印 请用 batchPrint,不要手写 for 循环。
  • 搞清 浅合并action 一致 两条规则,能避开大部分联调失败。
  • 终端安装 Web打印专家,前端 npm install web-print-pdf 即可。

更多 API 与参数说明见 npm 文档与客户端内置「运行示例」。