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

JS实现ZPL标签直接发送至IP10.100.2.200网络热敏打印机方案咨询

库存标签ZPL打印优化实现方案

实现选项说明

下面分别对应你提的两个需求的可落地实现:

  • 方案一:点击按钮直接唤起系统打印窗口,无需下载txt文件,手动选择对应热敏打印机即可完成打印
  • 方案二:搭配极简本地代理服务,实现点击按钮直接发送打印任务到IP为10.100.2.200的网络打印机,完全无中间操作

方案一:一键唤起打印窗口的完整页面代码

<!DOCTYPE html>
<html>
<head>
    <title>Print Inventory Labels at Papa's</title>
    <style>
        * {
            box-sizing: border-box;
        }
        div {
            padding: 10px;
            background-color: #f6f6f6;
            overflow: hidden;
        }
        input[type=text], textarea, select {
            font: 17px Calibri;
            width: 100%;
            padding: 12px;
            border: 1px solid #ccc;
            border-radius: 4px;
        }
        input[type=button]{ 
            font: 17px Calibri;
            width: auto;
            float: right;
            cursor: pointer;
            padding: 7px;
        }
                .container{
  width: 100%;
  margin: 3.2rem auto 0 auto;
}

@media(min-width: 576px){
  .container{
    max-width: 540px;
  }
}

