这是一个用于 Windows 系统的 ESC/POS 打印机驱动程序,使用 Node.js 和 C++ 实现。支持中英文混合打印,自动编码转换。
- 支持中英文混合打印
- 自动处理中文编码(GBK)
- 支持常用的 ESC/POS 命令
- 支持文本样式设置(加粗、对齐、大小等)
- 支持条形码打印(多种格式)
- 支持二维码打印(可调整大小和纠错等级)
- 支持图片打印(自动优化,支持抖动处理)
- 仅支持 Windows 系统
npm i @mixgeeker/node-escpos-win
- Windows 操作系统
- Node.js 14.0.0 或更高版本 (我用的是22)
- Windows SDK(用于编译 C++ 代码,单纯使用的话应该不要,何况我也没公布源码(bushi) 笑~)
- Visual Studio Build Tools (正常情况也不用)
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
// 创建打印机实例,参数为打印机名称
const printer = new ESCPOSPrinter('Your Printer Name');
// 方法一:分别打印中英文
printer.printAscii('Hello World'); // 打印英文
printer.printChinese('你好,世界'); // 打印中文
// 方法二:混合打印中英文
const printData = Buffer.concat([
ESCPOSPrinter.commands.INIT, // 初始化打印机
ESCPOSPrinter.commands.ALIGN_CENTER, // 居中对齐
ESCPOSPrinter.commands.CHINESE_MODE, // 切换到中文模式
ESCPOSPrinter.commands.BOLD_ON, // 开启加粗
printer.textToBuffer('收据标题\n', 'GBK'),
ESCPOSPrinter.commands.BOLD_OFF, // 关闭加粗
ESCPOSPrinter.commands.ALIGN_LEFT, // 左对齐
printer.textToBuffer('商品:测试商品\n', 'GBK'),
printer.textToBuffer('价格:¥9.99\n', 'GBK'),
printer.textToBuffer('时间:' + new Date().toLocaleString() + '\n', 'GBK'),
ESCPOSPrinter.commands.LF, // 换行
ESCPOSPrinter.commands.ALIGN_CENTER, // 居中对齐
ESCPOSPrinter.commands.CUT // 切纸
]);
printer.print(printData);
// 最后关闭打印机连接
printer.close();
- 支持多种图片格式(PNG、JPEG、BMP等)
- 自动调整图片大小以适应打印纸宽度
- 支持抖动算法处理,提高灰度打印效果
- 可调整打印参数(宽度、阈值、抖动等)
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
const printer = new ESCPOSPrinter('Your Printer Name');
// 打印图片
async function printImage() {
try {
// 使用默认参数打印
await printer.printImage('path/to/image.png');
// 使用自定义参数打印
await printer.printImage('path/to/image.png', {
width: 384, // 打印宽度(针对58mm打印纸)
threshold: 128, // 黑白转换阈值(0-255)
dither: true // 是否使用抖动算法
});
printer.print(ESCPOSPrinter.commands.CUT);
printer.close();
} catch (error) {
console.error('打印失败:', error);
printer.close();
}
}
printImage();
包含了一个测试工具 test_image.js
,可以测试不同的图片打印效果:
node test_image.js "打印机名称" "图片路径"
测试工具会:
- 使用默认参数打印图片
- 使用无抖动效果打印图片
- 使用较小尺寸打印图片
这样您可以比较不同参数下的打印效果,选择最适合的设置。
-
图片格式:
- 推荐使用 PNG 或 JPEG 格式
- 对于线条图或文字,建议使用 PNG 格式
- 对于照片,可以使用 JPEG 格式
-
图片大小:
- 58mm 打印纸最大可打印 384 点
- 80mm 打印纸最大可打印 576 点
- 建议根据打印纸宽度调整 width 参数
-
图片优化:
- 使用
dither: true
可以提高灰度图片的打印效果 - 对于黑白图片,可以设置
dither: false
获得更清晰的效果 - 通过调整
threshold
参数(0-255)可以控制黑白转换的临界值
- 使用
-
ESCPOSPrinter.commands.INIT
: 初始化打印机
-
ESCPOSPrinter.commands.CUT
: 切纸
-
ESCPOSPrinter.commands.ASCII_MODE
: 切换到 ASCII 模式 -
ESCPOSPrinter.commands.CHINESE_MODE
: 切换到中文模式
-
ESCPOSPrinter.commands.BOLD_ON
: 开启加粗 -
ESCPOSPrinter.commands.BOLD_OFF
: 关闭加粗
-
ESCPOSPrinter.commands.ALIGN_LEFT
: 左对齐 -
ESCPOSPrinter.commands.ALIGN_CENTER
: 居中对齐 -
ESCPOSPrinter.commands.ALIGN_RIGHT
: 右对齐
-
ESCPOSPrinter.commands.TEXT_NORMAL
: 正常大小 -
ESCPOSPrinter.commands.TEXT_DOUBLE_HEIGHT
: 双倍高度 -
ESCPOSPrinter.commands.TEXT_DOUBLE_WIDTH
: 双倍宽度 -
ESCPOSPrinter.commands.TEXT_DOUBLE_SIZE
: 双倍大小
-
ESCPOSPrinter.commands.FONT_A
: 标准字体 -
ESCPOSPrinter.commands.FONT_B
: 压缩字体 -
printer.setFontA()
: 设置为标准字体A -
printer.setFontB()
: 设置为压缩字体B
-
ESCPOSPrinter.commands.TEXT_SIZE(width, height)
: 设置字体宽度和高度-
width
: 宽度倍数(0-7,0表示正常宽度,1表示2倍宽度,以此类推) -
height
: 高度倍数(0-7,0表示正常高度,1表示2倍高度,以此类推)
-
-
printer.setTextSize(width, height)
: 设置字体大小 -
printer.setTextNormal()
: 设置为正常大小 -
printer.setTextDoubleHeight()
: 设置为双倍高度 -
printer.setTextDoubleWidth()
: 设置为双倍宽度 -
printer.setTextDoubleSize()
: 设置为双倍大小(宽度和高度都是2倍)
-
ESCPOSPrinter.commands.BARCODE_HEIGHT
: 设置条形码高度 -
ESCPOSPrinter.commands.BARCODE_WIDTH
: 设置条形码宽度 -
ESCPOSPrinter.commands.BARCODE_FONT
: 设置 HRI 字符字体 -
ESCPOSPrinter.commands.BARCODE_POSITION
: 设置 HRI 字符打印位置 -
ESCPOSPrinter.commands.BARCODE_TYPE
: 条形码类型-
UPC_A
: UPC-A 条码 -
UPC_E
: UPC-E 条码 -
EAN13
: EAN-13 条码 -
EAN8
: EAN-8 条码 -
CODE39
: CODE 39 条码 -
ITF
: ITF 条码 -
CODABAR
: CODABAR 条码
-
-
ESCPOSPrinter.commands.QR_SIZE
: 设置二维码大小(1-16) -
ESCPOSPrinter.commands.QR_ERROR_LEVEL
: 设置二维码纠错等级 -
ESCPOSPrinter.commands.QR_STORE_DATA
: 存储二维码数据 -
ESCPOSPrinter.commands.QR_PRINT
: 打印二维码
-
ESCPOSPrinter.commands.LF
: 换行
-
ESCPOSPrinter.imageCommands.S8_HIGH_DENSITY
: 高密度点阵图模式 -
ESCPOSPrinter.imageCommands.LINE_SPACING
: 设置行间距
-
ESCPOSPrinter.getPrinterList(): Array<PrinterInfo>
: 获取系统中所有打印机的列表- 返回值:打印机信息数组
interface PrinterInfo { name: string; // 打印机名称 description: string; // 打印机描述 isDefault: boolean; // 是否为默认打印机 }
- 返回值:打印机信息数组
new ESCPOSPrinter(printerName: string)
-
print(data: Buffer | string): boolean
: 打印数据 -
printChinese(text: string): boolean
: 打印中文文本 -
printAscii(text: string): boolean
: 打印英文文本 -
textToBuffer(text: string, charset?: 'ASCII' | 'GBK'): Buffer
: 文本转换为指定编码的 Buffer -
close(): void
: 关闭打印机连接 -
setFontA(): boolean
: 设置为标准字体A -
setFontB(): boolean
: 设置为压缩字体B -
setTextSize(width?: number, height?: number): boolean
: 设置字体大小 -
setTextNormal(): boolean
: 设置为正常大小 -
setTextDoubleHeight(): boolean
: 设置为双倍高度 -
setTextDoubleWidth(): boolean
: 设置为双倍宽度 -
setTextDoubleSize(): boolean
: 设置为双倍大小 -
printBarcode(data: string, type?: string, options?: BarcodeOptions): boolean
: 打印条形码-
data
: 条形码数据 -
type
: 条形码类型(默认为 'EAN13') -
options
: 条形码选项-
width
: 条形码宽度(默认为 3) -
height
: 条形码高度(默认为 64) -
font
: HRI 字符字体(默认为 0) -
position
: HRI 字符打印位置(默认为 2)
-
-
-
printQRCode(data: string, options?: QRCodeOptions): boolean
: 打印二维码-
data
: 二维码数据(文本或URL) -
options
: 二维码选项-
size
: 二维码大小(1-16,默认为 8) -
errorLevel
: 纠错等级(48-51,默认为 49)- 48: 纠错等级 L (7%)
- 49: 纠错等级 M (15%)
- 50: 纠错等级 Q (25%)
- 51: 纠错等级 H (30%)
-
-
-
processImage(imagePath: string, options?: ImageOptions): Promise<Buffer>
: 处理图片数据-
imagePath
: 图片文件路径 -
options
: 图片处理选项-
width
: 打印宽度(默认 384,适用于 58mm 打印纸) -
threshold
: 黑白转换阈值(0-255,默认 128) -
dither
: 是否使用抖动算法(默认 true)
-
-
-
printImage(imagePath: string, options?: ImageOptions): Promise<boolean>
: 打印图片- 参数同
processImage
- 参数同
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
const printer = new ESCPOSPrinter('Your Printer Name');
// 准备打印数据
const printData = Buffer.concat([
ESCPOSPrinter.commands.INIT,
ESCPOSPrinter.commands.ALIGN_CENTER,
ESCPOSPrinter.commands.CHINESE_MODE,
// 标题
ESCPOSPrinter.commands.BOLD_ON,
ESCPOSPrinter.commands.TEXT_DOUBLE_SIZE,
printer.textToBuffer('收银小票\n', 'GBK'),
ESCPOSPrinter.commands.TEXT_NORMAL,
ESCPOSPrinter.commands.BOLD_OFF,
// 商店信息
printer.textToBuffer('测试商店\n', 'GBK'),
printer.textToBuffer('电话:1234567890\n', 'GBK'),
printer.textToBuffer('------------------------\n', 'GBK'),
// 订单信息
ESCPOSPrinter.commands.ALIGN_LEFT,
printer.textToBuffer('订单号:123456789\n', 'GBK'),
printer.textToBuffer('日期:' + new Date().toLocaleString() + '\n', 'GBK'),
printer.textToBuffer('------------------------\n', 'GBK'),
// 商品列表
printer.textToBuffer('商品名称 数量 金额\n', 'GBK'),
printer.textToBuffer('测试商品A 1 ¥9.9\n', 'GBK'),
printer.textToBuffer('测试商品B 2 ¥19.8\n', 'GBK'),
printer.textToBuffer('------------------------\n', 'GBK'),
// 总计
ESCPOSPrinter.commands.ALIGN_RIGHT,
printer.textToBuffer('总计:¥29.7\n', 'GBK'),
ESCPOSPrinter.commands.LF,
// 二维码
ESCPOSPrinter.commands.ALIGN_CENTER,
printer.textToBuffer('扫描关注我们\n', 'GBK'),
ESCPOSPrinter.commands.LF
]);
// 打印数据
printer.print(printData);
// 打印二维码
printer.printQRCode('https://github.com/MixGeeker/ESCPOS-for-Windows', {
size: 8,
errorLevel: 49
});
// 打印条形码
printer.print(Buffer.concat([
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.LF
]));
printer.printBarcode('1234567890128', 'EAN13', {
width: 3,
height: 64
});
// 最后切纸
printer.print(Buffer.concat([
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.CUT
]));
// 关闭打印机连接
printer.close();
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
const printer = new ESCPOSPrinter('Your Printer Name');
// 打印图片
async function printWithImage() {
try {
// 打印标题
printer.print(Buffer.concat([
ESCPOSPrinter.commands.INIT,
ESCPOSPrinter.commands.ALIGN_CENTER,
ESCPOSPrinter.commands.CHINESE_MODE,
ESCPOSPrinter.commands.BOLD_ON,
printer.textToBuffer('图片打印测试\n', 'GBK'),
ESCPOSPrinter.commands.BOLD_OFF,
ESCPOSPrinter.commands.LF
]));
// 打印 LOGO
await printer.printImage('./logo.png', {
width: 384, // 适用于 58mm 打印纸
threshold: 128, // 黑白转换阈值
dither: true // 使用抖动算法,提高图片质量
});
// 打印分隔线和页尾
printer.print(Buffer.concat([
ESCPOSPrinter.commands.LF,
printer.textToBuffer('------------------------\n', 'GBK'),
ESCPOSPrinter.commands.ALIGN_CENTER,
printer.textToBuffer('页尾信息\n', 'GBK'),
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.CUT
]));
printer.close();
} catch (error) {
console.error('打印失败:', error);
printer.close();
}
}
printWithImage();
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
const printer = new ESCPOSPrinter('Your Printer Name');
// 初始化打印机
printer.print(ESCPOSPrinter.commands.INIT);
printer.print(ESCPOSPrinter.commands.CHINESE_MODE);
// 标准字体A
printer.setFontA();
printer.print(printer.textToBuffer('这是标准字体A\n', 'GBK'));
// 压缩字体B
printer.setFontB();
printer.print(printer.textToBuffer('这是压缩字体B\n', 'GBK'));
// 恢复标准字体A
printer.setFontA();
// 使用不同的字体大小
printer.print(printer.textToBuffer('以下是不同的字体大小示例:\n', 'GBK'));
// 正常大小
printer.setTextNormal();
printer.print(printer.textToBuffer('1. 正常大小文本\n', 'GBK'));
// 双倍高度
printer.setTextDoubleHeight();
printer.print(printer.textToBuffer('2. 双倍高度文本\n', 'GBK'));
// 双倍宽度
printer.setTextDoubleWidth();
printer.print(printer.textToBuffer('3. 双倍宽度文本\n', 'GBK'));
// 双倍大小(宽度和高度都是2倍)
printer.setTextDoubleSize();
printer.print(printer.textToBuffer('4. 双倍大小文本\n', 'GBK'));
// 自定义大小(3倍宽度,2倍高度)
printer.setTextSize(2, 1);
printer.print(printer.textToBuffer('5. 自定义大小文本\n', 'GBK'));
// 重置为正常大小
printer.setTextNormal();
printer.print(ESCPOSPrinter.commands.LF);
// 切纸并关闭
printer.print(ESCPOSPrinter.commands.CUT);
printer.close();
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
const printer = new ESCPOSPrinter('Your Printer Name');
async function printMixed() {
try {
// 1. 打印标题
printer.print(Buffer.concat([
ESCPOSPrinter.commands.INIT,
ESCPOSPrinter.commands.ALIGN_CENTER,
ESCPOSPrinter.commands.CHINESE_MODE,
ESCPOSPrinter.commands.BOLD_ON,
ESCPOSPrinter.commands.TEXT_DOUBLE_SIZE,
printer.textToBuffer('商店名称\n', 'GBK'),
ESCPOSPrinter.commands.TEXT_NORMAL,
ESCPOSPrinter.commands.BOLD_OFF
]));
// 2. 打印 LOGO
await printer.printImage('./logo.png', {
width: 300, // 稍小的宽度使 LOGO 更美观
dither: true
});
// 3. 打印商品信息
printer.print(Buffer.concat([
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.ALIGN_LEFT,
printer.textToBuffer('订单号:123456789\n', 'GBK'),
printer.textToBuffer('日期:' + new Date().toLocaleString() + '\n', 'GBK'),
printer.textToBuffer('------------------------\n', 'GBK'),
printer.textToBuffer('商品信息:\n', 'GBK'),
printer.textToBuffer('测试商品 1 x2 ¥18.00\n', 'GBK'),
printer.textToBuffer('测试商品 2 x1 ¥12.00\n', 'GBK'),
printer.textToBuffer('------------------------\n', 'GBK'),
ESCPOSPrinter.commands.ALIGN_RIGHT,
printer.textToBuffer('总计:¥30.00\n', 'GBK')
]));
// 4. 打印二维码
printer.print(Buffer.concat([
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.ALIGN_CENTER,
printer.textToBuffer('扫码关注我们\n', 'GBK')
]));
printer.printQRCode('https://github.com/MixGeeker/ESCPOS-for-Windows', {
size: 8,
errorLevel: 49
});
// 5. 打印页尾和切纸
printer.print(Buffer.concat([
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.LF,
printer.textToBuffer('谢谢惠顾\n', 'GBK'),
ESCPOSPrinter.commands.LF,
ESCPOSPrinter.commands.CUT
]));
printer.close();
} catch (error) {
console.error('打印失败:', error);
printer.close();
}
}
printMixed();
const ESCPOSPrinter = require('@mixgeeker/node-escpos-win');
// 获取所有打印机列表
const printers = ESCPOSPrinter.getPrinterList();
// 打印所有打印机信息
printers.forEach(printer => {
console.log(`打印机名称: ${printer.name}`);
console.log(`描述: ${printer.description}`);
console.log(`是否默认: ${printer.isDefault}`);
console.log('------------------------');
});
// 使用第一个打印机
if (printers.length > 0) {
const printer = new ESCPOSPrinter(printers[0].name);
// ... 使用打印机进行打印
printer.close();
}
在 Windows PowerShell 中运行以下命令可以获取系统中已安装的打印机名称:
Get-Printer | Select-Object Name
- 确保打印机已正确安装并在 Windows 系统中可见
- 使用管理员权限运行 Node.js 应用程序可能会获得更好的打印机访问权限
- 某些 ESC/POS 命令可能需要根据具体打印机型号进行调整
- 中文打印使用 GBK 编码,确保文本内容为正确的中文字符
- 二维码打印时,如果内容包含中文,需要使用
textToBuffer
方法进行 GBK 编码转换 - 条形码数据必须符合对应条形码类型的规范
- 图片打印建议:
- 使用黑白或灰度图片以获得最佳效果
- 图片宽度建议不超过打印纸宽度(58mm 打印纸最大 384 点)
- 对于照片类图片,建议启用抖动算法以获得更好的灰度效果
- LOGO 类图片建议使用较小的 threshold 值以保持图片清晰度
- 添加字体类型设置功能(FONT_A和FONT_B)
- 优化文本大小设置功能,支持自定义大小
- 添加便捷方法设置字体类型和大小
- 优化测试文件,展示更多打印功能
- 完善图片打印功能文档
- 添加详细的图片打印使用指南
- 我忘记编译了,编译重新上传
- 添加获取打印机列表功能
- 支持查看打印机详细信息
- 支持识别默认打印机
- 完善图片打印功能文档
- 添加详细的图片打印使用指南
- 优化图片打印测试工具
- 添加更多图片打印建议和最佳实践
- 完善图片打印功能
- 添加图片打印测试工具
- 优化图片处理算法
- 改进文档说明
- 修复中文字符编码问题
- 改进 Windows API 的调用方式
- 优化内存管理
- 增强字符串处理的稳定性
- 添加二维码打印功能
- 完善文档说明
- 我忘记改引用名了,改了重新上传
- 基础打印功能
- 条形码支持
- 中文支持
MIT
如果你在使用过程中遇到任何问题,请在 GitHub Issues 中提出。