我希望能夠在物理完成打印頁面(和/或整個作業)時從網絡打印機獲得通知。這將用於我正在通過網絡進行打印管理的應用程序,並且由於用戶每頁都收取費用,並且在頁面實際完成之前不應停止收費。如何在物理頁面/作業完成時從打印機獲取通知
我不確定這是否需要編寫驅動程序,某種插件或者客戶端應用程序能否完成。我對我的平臺很靈活,因爲我的客戶端還沒有寫入,所以我想在任何編程語言/級別的Windows或Linux中聽到任何合適的解決方案。
我知道假脫機程序和打印機之間是有區別的。我試圖檢查打印機在哪個級別通過IPP通知機器何時完成頁面或作業。
我正在調查Java,使用jspi或cups4j程序包獲取IPP屬性job-impressions-completed
更改時的通知,或者輪詢它。我正在使用本地打印機的CUPS IPP接口。運行一個簡單的測試程序(HelloPrint.java
附在下面;或包含在cups4j中),我沒有收到任何job-impressions-completed
屬性更改,也沒有列出我在投票時作業的屬性。
所以這裏的問題:
- 要這麼做嗎?如果不是,那我該怎麼做呢?
- 由於這是CUPS接口到本地打印機,它可能是
job-impressions-completed
屬性沒有被更新,特別是因爲它充當真正的打印機假脫機程序。假設真實打印機將通知或列出此屬性,這是打印機特定的還是必須任何支持IPP的打印機都可以使用此屬性並進行更新?
系統信息:Ubuntu的11.10,CUPS 1.5.0,打印機是兄弟HL-2240D(PPD available here)
注:HL-2240D是不我將使用爲最終項目打印機(具體而言,它不支持IPP);我打算使用HP HL4250DN或三星3741ND或類似產品。
下面是一個使用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()));
}
}
}
}
嗯,我認爲「我如何監控物理打印作業進度」是一個合適的問題。我考慮了你的意見,希望這個問題的版本更清晰(甚至可能會得到回答!) – Yuval 2012-04-12 15:01:13
您的修改後的問題非常適合。感謝(大量)編輯;它現在好多了。 :) – 2012-04-12 15:45:03
嗨Yuval,你能找到你的問題的答案? 我有同樣的要求,並且找不到解決方案。 – 2012-08-27 23:20:17