Java 查找打印机是否联机并准备好打印

Java 查找打印机是否联机并准备好打印,java,printing,printers,Java,Printing,Printers,以下4个问题没有帮助,因此这不是重复问题: , 我需要找到一种方法来发现我的系统报告的打印机是否可以打印 打印机页面: 在图片中,打印机“THERMAL”可用于打印,但“HPRT PPTII-A(USB)”不可用于打印。系统显示,通过使不可用的打印机着色 使用以下代码,我能够找到系统中的所有打印机 public static List<String> getAvailablePrinters() { DocFlavor flavor = DocFlavor.SERVICE

以下4个问题没有帮助,因此这不是重复问题:

,


我需要找到一种方法来发现我的系统报告的打印机是否可以打印

打印机页面:

在图片中,打印机“THERMAL”可用于打印,但“HPRT PPTII-A(USB)”不可用于打印。系统显示,通过使不可用的打印机着色

使用以下代码,我能够找到系统中的所有打印机

public static List<String> getAvailablePrinters() {
    DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
    PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();

    PrintService[] services = PrintServiceLookup.lookupPrintServices(flavor, aset);
    ArrayList<String> names = new ArrayList<String>();
    for (PrintService p : services) {
        Attribute at = p.getAttribute(PrinterIsAcceptingJobs.class);
        if (at == PrinterIsAcceptingJobs.ACCEPTING_JOBS) {
            names.add(p.getName());
        }

    }
    return names;
}
问题是:此代码显示了系统曾经安装的所有打印机

我需要的:这个列表应该只包含真正可用的打印机来打印。在此示例中,它应仅显示“THERMAL”,而不显示“HPRT PPTII-A(USB)”


如何实现这一点?

如果解决方案是特定于Windows的,请尝试。以下是我的情况:

如您所见,我的默认打印机“Kyocera Mita FS-1010”处于非活动状态(灰显),因为我只是将其关闭

现在将此添加到Maven POM中:


索法肯教授
我刚刚提出了一个请求。它使我们解析和过滤原始WMI输出,但代码仍然非常简单:

package de.scrum\u master.app;
导入com.profesorfalken.wmi4java.wmi4java;
导入com.profesorfalken.wmi4java.WMIClass;
导入java.util.array;
导入java.util.List;
导入java.util.stream.collector;
公共类打印机{
公共静态void main(字符串[]args){
字符串rawOutput=WMI4Java
.get()
.properties(Arrays.asList(“Name”、“WorkOffline”))
.filters(Arrays.asList(“$\.workffline-eq 0”))
.getRawWMIObjectOutput(WMIClass.WIN32_打印机);
列表打印机=Arrays.stream(rawOutput.split(“(\r?\n)”))
.filter(line->line.startsWith(“Name”))
.map(行->行.replaceFirst(“*”,“))
.已排序()
.collect(Collectors.toList());
System.out.println(打印机);
}
}
控制台输出如下所示:

    ArrayList<String> workingPrinter = new ArrayList<String>();
    System.out.println("Working printers:");
    for(String printer : getAvailablePrinters()){
        if(fullStatus.contains("\n" + printer + " ")){  // add a newline character before the printer name and space after so that it catches exact name 
            workingPrinter.add(printer);
            System.out.println(printer);
        }
    }
[传真、FinePrint、FreePDF、Microsoft打印到PDF、Microsoft XPS文档编写器、发送到OneNote 2016、WEB.DE Club SmartFax]
更新: 与查询WMI“win32_printer”对象不同,我建议您直接像这样使用Powershell,它的API更干净:

Get-Printer | where PrinterStatus -like 'Normal' | fl
要查看所有打印机和状态,请执行以下操作:

Get-Printer | fl Name, PrinterStatus
要查看所有属性,请执行以下操作:

Get-Printer | fl
您仍然可以在Java中使用ProcessBuilder,如下所述

更新前:

Windows解决方案,查询WMI“win32_打印机”对象:

要将InputStream转换为字符串,请查看此处:,或者只需使用:

public static String getStringFromInputStream(InputStream is) {
    ByteArrayOutputStream result = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int length;
    try {
        while ((length = is.read(buffer)) != -1) {
            result.write(buffer, 0, length);
        }
    } catch (IOException e1) {
        e1.printStackTrace();
    }
    // StandardCharsets.UTF_8.name() > JDK 7
    String finalResult = "";
    try {
        finalResult = result.toString("UTF-8");
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }
    return finalResult;
}
输出:

Name PrinterState PrinterStatus
----                          ------------ -------------
Foxit Reader PDF打印机0 3
发送到OneNote 2010 0 3
Microsoft XPS文档编写器0 3
Microsoft打印到PDF 0 3
传真03
\\192.168.50.192\POS_打印机0 3
如您所见,现在字符串中有所有处于工作状态的打印机

您可以使用现有方法(GetAvailablePrints()),例如添加如下内容:

    ArrayList<String> workingPrinter = new ArrayList<String>();
    System.out.println("Working printers:");
    for(String printer : getAvailablePrinters()){
        if(fullStatus.contains("\n" + printer + " ")){  // add a newline character before the printer name and space after so that it catches exact name 
            workingPrinter.add(printer);
            System.out.println(printer);
        }
    }

当然,您必须小心使用这种方法的名称-例如,如果“POS_打印机”在所有打印机中,但不在“工作打印机”列表中,它仍然可以添加到“工作打印机”列表中,如果有一个名为“POS_打印机1”的工作打印机,因为该名称包含“\nPOS_打印机”字符串…

这有什么帮助吗,只需将我发送到一个文档页面,在其中我不知道该做什么。。。添加为选中问题以及如何获取活动打印机名称列表?完美。赏金是你的。不幸的是,这是一个仅限Windows的解决方案。解决了我的问题(可能是op的问题,因为他在windows中提出了这个问题),但对未来的用户来说可能还不够谢谢,这对我帮助很大。我在powershell脚本中添加了|格式列表,因为一些打印机名称被切断了。没问题,很高兴它对您有所帮助。我假设您使用了类似这样的东西:
get wmiobject-class win32|u printer |其中对象{$$\ PrinterState-eq 0-和$\ PrinterStatus-eq 3}|格式列表名
    ArrayList<String> workingPrinter = new ArrayList<String>();
    System.out.println("Working printers:");
    for(String printer : getAvailablePrinters()){
        if(fullStatus.contains("\n" + printer + " ")){  // add a newline character before the printer name and space after so that it catches exact name 
            workingPrinter.add(printer);
            System.out.println(printer);
        }
    }