@media(min-width: 768px){
  .container{
    max-width: 720px
  }
    </style>
</head>
<body>
    <div>
        <div class="container">  
        <div align="center">
          <img src="https://www.papasjeepram.com/wp-content/uploads/2019/09/logo2.jpg" width="500" height="189" alt="Papa's Logo">
        </div>
      <h2>Enter Values to Generate Stock Label</h2>
      
        <div>
            <input type="text" onkeyup="this.value = this.value.toUpperCase();"id="txtStock" placeholder="Stock Number" />
        </div>
        <div>
            <input type="text" onkeyup="this.value = this.value.toUpperCase();"id="txtVin" maxlength="17" placeholder="Vin" />
        </div>
        <div>
            <input type="text" onkeyup="this.value = this.value.toUpperCase();"id="txtYear" maxlength="4" placeholder="Year" />
        </div>
        <div>
            <input type="text" onkeyup="this.value = this.value.toUpperCase();" id="txtMake" placeholder="Make" />
        </div>
        <div>
            <input type="text" onkeyup="this.value = this.value.toUpperCase();" id="txtModel" placeholder="Model" />
        </div>
        <div>
            <input type="text" onkeyup="this.value = this.value.toUpperCase();" id="txtColor" placeholder="Color" />
        </div>
        
        <div>
            <div align="left">
              <input type="button" id="bt" value="Generate Label" onclick="printLabel()" />
            </div>
        </div>

    </div>
</body>
<script>
    let printLabel = () => {
        // 获取表单数据
        const Stock = document.getElementById('txtStock');
        const Vin = document.getElementById('txtVin');
        const Year = document.getElementById('txtYear');
        const Make = document.getElementById('txtMake');
        const Model = document.getElementById('txtModel');
        const Color = document.getElementById('txtColor');

        // 生成ZPL内容
        let data = 
'\r^XA\n' + 
'^A0,213\n' + 
'^FO25,35^FD' + Stock.value + '^FS \r\n '+ 
'^BY3,2,225\n' + 
'^FO45,220^BC^FD' + Vin.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO45,500^FD' + Year.value + ' ' + Make.value + ' ' + Model.value + ' ' + Color.value + ' ^FS \r\n '+ 
'^A0,55\n' +
'^FO435,630^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO275,630^FD' + Year.value + '^FS \r\n '+ 
'^A0,55\n' +
'^FO45,630^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO695,630^FD' + Year.value + '^FS \r\n '+ 
'^A0,55\n' +
'^FO435,835^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO275,835^FD' + Year.value + '^FS \r\n '+ 
'^A0,55\n' +
'^FO45,835^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO695,835^FD' + Year.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO45,705^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO45,745^FD' + Vin.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO45,780^FD' + Color.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,705^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,745^FD' + Vin.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,780^FD' + Color.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO40,900^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO40,940^FD' + Vin.value + '^FS \r\n '+
'^A0,30\n' +
'^FO40,975^FD' + Color.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,900^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,940^FD' + Vin.value + '^FS \r\n '+
'^A0,30\n' +
'^FO435,975^FD' + Color.value + '^FS \r\n '+ 
'^XZ';
            
        // 创建隐藏的打印容器
        const printFrame = document.createElement('iframe');
        printFrame.style.position = 'absolute';
        printFrame.style.width = '0';
        printFrame.style.height = '0';
        printFrame.style.border = 'none';
        document.body.appendChild(printFrame);
        
        // 写入ZPL内容到iframe
        const frameDoc = printFrame.contentWindow || printFrame.contentDocument;
        frameDoc.document.open();
        frameDoc.document.write(`<pre>${data}</pre>`);
        frameDoc.document.close();
        
        // 等待加载完成后唤起打印
        setTimeout(() => {
            printFrame.contentWindow.focus();
            printFrame.contentWindow.print();
            document.body.removeChild(printFrame);
        }, 100);
    }
</script>
</html>

方案二:直接发送到指定网络打印机实现

步骤1:启动本地代理服务

浏览器无法直接发送TCP请求到打印机的9100原始打印端口,需要先启动一个本地代理服务,你可以用Node.js快速实现,代码如下:

const net = require('net');
const http = require('http');

// 打印机配置
const PRINTER_IP = '10.100.2.200';
const PRINTER_PORT = 9100;
const PROXY_PORT = 8080;

const server = http.createServer((req, res) => {
    // 允许跨域请求
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Methods', 'POST, OPTIONS');
    res.setHeader('Access-Control-Allow-Headers', '*');

    if (req.method === 'OPTIONS') {
        res.writeHead(200);
        res.end();
        return;
    }

    if (req.method === 'POST') {
        let zplContent = '';
        req.on('data', chunk => zplContent += chunk.toString());
        req.on('end', () => {
            // 连接打印机发送ZPL数据
            const printerSocket = net.connect(PRINTER_PORT, PRINTER_IP, () => {
                printerSocket.write(zplContent, () => {
                    printerSocket.end();
                    res.writeHead(200);
                    res.end('打印任务已发送');
                });
            });
            printerSocket.on('error', err => {
                console.error('连接打印机失败', err);
                res.writeHead(500);
                res.end('打印机连接失败');
            });
        });
    } else {
        res.writeHead(405);
        res.end('仅支持POST请求');
    }
});

server.listen(PROXY_PORT, () => {
    console.log(`打印代理服务已启动,监听端口${PROXY_PORT}`);
});

只要本地安装Node.js,把上面代码保存为print-proxy.js,执行node print-proxy.js即可启动代理。

步骤2:修改前端打印逻辑

把方案一中的printLabel函数替换为以下代码即可:

let sendToPrinter = async () => {
    // 获取表单数据
    const Stock = document.getElementById('txtStock');
    const Vin = document.getElementById('txtVin');
    const Year = document.getElementById('txtYear');
    const Make = document.getElementById('txtMake');
    const Model = document.getElementById('txtModel');
    const Color = document.getElementById('txtColor');

    // 生成ZPL内容
    let data = 
'\r^XA\n' + 
'^A0,213\n' + 
'^FO25,35^FD' + Stock.value + '^FS \r\n '+ 
'^BY3,2,225\n' + 
'^FO45,220^BC^FD' + Vin.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO45,500^FD' + Year.value + ' ' + Make.value + ' ' + Model.value + ' ' + Color.value + ' ^FS \r\n '+ 
'^A0,55\n' +
'^FO435,630^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO275,630^FD' + Year.value + '^FS \r\n '+ 
'^A0,55\n' +
'^FO45,630^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO695,630^FD' + Year.value + '^FS \r\n '+ 
'^A0,55\n' +
'^FO435,835^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO275,835^FD' + Year.value + '^FS \r\n '+ 
'^A0,55\n' +
'^FO45,835^FD' + Stock.value + '^FS \r\n '+ 
'^A0,50\n' +
'^FO695,835^FD' + Year.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO45,705^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO45,745^FD' + Vin.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO45,780^FD' + Color.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,705^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,745^FD' + Vin.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,780^FD' + Color.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO40,900^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO40,940^FD' + Vin.value + '^FS \r\n '+
'^A0,30\n' +
'^FO40,975^FD' + Color.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,900^FD' + Make.value + ' ' + Model.value + '^FS \r\n '+ 
'^A0,30\n' +
'^FO435,940^FD' + Vin.value + '^FS \r\n '+
'^A0,30\n' +
'^FO435,975^FD' + Color.value + '^FS \r\n '+ 
'^XZ';
    
    try {
        const res = await fetch('http://localhost:8080', {
            method: 'POST',
            body: data
        });
        if (res.ok) {
            alert('打印任务已发送成功');
        } else {
            alert('打印失败,请检查代理服务和打印机是否正常');
        }
    } catch (e) {
        alert('打印失败,请检查代理服务是否启动');
    }
}

同时把按钮的点击事件改为onclick="sendToPrinter()"即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:45:09