完成物理页面/作业后如何从打印机获取通知 [英] How to get notification from printer when physical page/job is complete

查看:119
本文介绍了完成物理页面/作业后如何从打印机获取通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够在网络打印机实际完成页面(和/或整个作业)的打印时从网络打印机获得通知.这将在我正在编写的用于通过网络进行打印管理的应用程序中使用,并且由于用户按页面收费,因此在页面实际完成之前不应减少收费.

I'd like to be able to get a notification from a network printer when it physically finishes printing a page (and/or the entire job). This is going to be used in an app I'm writing for print management via web, and since users get charged per-page, and the charge shouldn't go down before the page actually completes.

我不确定这是否需要编写驱动程序,某种插件或客户端应用程序是否需要.由于我的客户端尚未编写,因此我对自己的平台很灵活,所以我想听听有关Windows或Linux上任何编程语言/级别的任何合适解决方案的信息.

I'm not sure whether this requires writing a driver, some kind of plug-in or whether a client app will do. I am flexible with my platform, since my client isn't written yet, so I'd like to hear about any suitable solution in either Windows or Linux, in any programming language/level.

我知道后台打印程序和打印机之间是有区别的.我正在尝试检查打印机或页面在物理上完成时可以通过IPP通知机器的级别.

I'm aware that there is a difference between the spooler and the printer. I'm trying to examine at which level the printer might notify the machine, via IPP, when the page or job physically complete.

我目前正在使用 jspi job-impressions-completed 进行更改,或者进行轮询.我正在使用CUPS IPP接口连接到本地打印机.运行一个简单的测试器(下面附有HelloPrint.java;或cups4j中包含的CupsTest.java),我没有收到任何job-impressions-completed属性更改,也没有在轮询时列出该作业的属性.

I'm currently looking into Java, using either jspi or cups4j package to obtain a notification when the IPP property job-impressions-completed changes, or alternatively, poll for it. I'm using a CUPS IPP interface to a local printer. Running a simple tester (HelloPrint.java attached below; or the CupsTest.java included in cups4j), I did not receive any job-impressions-completed attribute changes nor did it list the attribute for the job when I was polling.

所以这是问题:

  • 这样做正确吗?如果没有,那我该怎么办?
  • 由于这是本地打印机的CUPS接口,因此job-impressions-completed属性可能没有被更新,特别是因为它充当实际打印机的假脱机程序.假设真正的打印机 会通知或列出此属性,这是特定于打印机的还是必须任何支持IPP的打印机都具有该属性并已更新?
  • Am doing this right? If not, then how should I do it?
  • Since this is a CUPS interface to a local printer, it might be that the job-impressions-completed attribute isn't being updated, specifically since it acts as a spooler for the real printer. Assuming that the real printer will notify about or list this attribute, Would this be printer-specific or must any IPP-supporting printer have this attribute available and updated?

系统信息:Ubuntu 11.10,CUPS 1.5.0,打印机为Brother HL-2240D(

System info: Ubuntu 11.10, CUPS 1.5.0, printer is Brother HL-2240D (PPD available here)

注意:HL-2240D不是我将用于最终项目的打印机(具体来说,它不支持IPP);我打算使用HP HL4250DN或Samsung 3741ND或类似产品.

Note: HL-2240D is not the printer I will be using for the eventual project (specifically, it doesn't support IPP); I'm intending to use either an HP HL4250DN or Samsung 3741ND or similar.

这是一个使用javax.print软件包和jspi的示例应用程序:

Here's a sample app using the javax.print packages and 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将作业印象完成属性指定为可选.这意味着,如果打印机不知道已打印了哪一页,则无论您的编程是否正确,都将无法阅读.

In the end it all depends on the printers firmware. IPP specifies the attribute job-impressions-completed as optional. That means if the printer can't tell which page has been printed, you won't be able to read it - no matter whether your programming is correct or not.

制造商通常声称支持IPP,但是没有很好地记录他们可能已经实现(或不实现)的可选部件.

Manufacturers usually claim to support IPP but don't document very well the optional parts they might have implemented (or not).

在进行任何编程之前,我建议使用CUPS的ipptool读取所有可用的作业属性:

Before doing any programming I suggest to read all available job-attrbutes using the ipptool available from CUPS:

#!/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
}

job-state是必填属性,应在一段时间后达到最终状态:completedabortedcanceled.如果您可以获得其他地方的工作页数,这可能就足够了:-)

job-state is a mandatory attribute and should reach a final state after some time: completed, aborted or canceled. This might be good enough, if you can get the number of job-pages somewhere else :-)

这篇关于完成物理页面/作业后如何从打印机获取通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