如何使用PJL与Java取消已通过网络发送的打印作业?
打印作业取消功能修正方案
现有取消代码的核心问题
你的取消代码没有生效反而新增作业,是因为存在以下语法和逻辑错误:
- 指令语法错误:
out.write("%-12345X@PJL\\rn".getBytes());中转义符写错,应该是\r\n而非\\rn,导致PJL指令无法被打印机正确解析 - 指令缺失前缀:
DEFAULT JOBID =ON\r\n前面漏了@PJL前缀,打印机不会识别该配置指令 - 指令逻辑错误:未使用作业取消专用指令
@PJL CANCEL JOB,反而使用了@PJL EOJ(作业结束指令),该指令会将你当前提交的内容识别为一个新作业并结束,自然会新增空白作业 - 匹配逻辑错误:
@PJL EOJ NAME是用于结束当前会话内的作业,无法匹配打印机队列中已存在的待处理作业
修正后的代码
public static void cancelPrintJob(String jobName, String printerIpAdd, Integer printerPort) { System.out.println("port " + printerPort); try (Socket socket = new Socket(printerIpAdd, printerPort)) { DataOutputStream out = new DataOutputStream(socket.getOutputStream()); // PJL通用头 out.write(27); //esc out.write("%-12345X@PJL\r\n".getBytes()); // 开启作业ID识别和作业状态通知 out.write("@PJL DEFAULT JOBID = ON\r\n".getBytes()); out.write("@PJL USTATUS JOB = ON\r\n".getBytes()); // 按作业名取消已提交的作业,作业名有特殊字符建议加双引号包裹 out.write(("@PJL CANCEL JOB NAME = \"" + jobName + "\"\r\n").getBytes()); // PJL通用结束符 out.write(27); //esc out.write("%-12345X\r\n".getBytes()); out.flush(); out.close(); } catch (IOException ex) { LOGGER.error(ex); } }
额外注意事项
- 你的原有打印代码存在笔误:
out.write(("@PJL SET COPIES=1"\n".getBytes());中引号错位,需要修正为out.write(("@PJL SET COPIES=1\n").getBytes());避免打印异常 - 如果可以获取到待取消作业的ID,使用
@PJL CANCEL JOB ID = 作业ID的方式取消,准确率远高于按作业名取消 - 部分厂商打印机需要提前在设置中开启「远程作业管理/取消」权限,否则取消指令会被拒绝
- 所有PJL指令的换行符统一使用
\r\n,避免不同品牌打印机的解析兼容问题
内容的提问来源于stack exchange,提问作者Wael M Elmahask
相关产品推荐
相关产品推荐

