如何访问打印机的状态?

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

  1. 检查打印机状态,天气是否接受作业,
  2. 没有纸了
  3. 打印机队列
  4. 爽肤水
  5. 等等..

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

看看这个PrinterStateReason 。 还有javax.print 。

无法获得打印机的完整状态。 打印机具有能够请求服务的本机驱动程序,但由于存在许多可能的打印机function,因此Java仅支持其子集。

您实际上可以通过调用为用户提供修改状态

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

它显示本机打印机对话框。 尽管javax.print API中的信息可以检查打印机状态,但我无法为我的打印机执行此操作 ! (佳能)。

要检查的代码:

 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 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 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 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"); } } 

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

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

我被告知可以通过这种方式检查打印机状态:

 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."); } } 

可悲的是,似乎我的打印机不支持printerState,所以我无法测试它。

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

在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); 

将InputStream转换为String后,你应该得到类似的东西:

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

状态和状态应该在各种情况下发生变化(打印机关闭,缺纸,打开盖子……)。

这应该工作,但取决于打印机和驱动程序。 我使用带有ESDPRT端口的EPSON TM打印机,我可以得到以下信息:没有纸张,打开盖子,打印机脱机/关闭,打印机暂停。

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