How to access the status of the printer?

前端 未结 4 1752
醉酒成梦
醉酒成梦 2020-12-03 20:03

I need to know the Printer Status. I need to control the Printer Status using Java Program. Example

  1. Check the Printer status, weather will it accept the Job
相关标签:
4条回答
  • 2020-12-03 20:26

    Getting the complete status of a printer is not possible. Printers have a native driver which is able to request services but because there are so many possible printer functionalities, Java only supports a subset of it.

    You can actually offer the user to modify the status by calling

    PrinterJob pj = PrinterJob.getPrinterJob();
    pj.printDialog()
    

    which shows the native printer dialog. Despite the information in the javax.print API that it is possible to check the printer state, I was not able to do so for my printer !. (Canon).

    Code to check:

    import javax.print.*;
    import javax.print.attribute.DocAttributeSet;
    import javax.print.attribute.PrintServiceAttributeSet;
    import javax.print.attribute.standard.PrinterStateReason;
    import javax.print.attribute.standard.PrinterStateReasons;
    import javax.print.attribute.standard.Severity;
    import javax.print.event.*;
    import java.awt.*;
    import java.awt.print.PageFormat;
    import java.awt.print.Printable;
    import java.awt.print.PrinterException;
    import java.awt.print.PrinterJob;
    import java.io.*;
    import java.util.Set;
    
    /**
     * PrintTest
     */
    public class PrintTest implements PrintServiceAttributeListener,PrintJobListener,Doc, Printable, PrintJobAttributeListener {
    
      private static final transient String TEXT = "12345";
    
      public static void main(String[] args) {
        PrintTest test = new PrintTest();
        test.checkPrinters();
      }
    
      public void checkPrinters() {
        Thread newThread = new Thread(new Runnable() {
          public void run() {
        PrintService ps = PrinterJob.getPrinterJob().getPrintService();
    
        DocFlavor[] myFlavors = ps.getSupportedDocFlavors();
        ps.addPrintServiceAttributeListener(PrintTest.this);
        DocPrintJob docJob = ps.createPrintJob();
          docJob.addPrintJobAttributeListener(PrintTest.this, null);
        docJob.addPrintJobListener(PrintTest.this);
        try {
          docJob.print(PrintTest.this,null);
        }
        catch (PrintException e) {
          e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        } });
    
        newThread.start();
        /**
        PrintServiceAttributeSet attSet = ps.getAttributes();
        PrinterStateReasons psr = ps.getAttribute(PrinterStateReasons.class);
    
        if (psr != null) {
          Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT);
          for (PrinterStateReason reason : errors)
            System.out.printf(" Reason : %s",reason.getName());
          System.out.println();
        }          */
      }
    
      public void attributeUpdate(PrintServiceAttributeEvent psae) {
        System.out.println(psae.getAttributes());
      }
    
      public void printDataTransferCompleted(PrintJobEvent pje) {
        System.out.println("Transfer completed");
      }
    
      public void printJobCompleted(PrintJobEvent pje) {
        System.out.println("Completed");
      }
    
      public void printJobFailed(PrintJobEvent pje) {
        System.out.println("Failed");
        PrinterStateReasons psr = pje.getPrintJob().getPrintService().getAttribute(PrinterStateReasons.class);
        if (psr != null) {
          Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT);
          for (PrinterStateReason reason : errors)
            System.out.printf(" Reason : %s",reason.getName());
          System.out.println();
        }
      }
    
      public void printJobCanceled(PrintJobEvent pje) {
        System.out.println("Canceled");
      }
    
      public void printJobNoMoreEvents(PrintJobEvent pje) {
        System.out.println("No more events");
      }
    
      public void printJobRequiresAttention(PrintJobEvent pje) {
        System.out.println("Job requires attention");
        PrinterStateReasons psr = pje.getPrintJob().getPrintService().getAttribute(PrinterStateReasons.class);
        if (psr != null) {
          Set<PrinterStateReason> errors = psr.printerStateReasonSet(Severity.REPORT);
          for (PrinterStateReason reason : errors)
            System.out.printf(" Reason : %s",reason.getName());
          System.out.println();
        }
      }
    
      public DocFlavor getDocFlavor() {
        return DocFlavor.SERVICE_FORMATTED.PRINTABLE;  //To change body of implemented methods use File | Settings | File Templates.
      }
    
      public Object getPrintData() throws IOException {
        return this;
      }
    
      public DocAttributeSet getAttributes() {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
      }
    
      public Reader getReaderForText() throws IOException {
        return null; //To change body of implemented methods use File | Settings | File Templates.
      }
    
      public InputStream getStreamForBytes() throws IOException {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
      }
    
      public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
        return pageIndex == 0 ? PAGE_EXISTS : NO_SUCH_PAGE;  //To change body of implemented methods use File | Settings | File Templates.
      }
    
      public void attributeUpdate(PrintJobAttributeEvent pjae) {
        System.out.println("Look out");
      }
    }
    

    I have tried to get a PrinterReasonsState by willfully opening the case or removing the paper, but I was unsuccessfull. Perhaps someone else can show how it is possible, but so far it seems that the API offers much more functionality which is in reality not available.

    Or in short: It does not work, at least not for my printer.

    0 讨论(0)
  • 2020-12-03 20:28

    UPDATE: Instead of querying WMI "win32_printer" object I would recommend using Powershell directly like this, its much cleaner API :

    Get-Printer | where PrinterStatus -like 'Normal' | fl
    

    To see all the printers and statuses:

    Get-Printer | fl Name, PrinterStatus
    

    To see all the attributes:

    Get-Printer | fl
    

    You can still use ProcessBuilder in Java as described below.

    Before update:

    Solution for Windows only. In Windows you can query WMI "win32_printer" class, so you check that the state on OS layer: Win32_Printer class

    In Java you can use ProcessBuilder like this to start PowerShell and execute the PS script like this:

    String printerName = "POS_PRINTER";
    ProcessBuilder builder = new ProcessBuilder("powershell.exe", "get-wmiobject -class win32_printer | Select-Object Name, PrinterState, PrinterStatus | where {$_.Name -eq '"+printerName+"'}");
    
    String fullStatus = null;
    Process reg;
    builder.redirectErrorStream(true);
    try {
        reg = builder.start();
        fullStatus = getStringFromInputStream(reg.getInputStream());
        reg.destroy();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    System.out.print(fullStatus);
    

    After converting the InputStream to String you should get something like that:

    Name        PrinterState PrinterStatus
    ----        ------------ -------------
    POS_PRINTER            0             3
    

    State and Status should change for various situations (printer turned off, out of paper, cover opened,...).

    This should work, but depends on the printer and drivers. I used this with EPSON TM printers with ESDPRT port and I could get information like: no paper, cover open, printer offline/turned off, printer paused.

    More comprehensive answer here: - my StackOverflow answer on a similar question.

    0 讨论(0)
  • 2020-12-03 20:35

    I was told one could check the printer status this way:

    PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
    AttributeSet attributes = printService.getAttributes();
    String printerState = attributes.get(PrinterState.class).toString();
    String printerStateReason = attributes.get(PrinterStateReason.class).toString();
    
    System.out.println("printerState = " + printerState); // May be IDLE, PROCESSING, STOPPED or UNKNOWN
    System.out.println("printerStateReason = " + printerStateReason); // If your printer state returns STOPPED, for example, you can identify the reason 
    
    if (printerState.equals(PrinterState.STOPPED.toString()) {
    
        if (printerStateReason.equals(PrinterStateReason.TONER_LOW.toString()) {
    
            System.out.println("Toner level is low.");
        }
    }
    

    Sadly it seems that my printer doesn't have support for printerState so I can't test it.

    0 讨论(0)
  • 2020-12-03 20:44

    Have a look at this PrinterStateReason. And also javax.print.

    0 讨论(0)
提交回复
热议问题