接入指南

打印组件接入文档

将传思网"打印模板"能力嵌入到您的网站,让您的用户在线设计模板、下发到本地客户端并触发打印。共三步:完成身份核验(申请 API Key 并换取 Token)→ 安装本地 ClientPrinter 客户端 → 引入 wacp.js SDK 调用「设计 / 下载 / 打印」。

在线设计 下发到本地 本地打印

1身份核验(申请 API Key + 换取 Token)

使用 wacp.js 的设计器与下载能力前,需要一个有效的 API Key 并换取 Poster 服务 Token(打印模板与海报共用同一类型 Token)。详细步骤请参阅:

概要:注册账号 → 申请 API Key → 用 ApiKey + serviceType=Poster 换取 Token(有效期 1 小时)→ 把 Token 传给 SDK。
注意:OCR / ASR / TTS 的 Token 不可用于打印模板接入,必须使用 serviceType=Poster
Token 仅在两处使用:① 调用 wacp.openDesigner 打开设计器时;② 调用 wacp.downloadTemplate 把模板下发到本地时。
后续 wacp.print 完全走本机链路,无需 Token、断网亦可继续打印

2安装本地打印客户端 ClientPrinter

打印动作发生在用户的本机(依赖系统打印机驱动),因此需要在每台需要打印的电脑上安装 ClientPrinter。它兼容 Windows 7 / 10 / 11(32 位 / 64 位)

安装后的客户端为 SDK 提供两项能力:

  • 注册 acp:// 自定义协议,浏览器可自动唤起客户端,无需用户手动启动;
  • 持久化已下载的模板,断网仍可继续打印;客户端不持久化任何 Token
首次接入须知:
• 点击上方按钮下载安装包后,双击运行并按提示完成系统打印机驱动安装;
• 安装后需允许其开机自启,否则用户每次需手动启动;
• 浏览器首次唤起 acp:// 时会弹出"是否允许打开 ClientPrinter",请勾选"始终允许"以避免反复确认;
• 未检测到客户端运行时,SDK 会自动弹出下载提示。

3引入 SDK 并完成三段式调用

3.1 引入 wacp.js

在您的网站页面引入 wacp.js

html
<script src="https://your-webapi.com/printtemplate/wacp.js"></script>
<script>
  var wacp = new Wacp();
</script>

3.2 打开模板设计器(openDesigner)

调用 wacp.openDesigner(token, options, onReady) 在新窗口打开设计器,用户保存模板时通过 onReady 回调拿到 templateId 并持久化到您的业务系统。

参数 必填 类型 说明
token string Poster 服务 Token。
options.templateId string 已有模板 ID。不传 则创建空白模板;传入 则加载已有模板用于继续编辑。
options.dataSourceFields object 设计器内可绑定的数据源字段映射,{ 英文键: '中文显示名' },例如 { userName: '姓名', orderId: '工号' }
options.dpi number 新建模板时画布的初始 DPI,常用 203(热敏标签/小票)/ 300(激光)/ 600(照片)。仅未传 templateId 时生效;不传时设计器默认 203,用户仍可在工具栏修改。详见下方「DPI 参数怎么填」。
options.width / options.height number 新建模板时画布初始尺寸(单位:像素)。仅未传 templateId 时生效,未传时设计器自带默认。
onReady function 设计器保存或退出时回调 { templateId, error, type }templateId 即为可持久化到三方业务系统的模板 ID。
js
// 打开设计器(独立窗口)
wacp.openDesigner(
  'a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6',
  {
    templateId: '',                       // 留空 = 新建
    dpi: 203,                             // 新建画布初始 DPI(203 / 300 / 600)
    dataSourceFields: {
      userName: '姓名',
      orderId:  '工号'
    }
  },
  function (ev) {
    if (ev.error) {
      console.error('[wacp] 设计器返回错误:', ev.error);
      return;
    }
    // ev.templateId 为最终保存的模板 ID
    // 业务方持久化此 ID,用于后续 download / print
    localStorage.setItem('myTemplateId', ev.templateId);
    console.log('模板已保存,templateId:', ev.templateId);
  }
);
设计器要求:必须在「打印参数」面板中填写 widthMm(毫米宽)/ heightMm(毫米高)/ dpi(建议 203 / 300),保存时会强校验,否则拒绝入库。

