Printing 如何在物理页面/作业完成时从打印机获取通知
我希望能够在网络打印机实际完成打印页面(和/或整个作业)时收到来自该打印机的通知。这将用于我正在编写的一个应用程序,用于通过web进行打印管理,因为用户每页收取费用,而且在页面实际完成之前,费用不应该下降 我不确定这是否需要编写驱动程序、某种插件或客户端应用程序。我对我的平台很灵活,因为我的客户机还没有编写,所以我想听听Windows或Linux中任何编程语言/级别的合适解决方案 我知道后台打印程序和打印机之间有区别。我试图检查当页面或作业实际完成时,打印机可能通过IPP通知机器的级别 我目前正在研究Java,在IPP属性更改时使用或包获取通知,或者轮询它。我正在使用CUPS IPP接口连接到本地打印机。运行一个简单的测试仪(Printing 如何在物理页面/作业完成时从打印机获取通知,printing,driver,monitoring,Printing,Driver,Monitoring,我希望能够在网络打印机实际完成打印页面(和/或整个作业)时收到来自该打印机的通知。这将用于我正在编写的一个应用程序,用于通过web进行打印管理,因为用户每页收取费用,而且在页面实际完成之前,费用不应该下降 我不确定这是否需要编写驱动程序、某种插件或客户端应用程序。我对我的平台很灵活,因为我的客户机还没有编写,所以我想听听Windows或Linux中任何编程语言/级别的合适解决方案 我知道后台打印程序和打印机之间有区别。我试图检查当页面或作业实际完成时,打印机可能通过IPP通知机器的级别 我目前正
HelloPrint.java
附在下面;或者cups4j中包含的CupsTest.java
),我没有收到任何作业印象完成
属性更改,也没有在轮询时列出作业的属性
以下是问题:
- 我做得对吗?如果没有,我应该怎么做
- 由于这是本地打印机的CUPS接口,可能是因为
属性没有更新,特别是因为它充当真实打印机的后台处理程序。假设真正的打印机将通知或列出此属性,这是特定于打印机的,还是任何支持IPP的打印机都必须提供并更新此属性job impressions completed
javax.print
包和jspi的示例应用程序:
HelloPrint.java
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import javax.print.*;
import javax.print.attribute.*;
import javax.print.attribute.standard.*;
import javax.print.event.*;
import de.lohndirekt.print.IppPrintService;
public class HelloPrint {
/**
* @param args
*/
public static void main(String[] args) {
// create request attributes
PrintRequestAttributeSet requestAttributeSet = new HashPrintRequestAttributeSet();
requestAttributeSet.add(MediaSizeName.ISO_A4);
requestAttributeSet.add(new Copies(1));
requestAttributeSet.add(Sides.DUPLEX);
// find an appropriate service
// using jspi (http://code.google.com/p/jspi/)
URI printerURI;
try {
printerURI = new URI("ipp://localhost:631/printers/HL2240D-local");
} catch (URISyntaxException e2) {
e2.printStackTrace();
return;
}
IppPrintService service = new IppPrintService(printerURI);
// by enumerating
// PrintService[] services = PrintServiceLookup.lookupPrintServices(
// DocFlavor.INPUT_STREAM.PDF, requestAttributeSet);
// for (PrintService service1 : services) {
// System.out.println(service1);
// }
// PrintService service = services[0];
// add listeners to service
service.addPrintServiceAttributeListener(new PrintServiceAttributeListener() {
@Override
public void attributeUpdate(PrintServiceAttributeEvent event) {
PrintServiceAttributeSet serviceAttributeSet = event
.getAttributes();
StringBuilder s = new StringBuilder();
s.append("=== PrintServiceAttributeEvent: (" + serviceAttributeSet.size() + " attributes)\n");
for (Attribute attribute : serviceAttributeSet.toArray()) {
PrintServiceAttribute printServiceAttribute = (PrintServiceAttribute) attribute;
s.append(printServiceAttribute.getCategory().getName()
+ "/" + printServiceAttribute.getName() + " = "
+ printServiceAttribute.toString() + "\n");
}
System.out.println(s.toString());
}
});
// add file (blank.pdf is a blank page exported as PDF from LibreOffice
// Writer)
FileInputStream inputStream;
try {
inputStream = new FileInputStream("blank.pdf");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
// create a new doc and job
DocAttributeSet docAttributeSet = new HashDocAttributeSet();
docAttributeSet.add(MediaSizeName.ISO_A4);
docAttributeSet.add(Sides.DUPLEX);
Doc doc = new SimpleDoc(inputStream, DocFlavor.INPUT_STREAM.PDF,
docAttributeSet);
DocPrintJob job = service.createPrintJob();
// listen to print job attribute change events
// attribute set is null, means this means to listen on all dynamic
// attributes that the job supports.
job.addPrintJobAttributeListener(new PrintJobAttributeListener() {
@Override
public void attributeUpdate(PrintJobAttributeEvent event) {
PrintJobAttributeSet jobAttributeSet = event.getAttributes();
StringBuilder s = new StringBuilder();
s.append("=== PrintJobAttributeEvent: (" + jobAttributeSet.size() + " attributes)\n");
for (Attribute attribute : jobAttributeSet.toArray()) {
PrintJobAttribute jobAttribute = (PrintJobAttribute) attribute;
s.append(jobAttribute.getCategory().getName() + "/"
+ jobAttribute.getName() + " = "
+ jobAttribute.toString() + "\n");
}
System.out.println(s.toString());
}
}, null);
// listen to print job events
job.addPrintJobListener(new PrintJobListener() {
@Override
public void printJobRequiresAttention(PrintJobEvent pje) {
System.out.println("=== PrintJobEvent: printJobRequiresAttention");
}
@Override
public void printJobNoMoreEvents(PrintJobEvent pje) {
// TODO Auto-generated method stub
System.out.println("=== PrintJobEvent: printJobNoMoreEvents");
System.out.println(pje.getPrintEventType());
System.out.println(pje.toString());
}
@Override
public void printJobFailed(PrintJobEvent pje) {
// TODO Auto-generated method stub
System.out.println("=== PrintJobEvent: printJobFailed");
System.out.println(pje.getPrintEventType());
System.out.println(pje.toString());
}
@Override
public void printJobCompleted(PrintJobEvent pje) {
// TODO Auto-generated method stub
System.out.println("=== PrintJobEvent: printJobCompleted");
System.out.println(pje.getPrintEventType());
System.out.println(pje.toString());
}
@Override
public void printJobCanceled(PrintJobEvent pje) {
// TODO Auto-generated method stub
System.out.println("=== PrintJobEvent: printJobCanceled");
System.out.println(pje.getPrintEventType());
System.out.println(pje.toString());
}
@Override
public void printDataTransferCompleted(PrintJobEvent pje) {
System.out.println("=== PrintJobEvent: printDataTransferCompleted");
System.out.println(pje.getPrintEventType());
System.out.println(pje.toString());
}
});
// print
try {
job.print(doc, requestAttributeSet);
} catch (PrintException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return;
}
// try polling
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
System.out.println("=== Polling: I'm alive and it's " + new Date());
System.out.println("Job attributes");
for (Attribute attribute : job.getAttributes().toArray()) {
System.out.println((attribute.getCategory().getName() + "/"
+ attribute.getName() + " = " + attribute.toString()));
}
System.out.println("Service attributes");
for (Attribute attribute : service.getAttributes().toArray()) {
System.out.println((attribute.getCategory().getName() + "/"
+ attribute.getName() + " = " + attribute.toString()));
}
}
}
}
最后,这一切都取决于打印机固件IPP将属性job impressions completed指定为可选属性。这意味着,如果打印机无法分辨打印的是哪一页,则无论您的编程是否正确,您都将无法读取该页 制造商通常声称支持IPP,但没有很好地记录他们可能实施(或未实施)的可选部件 在进行任何编程之前,我建议使用CUPS提供的
ipptool
读取所有可用的作业属性:
#!/usr/bin/env ipptool -tv -d job=482 ipp://192.168.2.113/ipp
{
OPERATION Get-Job-Attributes
GROUP operation-attributes-tag
ATTR charset attributes-charset utf-8
ATTR language attributes-natural-language en
ATTR uri printer-uri $uri
ATTR integer job-id $job
}
作业状态
是一个强制属性,应在一段时间后达到最终状态:完成
、中止
或取消
。如果你能在其他地方得到工作页面的数量,这可能就足够了
实现提示:提供方法
waitForTermination()
我认为“如何监视物理打印作业进度”是一个合适的问题。我考虑了你的意见,希望这个问题的版本更清晰(甚至可能得到回答!)你修改后的问题非常合适。感谢(大量)编辑;现在好多了嗨,尤瓦尔,你能找到你问题的答案吗?我当然有同样的要求,但还没有找到解决方案。实际上,我现在又回到这个项目上了。我刚刚得到一张京瓷KM-3530 w/打印机卡(我希望我的型号正确),我将检查如何使用它。这是一个志愿者项目,需要一个月左右我才能有时间去做,但我会保持联系并更新这个问题。谢谢你。您是否有参考资料表明,完成的工作印象
是可选的?职务描述属性:“如果未按要求指示[属性],则为可选”