9.5 KiB
9.5 KiB
XSL-PrintDot Client 使用指南与规范
1. 项目简介
XSL-PrintDot Client 是一个基于 Wails (Go + Vue 3) 开发的本地打印中间件。它充当浏览器(或其他客户端)与操作系统打印机之间的桥梁,通过 WebSocket 协议接收打印指令,并调用系统打印机进行打印。
主要功能:
- 自动获取操作系统已安装的打印机列表。
- 启动 WebSocket 服务监听打印请求(默认端口 1122)。
- 支持自定义服务端口和安全密钥(Secret Key)。
- 打印内容要求:接收 Base64 编码的 PDF 文件内容,并调用系统打印命令进行打印。
- 支持高级打印参数:打印份数、份数间隔,以及更多打印设置。
- 提供可视化的管理界面,实时查看日志和打印机状态。
- 日志实时监控:支持实时查看系统日志。
2. 启动与配置
2.1 启动应用
可以直接运行编译后的可执行文件(如 XSL-PrintDot.exe),或在开发环境中使用:
wails dev
注意: 程序启动时会自动开启 WebSocket 服务(默认端口 1122)。
Windows 打印说明:
- 请确保 Windows 打印后端可用且程序有权限访问。
2.2 界面配置
启动后,界面提供以下配置项:
- Port: WebSocket 服务监听端口(默认
1122)。 - Secret Key: 安全密钥(可选)。如果设置了密钥,客户端在连接或发送请求时必须通过鉴权。
- Start/Stop Server: 点击按钮即可启动或停止 WebSocket 服务。
- Connection URL: 服务启动后,界面会显示完整的连接地址(如
ws://localhost:1122/ws?key=...)。
操作说明:
- 退出程序: 使用菜单栏
Menu->Quit(Ctrl+Q),或使用托盘菜单的Quit可完全退出程序。 - 后台运行: 点击主窗口关闭按钮 (X) 不会退出程序,而是将程序最小化到系统托盘区。程序启动后会在系统托盘区显示图标,可用于快速唤起窗口或退出。
- 托盘菜单: 在系统托盘图标上右键单击,可选择
Show Main Window显示主窗口或Quit退出程序。 - 打开设置: 使用菜单栏
Menu->Settings(Ctrl+I) 可打开设置窗口。 - 查看日志: 使用菜单栏
Menu->System Logs(Ctrl+L) 可查看实时日志.
3. WebSocket 接口规范
3.1 连接信息
- 协议: WebSocket (
ws://) - 地址:
ws://localhost:<PORT>/ws - 鉴权:
- 如果设置了
Secret Key,建议在连接 URL 中携带:ws://localhost:1122/ws?key=YOUR_PASSWORD - 如果连接时未携带 key,也可以在发送的消息体中包含
key字段(但不推荐,连接可能被拒绝)。
- 如果设置了
3.2 消息类型
3.2.1 连接成功响应 (Server -> Client)
连接建立后,服务端会立即发送当前的打印机列表:
{
"type": "printer_list",
"data": [
{"name": "Microsoft Print to PDF", "isDefault": true},
{"name": "ZDesigner GK888t", "isDefault": false}
]
}
3.2.2 获取打印机列表 (Client -> Server)
客户端可以随时发送以下 JSON 消息主动获取最新的打印机列表:
{
"type": "get_printers"
}
服务端将回复与 3.2.1 相同格式的 printer_list 消息。
3.2.3 获取打印机能力 (Client -> Server)
客户端可以请求指定打印机的可用参数:
{
"type": "get_printer_caps",
"printer": "Microsoft Print to PDF"
}
服务端响应示例:
{
"type": "printer_caps",
"printer": "Microsoft Print to PDF",
"data": {
"paperSizes": ["A4", "Letter"],
"printerPaperNames": ["A4", "Letter"],
"duplexSupported": false,
"colorSupported": true
}
}
说明:不同系统返回字段会有差异,Windows 返回 Win32_Printer/Win32_PrinterConfiguration 信息;Linux/macOS 返回 lpoptions 解析结果。
3.2.4 发送打印任务 (Client -> Server)
客户端发送的 JSON 数据包结构如下(按功能分类):
{
"printer": "Microsoft Print to PDF", // [必填] 目标打印机名称
"content": "data:application/pdf;base64,JVBERi...", // [必填] Base64 编码的 PDF 内容 (支持带前缀或纯 Base64)
"key": "123456", // [选填] 鉴权密钥 (若连接时已验证可省略)
"job": {
"name": "My Print Job 001", // [选填] 任务名称 (仅用于日志记录)
"copies": 2, // [选填] 打印份数,默认 1
"intervalMs": 1000 // [选填] 份数间延迟(毫秒),用于手动隔张打印
},
"pages": {
"range": "1-3,5", // [选填] 页码范围 (支持 N / N-M / N,M / 反向区间)
"set": "odd" // [选填] odd | even
},
"layout": {
"scale": "fit", // [选填] noscale | shrink | fit
"orientation": "portrait" // [选填] portrait | landscape
},
"color": {
"mode": "color" // [选填] color | monochrome
},
"sides": {
"mode": "duplex" // [选填] simplex | duplex | duplexshort | duplexlong
},
"paper": {
"size": "A4" // [选填] A4 | letter | legal | tabloid | statement | A2 | A3 | A5 | A6
},
"tray": {
"bin": "2" // [选填] 纸盒编号或名称,例如 2 / Manual
}
}
注意:
content字段必须是 PDF 文件的 Base64 编码字符串。
- 支持标准 Data URI 格式:
data:application/pdf;base64,JVBERi...- 也支持纯 Base64 字符串:
JVBERi...- 服务端会自动去除
data:前缀(如果有)并校验解码后的内容是否以
| 字段 | 类型 | 说明 |
|---|---|---|
printer |
String | 目标打印机名称。 |
content |
String | Base64 编码的 PDF 内容。 |
job.name |
String | 打印任务名称。 |
job.copies |
Integer | 打印份数。intervalMs 为 0 时由系统命令一次性处理。 |
job.intervalMs |
Integer | 隔张间隔 (ms)。大于 0 时服务端逐份打印。 |
pages.range |
String | 页码范围:N / N-M / N,M / 反向区间。 |
pages.set |
String | 奇偶页:odd / even。 |
layout.scale |
String | 缩放:noscale / shrink / fit。 |
layout.orientation |
String | 方向:portrait / landscape。 |
color.mode |
String | 颜色模式:color / monochrome。 |
sides.mode |
String | 单双面:simplex / duplex / duplexshort / duplexlong。 |
paper.size |
String | 纸张:如 A4、letter、legal。未提供时会尝试从 PDF 的 MediaBox 自动识别常见尺寸。 |
tray.bin |
String | 纸盒:编号或名称。 |
3.2.3.1 平台支持说明
Windows
pages.range/pages.set/layout.scale/layout.orientation/color.mode/sides.mode/paper.size/tray.bin/job.copies会被转换为 Windows 打印选项。
Linux/macOS (lp/CUPS)
pages.range->-P。pages.set->-o page-set=odd|even。layout.scale->fit-to-page/scaling=100(shrink使用默认行为)。layout.orientation->-o orientation-requested=3|4(驱动可能忽略)。color.mode->-o ColorModel=Gray/-o ColorModel=RGB(部分驱动可能忽略)。sides.mode->-o sides=...。paper.size->-o media=...。tray.bin->-o InputSlot=...(依赖驱动支持)。
3.2.4 服务端响应 (Server -> Client)
服务端会返回每次打印的结果:
成功响应:
{
"status": "success",
"message": "Printed successfully"
}
失败响应:
{
"status": "error",
"message": "Content must be a PDF file"
}
Windows 队列跟踪说明:
Windows 下服务端会等待打印任务进入打印队列并完成后才返回 success。
若 120 秒内未入队或 5 分钟内未完成,将返回 error 并给出超时提示。
4. 调用示例 (JavaScript)
const socket = new WebSocket('ws://localhost:1122/ws?key=123456');
socket.onopen = () => {
console.log('已连接');
};
socket.onmessage = (event) => {
const msg = JSON.parse(event.data);
if (msg.type === 'printer_list') {
console.log('可用打印机:', msg.data);
const targetPrinter = msg.data.find(p => p.isDefault) || msg.data[0];
// 示例:主动刷新打印机列表
// socket.send(JSON.stringify({ type: 'get_printers' }));
// 获取打印机能力(纸张/单双面/彩色等)
socket.send(JSON.stringify({
type: 'get_printer_caps',
printer: targetPrinter?.name
}));
} else if (msg.type === 'printer_caps') {
const caps = msg.data || {};
const sizes = caps.printerPaperNames || caps.paperSizes || [];
const paperSize = sizes[0] || 'A4';
// 发送打印任务(按功能分组)
socket.send(JSON.stringify({
printer: msg.printer,
content: "JVBERi0xLjQKJ...", // Base64 PDF Data
job: {
name: "Test Job",
copies: 2,
intervalMs: 0
},
pages: {
range: "1-3,5",
set: "odd"
},
layout: {
scale: "fit",
orientation: "portrait"
},
color: {
mode: "color"
},
sides: {
mode: "duplex"
},
paper: {
size: paperSize
},
tray: {
bin: "2"
}
}));
} else {
console.log('收到回复:', msg);
}
};