3.3 把模板下载到本地(downloadTemplate)

用户首次打印(或模板更新后)需把云端最新模板下发到本地 ClientPrinter。SDK 会自动尝试唤起本地客户端:

参数 必填 类型 说明
token string Poster 服务 Token。
templateId string 云端模板 ID(由 openDesigner 保存时返回)。
name string 本地显示名称,仅用于客户端「查看本机模板」下拉列表展示;允许重复,本地仍以 templateId 唒一。未传时默认使用 templateId 作为名称。
js
// 不传名称:本地以 templateId 作为显示名
wacp.downloadTemplate(token, templateId)
  .then(function (info) {
    // info = { templateId, name }
    console.log('模板已下发到本地:', info.templateId, info.name);
  })
  .catch(function (err) {
    // 常见错误:本地 ClientPrinter 未运行(acp:// 唤起失败)/ token 过期 / 模板不存在
    alert('下发失败:' + err.message);
  });

// 传入中文名称:客户端下拉列表中会显示“工号牌-2026版”
wacp.downloadTemplate(token, templateId, '工号牌-2026版');

// 也可以传对象形式
wacp.downloadTemplate(token, templateId, { name: '工号牌-2026版' });
这是整个链路里唯一需要 token 的客户端动作。下发完成后,ClientPrinter 立即丢弃 token 不持久化;后续 wacp.print 全程本地,不再需要 token。
关于名称重复:本地客户端「查看本机模板」的下拉框仅展示 name,不拼接 ID。如果多个模板使用同名称,用户从视觉上无法区分,但选中后系统仍会按唯一的 templateId 加载;建议业务侧在名称中附加可识别后缀(如「工号牌-A版」/「工号牌-B版」)。

3.4 触发本地打印(print)

打印动作完全在用户本机执行,无需联网。一次调用支持多条数据 + 多份份数。

参数 必填 类型 说明
templateId string 必须为已经 downloadTemplate 过的模板 ID;本地未找到时报错。
payload.rows object[] 非空数组,每个对象一条打印记录。键名必须与设计器中绑定的 dataSourceFields 一致。
payload.copies number 每条记录的打印份数,默认 1
js
wacp.print(templateId, {
  rows: [
    { userName: '张三', orderId: 'A001' },
    { userName: '李四', orderId: 'A002' }
  ],
  copies: 1
})
.then(function (res) {
  console.log('已下达打印任务:', res);
})
.catch(function (err) {
  console.error('打印失败:', err.message);
});

3.5 删除云端模板(deleteTemplate)

当不再需要某个模板时,可从服务器永久删除。删除后该模板不可恢复,但本地已下载的副本不受影响(仍可继续打印)。

参数 必填 类型 说明
token string Poster 服务 Token。
templateId string 要删除的模板 ID(由 openDesigner 保存时返回)。
js
wacp.deleteTemplate(token, templateId)
  .then(function (res) {
    console.log('模板已删除:', res.message);
  })
  .catch(function (err) {
    // 常见错误:token 过期 / 模板不存在 / 无权删除(非本账号创建的模板)
    alert('删除失败:' + err.message);
  });
注意:删除为不可逆操作,建议在业务层增加二次确认。删除仅影响云端存储;若本地 ClientPrinter 已下载该模板,本地副本仍然有效,但无法再通过 downloadTemplate 重新拉取。

3.6 事件订阅

事件 触发时机
connectedSDK 与本地 ClientPrinter 建链成功。
disconnected本地连接断开(用户关闭客户端、网络异常等)。
printed本地完成一次打印,payloadtaskCount 等统计字段。
error调用链路中的任何错误(连接超时、token 过期、模板不存在)。
idCardRead / idCardConnected /
idCardDisconnected / idCardError /
idCardReaderSwitched / idCardReaderEnabled
身份证读卡器推送事件,详见下文「3.8 身份证读卡器」。
js
wacp.on('connected', function () { console.log('客户端已连接'); });
wacp.on('printed',   function (e) { console.log('打印完成', e); });
wacp.on('error',     function (e) { console.error('SDK 错误', e); });

扩展能力(本地存取 / 读卡器 / 系统)

