Node + Electron 调用科诚 G500 小票打印机(EZPL)完整方案

94 阅读2分钟

适用场景:在 Electron 页面点击按钮即可静默触发小票打印,支持文本和二维码打印。

打印机型号:科诚 G500U

Node 环境:16.20.2

依赖模块koffi

外部 DLLEZio64.dll

官方 DLL 下载地址:科诚官网 EZio DLL V1.0.0.18


Ⅰ. 背景

科诚 G500 打印机支持 EZPL 指令集,官方示例提供的是 C++ / C# 的调用方式,但 Node.js 版本并未提供。本文通过 koffi 模块封装 DLL 调用,实现 Node 环境下的静默打印。

目标功能:

  • 打开/关闭打印机端口(USB / COM / Network)
  • 设置打印参数(纸张高度、黑度、速度等)
  • 发送 EZPL 指令
  • 打印文本、Unicode 中文、二维码
  • 绘制简单图形
  • 获取 DLL 版本号

EZPL只要是支持EZPL的打印机都可以使用


Ⅱ. 安装依赖

npm install koffi

确保 EZio64.dll 已放在项目的 public 目录(开发环境)或 Electron resources 目录(打包环境)。


Ⅲ. 封装打印机类 godex.class.js

const path = require('path');
const koffi = require('koffi');
​
const getEZio64Path = () => {
    if (__dirname.split(path.sep).includes("app.asar")) {
        return path.join(process.resourcesPath, 'EZio64.dll');
    }
    return path.join(__dirname, '..', '..', '..', 'public', 'EZio64.dll');
}
​
class GodexPrinter {
    constructor(dllPath = null) {
        this.dllPath = dllPath || getEZio64Path();
        this.port = null;
        this.initialized = false;
​
        try {
            this.lib = koffi.load(this.dllPath);
            this.funcs = {
                openport: this.lib.func('openport', 'int', ['string']),
                closeport: this.lib.func('closeport', 'int', []),
                sendcommand: this.lib.func('sendcommand', 'int', ['string']),
                setup: this.lib.func('setup', 'int', ['int','int','int','int','int','int']),
                ecTextOut: this.lib.func('ecTextOut', 'int', ['int','int','int','string','string']),
                ecTextOutW: this.lib.func('ecTextOutW', 'int', ['int','int','int','string','string','int']),
                Bar_QRcode_S: this.lib.func('Bar_QRcode_S', 'int', ['int','int','int','string']),
                GetDllVersion: this.lib.func('GetDllVersion', 'int', ['string'])
            };
            this.initialized = true;
            console.log(`✅ 已加载 DLL: ${this.dllPath}`);
        } catch (err) {
            console.error("❌ 加载 EZio64.dll 失败:", err.message);
        }
    }
​
    open(port = "6") {
        if (!this.initialized) throw new Error("DLL 未加载");
        const result = this.funcs.openport(port);
        if (result === 1) this.port = port;
        return result;
    }
​
    close() {
        if (!this.initialized) return;
        const result = this.funcs.closeport();
        this.port = null;
        return result;
    }
​
    setup({ height=40, dark=10, speed=4, mode=0, gap=2, top=0 } = {}) {
        return this.funcs.setup(height,dark,speed,mode,gap,top);
    }
​
    send(command) {
        if (!this.port) throw new Error("端口未打开");
        const cmd = command.endsWith('\r\n') ? command : command + '\r\n';
        return this.funcs.sendcommand(cmd);
    }
​
    printText(x, y, height, fontName, text) {
        return this.funcs.ecTextOut(x, y, height, fontName, text);
    }
​
    printTextW(x, y, height, text, fontName="") {
        const buf = Buffer.from(text, 'utf16le');
        return this.funcs.ecTextOutW(x, y, height, fontName, buf, buf.length);
    }
​
    printQRCode(x, y, data) {
        const len = Buffer.byteLength(data, 'utf8');
        return this.funcs.Bar_QRcode_S(x, y, len, data);
    }
​
    getDllVersion() {
        const versionBuf = Buffer.alloc(64);
        const len = this.funcs.GetDllVersion(versionBuf);
        return versionBuf.toString('utf8', 0, len);
    }
​
    // 示例打印方法
    rukudan10070Print(data) {
        const date = new Date().toISOString().split('T')[0];
        const qrContent = `物品:${data.itemN},图号:${data.custDrawingNum},数量:${data.inStockQuantity}${data.unitN},入库:${date}`;
        const sum = data.inStockQuantity + '' + data.unitN || '';
​
        this.open("6");
        this.send("^W100");
        this.send("^Q70,10");
        this.send("^L");
​
        this.printTextW(25, 10, 24, `物品名称:${data.itemN}`);
        this.printTextW(25, 50, 24, `图号:${data.custDrawingNum}`);
        this.printTextW(25, 90, 24, `批次:${data.itemBatch}`);
        this.printTextW(25, 130, 24, `数量: ${sum}`);
        this.printTextW(25, 170, 24, `入库日期:${date}`);
        this.printQRCode(320, 50, qrContent);
​
        this.send("^P1");
        this.send("E");
        this.close();
    }
}
​
module.exports = GodexPrinter;

Ⅳ. 使用示例

const GodexPrinter = require('./g500Print/godex.class.js');
​
const data = {
    itemN: "测试物品",
    custDrawingNum: "T-1001",
    itemBatch: "B20251028",
    inStockQuantity: 10,
    unitN: "个"
};
​
const printer = new GodexPrinter();
printer.rukudan10070Print(data);

点击按钮即可触发打印,无需用户交互。

DLL 函数绑定 可以参考 科诚官网 EZio DLL V1.0.0.18 中的pdf


Ⅵ. 小结

通过 koffi 封装 EZio64.dll,Node.js + Electron 可以完美支持科诚 G500 小票打印机的 EZPL 指令集。适合仓库入库单、收据、标签打印等场景,支持中文文本、二维码以及自定义纸张尺寸。