You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Print.js适配58mm热敏POS打印机打印收据及替代方案咨询

解决Print.js适配58mm热敏POS打印机及替代方案

一、修复Print.js的58mm适配及边距问题

你现在遇到的A4边距问题,是因为Print.js默认采用了A4纸张的打印配置,哪怕你给内容div设了58mm宽度,打印时浏览器还是会套用A4的边距规则。可以通过以下步骤调整:

1. 自定义Print.js配置参数

修改你的打印调用代码,添加自定义样式和打印配置,覆盖默认的A4设置:

$("#print-receipt").on("click", function() {
  printJS({
    printable: "invoice-print-div",
    type: "html",
    // 自定义打印样式,强制去掉边距并固定宽度
    style: `
      @media print {
        body { margin: 0 !important; padding: 0 !important; width: 58mm !important; }
        #invoice-print-div { display: block !important; }
        #invoice-print-div > div { width: 58mm !important; margin: 0 !important; padding: 0 2mm; /* 留一点点内边距避免内容贴边 */ }
      }
    `,
    scanStyles: false, // 禁用默认的样式扫描,避免干扰自定义样式
    // 指定需要保留的目标元素样式,确保你的内容样式生效
    targetStyle: ["width", "margin", "padding", "text-align", "background-color", "border"]
  });
});

2. 优化HTML结构的基础样式

给打印区域的div补充更明确的样式,同时在页面头部添加打印媒体查询的全局样式:

<head>
  <style>
    .hidden { display: none; }
    @media print {
      /* 确保打印时页面整体适配58mm宽度 */
      body {
        width: 58mm;
        margin: 0;
        padding: 0;
      }
      .hidden { display: block !important; }
    }
  </style>
</head>

这样调整后,Print.js会按照58mm的宽度打印,并且去掉多余的A4边距。

二、JavaScript打印的替代方案

如果Print.js还是达不到你的预期,或者你想尝试更灵活的方式,这里有几个实用的替代方案:

1. 原生window.print() + 自定义打印样式

这是最轻量化的方案,完全不需要第三方库,通过控制打印区域和打印样式来实现:

$("#print-receipt").on("click", function() {
  // 临时隐藏页面上不需要打印的元素
  const nonPrintElements = $("body > *:not(#invoice-print-div)");
  nonPrintElements.addClass("print-hidden");
  
  // 显示打印区域
  $("#invoice-print-div").removeClass("hidden");
  
  // 触发打印
  window.print();
  
  // 打印完成后恢复页面状态
  nonPrintElements.removeClass("print-hidden");
  $("#invoice-print-div").addClass("hidden");
});

对应的CSS补充:

.print-hidden { display: none !important; }
@media print {
  body { width: 58mm; margin: 0; padding: 0; }
  #invoice-print-div > div { width: 58mm; padding: 0 2mm; }
}

2. 使用ESC/POS专用打印库

热敏POS打印机大多支持ESC/POS指令,用专门的库可以直接发送原生指令,能精准控制字体、对齐、切纸等操作,比HTML打印更稳定。比如前端的escpos-js:

// 示例(需引入escpos-js库)
const { Printer, Model, USB } = require('escpos');

// 通过USB连接打印机(需浏览器支持Web USB)
USB.requestDevice().then(device => {
  const adapter = new USB(device);
  const printer = new Printer(new Model('TM-T88V'), adapter);
  
  printer
    .font('a')
    .align('ct') // 居中对齐
    .text('alpha')
    .newLine()
    // 打印表格
    .table([
      ['Item', 'Qty', 'Price'],
      ['abc', '1', '120'],
      ['pqr', '2', '240'],
      ['xyz', '4', '360']
    ])
    .newLine(2)
    .cut() // 切纸
    .close();
});

这种方式适合需要精细控制打印格式的场景,比如打印条码、logo或者自定义字体。

3. Web Bluetooth/Web USB直接通信

如果你的打印机支持蓝牙或USB连接,可以用浏览器的Web Bluetooth/Web USB API直接发送ESC/POS指令,不需要额外库。比如Web USB的示例:

async function printReceipt() {
  const device = await navigator.usb.requestDevice({ filters: [{ vendorId: 0x04b8 }] }); // 替换为你的打印机厂商ID
  await device.open();
  await device.selectConfiguration(1);
  await device.claimInterface(0);
  
  // 发送ESC/POS指令:初始化、居中、打印文本等
  const commands = [
    Buffer.from([0x1B, 0x40]), // 初始化打印机
    Buffer.from('\x1B\x61\x01'), // 居中对齐
    Buffer.from('alpha\n'),
    Buffer.from('Item    Qty    Price\n'),
    Buffer.from('abc     1      120\n'),
    Buffer.from('pqr     2      240\n'),
    Buffer.from('xyz     4      360\n'),
    Buffer.from([0x1D, 0x56, 0x01]) // 切纸
  ];
  
  for (const cmd of commands) {
    await device.transferOut(1, cmd);
  }
  
  await device.close();
}

$("#print-receipt").on("click", printReceipt);

这个方案的优势是完全原生,不需要依赖任何第三方库,但需要打印机支持对应的通信方式,且浏览器版本较新。

内容的提问来源于stack exchange,提问作者Atharva Kale

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:29:08