除「设计 / 下发 / 打印」主链路外,wacp.js 还封装了 ClientPrinter 在本机提供的应用能力,可调用本机键值存取、身份证读卡器、系统动作等,本节能力全部走本机链路,不需 token

3.7 本机键值对存取 (setItems / getItems / removeItems)

将 UI 常用参数(如部门名、上次选择、设备号)写入本机 Settings 表,断电不丢;同一台机器上不同页面/会话都能读到。存储 value 统一以字符串语义调度。

js
// 写入(同名键会被覆盖)
wacp.setItems({
  deptName: '行政部',
  userName: '张三',
  lastTplId: 'tpl_20260520_xxx'
});

// 读取:返回只包含存在的 key
wacp.getItems(['deptName', 'userName']).then(function (m) {
  console.log(m.deptName, m.userName); // 行政部 张三
});

// 删除
wacp.removeItems(['deptName']);
与浏览器 localStorage 的区别:setItems 写入的是本机 ClientPrinter,与浏览器、域名均无关;同一台电脑上的任何三方网站都能读取。

3.8 身份证读卡器

ClientPrinter 内置两种读卡器驱动:HS100N(USB 免驱)与 SerialPort(串口 IDM40 类)。SDK 提供状态查询 / 切换 / 开关控制以及 推送式读卡事件

方法 说明
switchIDCardReader(type)切换型号,type'HS100N''SerialPort'。返回 { readerType }
getIDCardReaderType()查询当前型号。返回 { readerType }
setIDCardReaderEnabled(enabled)开启 / 关闭读卡。返回 { enabled, readerType }
getIDCardReaderEnabled()查询读卡开关状态。返回 { enabled, readerType }

推送事件(服务端主动广播):

事件名 触发时机 / payload
idCardRead读到身份证。ev.data 为包含姓名、性别、身份证号、地址、照片 base64 等字段的对象。
idCardConnected读卡器设备已连接(USB 插入 / 串口打开)。
idCardDisconnected读卡器设备已拔出,插回后会自动重新广播 connected
idCardError读卡过程异常(SDK 异常、设备占用等)。
idCardReaderSwitched调用 switchIDCardReader 后会同时返回 Promise,也会广播该事件。
idCardReaderEnabled读卡开关变更(包括在 ClientPrinter 本机 UI 手动切换)。
js
// 订阅读卡事件(在调用 setIDCardReaderEnabled(true) 之前订阅以免丢事件)
wacp.on('idCardRead', function (ev) {
  // ev.data 示例:
  // {
  //   Name: '张三', Sex: '男', Nation: '汉', Birth: '19900101',
  //   Address: '北京市海淀区中关村大街1号',
  //   IDCardNo: '110108199001011234',
  //   Department: '北京市公安局海淀分局',
  //   ValidStart: '20200101', ValidEnd: '20400101',
  //   PhotoBase64: 'data:image/bmp;base64,...'  // 按驱动不同可能为 JPG
  // }
  console.log('读到身份证', ev.data);
});
wacp.on('idCardError',        function (ev) { console.error('读卡错误', ev.data); });
wacp.on('idCardDisconnected', function () { /* 提示用户重插 */ });

// 选择型号 + 开启读卡
wacp.switchIDCardReader('HS100N')
    .then(function () { return wacp.setIDCardReaderEnabled(true); })
    .then(function (r) { console.log('读卡已开启', r); });
设备要求:
HS100N 需插入 USB 读卡器,ClientPrinter 会自动检测;
SerialPort(IDM40 类串口读卡器)需要使用手动点亮其驱动,ClientPrinter 会自动探测串口;
• 设备拔插后会自动推送 idCardConnected / idCardDisconnected,业务侧只需代码订阅事件即可。

3.9 系统能力

方法 说明
createDesktopShortcut(name, url)在用户桌面创建一个网页快捷方式,使用默认浏览器打开。按机器头一次使用时快速引导。
getClientNum()获取本机 ClientPrinter 的唯一通道号 ClientNum,返回 { clientNum }
clearPrintTasks()清空本机打印任务队列,不影响已下发给驱动的任务。
clearTemplates()清空本机所有已下载的模板(谨慎),后续需重新 downloadTemplate
connect()显式建立 WebSocket 连接。默认采用懒建连,等首次业务调用时自动建连。
js
// 1)创建桌面快捷方式
wacp.createDesktopShortcut('打印组件 Demo',
    'https://tools.eainfor.com/printtemplate/demo-printer.html');

