java 如何访问打印机的状态?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16035739/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 21:42:25  来源:igfitidea点击:

How to access the status of the printer?

javaprinting

提问by user2255885

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

我需要知道打印机状态。我需要使用 Java 程序控制打印机状态。例子

  1. Check the Printer status, weather will it accept the Job or not,
  2. Out of Paper
  3. Printer queue
  4. Toner
  5. and etc..
  1. 检查打印机状态,天气是否接受作业,
  2. 没纸了
  3. 打印机队列
  4. 碳粉
  5. 等等..

I know there is a way to check the basic information, such as name, color supported or not. But I can't find any example to check paper, toner, job queue. I like to know if it is possible to using Java API. I found big API for printer function, but they didn't give a simple example how to use it.

我知道有一种方法可以检查基本信息,例如名称、颜色是否支持。但我找不到任何检查纸张、碳粉、作业队列的示例。我想知道是否可以使用 Java API。我找到了打印机功能的大 API,但他们没有给出如何使用它的简单示例。

回答by Maximin

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

看看这个PrinterStateReason。还有javax.print

回答by Thorsten S.

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.

不可能获得打印机的完整状态。打印机有一个能够请求服务的本机驱动程序,但是因为有很多可能的打印机功能,Java 只支持它的一个子集。

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).

它显示了本机打印机对话框。尽管 javax.print API 中的信息表明可以检查打印机状态,但我无法为我的打印机这样做!(佳能)。

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.

我试图通过故意打开箱子或取出纸张来获得 PrinterReasonsState,但我没有成功。也许其他人可以展示它是如何可能的,但到目前为止,API 似乎提供了更多实际上不可用的功能。

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

或者简而言之:它不起作用,至少不适用于我的打印机。

回答by Fernando Paz

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.

遗憾的是,我的打印机似乎不支持 printerState,因此我无法对其进行测试。

回答by Rok T.

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

仅适用于 Windows 的解决方案。在 Windows 中,您可以查询 WMI "win32_printer" 类,因此您可以检查 OS 层上的状态:Win32_Printer 类

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

在 Java 中,您可以像这样使用 ProcessBuilder 来启动 PowerShell 并像这样执行 PS 脚本:

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:

将 InputStream 转换为 String 后,您应该得到类似的结果:

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.

这应该可行,但取决于打印机和驱动程序。我将它与带有 ESDPRT 端口的 EPSON TM 打印机一起使用,我可以获得如下信息:无纸、盖子打开、打印机离线/关闭、打印机暂停。

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

更全面的答案在这里: -我在类似问题上的 StackOverflow 回答