// 2)查询本机通道号
wacp.getClientNum().then(function (r) { console.log(r.clientNum); });

// 3)集中作业中零凌时清队
wacp.clearPrintTasks();

在线体验

我们提供了一个集成 Demo 启动页,覆盖「换 Token / 设计模板 / 下发到本地 / 触发打印」全链路,可在不写代码的情况下走通流程:

建议先在 Demo 启动页跑通一次完整链路(确认本机 ClientPrinter 已安装、能成功唤起 + 出纸),再按上面的示例代码集成到您自己的网站。

DPI 参数怎么填

设计器顶部工具栏的 DPI 输入框(默认 203)决定模板的 毫米 ↔ 像素 折算关系:

formula
画布像素宽 = widthMm × dpi ÷ 25.4
画布像素高 = heightMm × dpi ÷ 25.4

所以 DPI 必须与目标打印机的实际 DPI 一致,否则本地客户端会按比例缩放,导致出纸尺寸偏大或偏小。

推荐取值

打印机类型 推荐 DPI
热敏标签机(条码、胸卡)203
热敏小票机203
普通激光 / 喷墨打印机300
高精度照片打印600
快速判断(标签机/小票机):型号末尾常带数字。例如 XX-203 即为 203 dpi,XX-300 即为 300 dpi。

如何在 Windows 查看打印机 DPI

打开 控制面板 → 设备和打印机,右键目标打印机 → 打印机属性,然后按下表查找:

选项卡 查看位置
常规 部分驱动会在"型号 / Model"行显示 203 dpi 等字样。
高级 打印默认值...图形质量,会有"分辨率"下拉框,列出 203 dpi / 300 dpi 等可选值。
设备设置 标签机驱动通常在这里有"打印头分辨率 / Print Head Resolution"选项。
注意:办公激光 / 喷墨打印机的"打印质量"里可能列出 600 dpi / 1200 dpi,那是最大输出分辨率,不是物理 DPI。普通办公场景按 300 填即可,更高反而可能引起缩放问题。

实在查不到?用试错法

如果没有规格书也找不到驱动属性,按推荐值填一个,然后通过设计器右上角的 🖨️ 打印测试页 试打一张,再用尺子量纸面:

  • 量出来比设计的 → 填的 DPI 小了,调高(如 203 → 300);
  • 量出来比设计的 → 填的 DPI 大了,调低(如 300 → 203);
  • 量出来一致 → DPI 就是对的。

常见问题

Q1:浏览器一直提示"无法连接到本地 ClientPrinter"
• 确认本机已安装并运行 ClientPrinter(任务栏托盘有对应图标);未安装请点击 下载 ClientPrinter
• 确认浏览器允许 acp:// 协议唤起(Chrome 首次需勾选"始终允许");
• 默认监听端口为 8080,若被占用可在 ClientPrinter 配置中修改,并同步传入 new Wacp({ wsUrl: 'ws://127.0.0.1:新端口/' })
Q2:保存模板提示"模板缺少 print 节"
• 设计器右侧「打印参数」面板必须填写 widthMm / heightMm / dpi(均为正数);
• dpi 推荐:热敏标签 203 / 热敏小票 203 / 普通激光打印机 300。
Q3:打印出纸为空白或字段未替换
• 检查 rows[i] 的键名是否与设计器中绑定的 dataSourceFields 一致(区分大小写);
• 若设计器使用 {{key}} 占位符,请确保 key 已加入 dataSourceFields 并在 rows 中提供值。
Q4:打印物理尺寸与设计器预览不一致
print.dpi 必须与目标打印机实际 DPI 匹配,否则会被等比缩放;
• 横向打印机请将 print.rotate90 设为 true,仅做长宽交换,无需重新设计内容。
Q5:Token 报错"服务类型不匹配"
• 换取 Token 时 serviceType 必须为 Poster
• OCR / ASR / TTS 的 Token 不可用于打印模板接入,需要单独换取。