使用javax.print库以属性(纸盘控制,双面打印等)进行打印 [英] Printing with Attributes(Tray Control, Duplex, etc...) using javax.print library

查看:141
本文介绍了使用javax.print库以属性(纸盘控制,双面打印等)进行打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试了一段时间,以确定一种使用标准Java打印库来打印具有某些属性的文件-特别是PDF文档的方法. ,某些纸盘或双面打印.

I've been trying for some time to determine a way to use the standard Java Print library to print files - specifically, PDF documents - with certain attributes - specifically, to certain trays or using duplex.

关于如何执行此操作,有很多文档,实际上,我已经研究并尝试了这些方法.典型的方法是这样的:

There exists plenty of documentation on how this should be done, and indeed, I've researched and tried these methods. The typical way is something like this:

public static void main (String [] args) {
    try {

        PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null);

        //Acquire Printer
        PrintService printer = null;
        for (PrintService serv: pservices) {
            System.out.println(serv.toString());
            if (serv.getName().equals("PRINTER_NAME_BLAH")) {
                printer = serv;
            }
        }

        if (printer != null) {
            System.out.println("Found!");


            //Open File
            FileInputStream fis = new FileInputStream("FILENAME_BLAH_BLAH.pdf");

            //Create Doc out of file, autosense filetype
            Doc pdfDoc = new SimpleDoc(fis, DocFlavor.INPUT_STREAM.AUTOSENSE, null);

            //Create job for printer
            DocPrintJob printJob = printer.createPrintJob();

            //Create AttributeSet
            PrintRequestAttributeSet pset = new HashPrintRequestAttributeSet();

            //Add MediaTray to AttributeSet
            pset.add(MediaTray.TOP);

            //Add Duplex Option to AttributeSet
            pset.add(Sides.DUPLEX);

            //Print using Doc and Attributes
            printJob.print(pdfDoc, pset);

            //Close File
            fis.close();

        }

    }
    catch (Throwable t) {
        t.printStackTrace();
    }
}

简而言之,请执行以下操作

In short, you do the following

  1. 找到打印机
  2. 创建PrinterJob
  3. 创建AttributeSet
  4. 向AttributeSet中添加属性,例如Tray和Duplex
  5. 使用AttributeSet在打印机作业上调用打印

这里的问题是,尽管已记录了这样做的方法,以及我在多个教程中发现的方法,但此方法... 不起作用.现在,请记住,我知道这听起来并不十分描述,但是请听我说. 我不会轻易地说 ...

The problem here is that, despite being the documented way of doing this, as well as what I've found from several tutorials, this method... doesn't work. Now keep in mind, I know that doesn't sound very descript, but hear me out. I don't say that lightly...

PrinterJob的官方文档实际上提到在默认实现中忽略了AttributeSet. 在此处看到的源代码证明这是正确的-属性被传入并被完全忽略.

The official documentation for PrinterJob actually mentions that the AttributeSet is ignored in the default implementation. Source code seen here shows this to be true - the attributes are passed in and ignored entirely.

因此,显然,您需要类的某种扩展版本,该扩展版本可能基于特定的打印机及其功能?我试图编写一些测试代码来告诉我这样的功能-我们在办公室安装了各种各样的打印机,大小不一,简单或充满风吹草动-更不用说我计算机上的几个用于伪装的驱动程序了-printer驱动程序,该驱动程序仅创建文档并模拟打印机,而无需使用任何类型的硬件.测试代码如下:

So apparently, you need some sort of extended version of the class, which is possibly based on the specific printers and their capabilities? I attempted to write some test code that would tell me such capabilities - we have a large variety of printers set up at the office, large or small, simple or full of bells and whistles - not to mention several drivers on my computer just for pseudo-printer drivers that just create documents and simulate printers without going to any sort of hardware. The test code is as follows:

public static void main (String [] args) {

    PrintService[] pservices = PrintServiceLookup.lookupPrintServices(null, null);

    for (PrintService serv: pservices) {
        System.out.println(serv.toString());

        printFunctionality(serv, "Trays", MediaTray.class);
        printFunctionality(serv, "Copies", Copies.class);
        printFunctionality(serv, "Print Quality", PrintQuality.class);
        printFunctionality(serv, "Color", ColorSupported.class);
        printFunctionality(serv, "Media Size", MediaSize.class);
        printFunctionality(serv, "Accepting Jobs", PrinterIsAcceptingJobs.class);
    }
}

private static void printFunctionality(PrintService serv, String attrName, Class<? extends Attribute> attr) {
    boolean isSupported = serv.isAttributeCategorySupported(attr);
    System.out.println("    " + attrName + ": " + (isSupported ? "Y" : "N"));
}

我发现的结果是,每台打印机都无一例外地返回支持份数"的信息,而所有其他属性均不受支持.此外,每台打印机的功能都是相同的,无论看上去多么令人难以置信.

The results I found were that every printer, without exception, returned that "copies" were supported, and all other attributes were not. Furthermore, every printer's capabilities were identical, regardless of how implausible that would seem.

不可避免的问题是多层的:一个如何以注册属性的方式发送属性?此外,如何正确检测打印机的功能?确实,PrinterJob类实际上是以一种可用的方式进行扩展的,还是始终忽略该属性?

The inevitable question is multi-layered: How does one send in attributes in a way that they are registered? Additionally, how does one properly detect the capabilities of a printer? Indeed, is the PrinterJob class actually extended in a usable way at all, or are the Attributes always ignored?

我在整个Internet上发现的示例似乎向我表明,后一个问题的答案是不,它们总是被忽略",这对我来说似乎很荒谬(但是当我浏览数百页时,它变得越来越可信) ). 这是Sun设置的代码,但从未生效吗?如果是这样,有其他选择吗?

Examples I've found throughout The Internet seem to suggest to me that the answer to the latter question is "No, they are always ignored", which seems ridiculous to me (but increasingly more believable as I sift through hundreds of pages). Is this code that Sun simply set up but never got working to a completed state? If so, are there any alternatives?

推荐答案

因此,我们不可避免地找到了一种方法来打印到不同的纸盘和不同的设置,但不能直接打印.我们发现不可能通过printJob.print方法发送属性,并且大部分都没有改变.但是,我们能够设置打印作业的名称,然后使用低级的Perl脚本拦截打印作业,解析名称,然后在其中设置纸盘和双面打印设置.这是一个极端的技巧,但确实有效. Java打印机属性不起作用仍然是事实,如果要设置它们,您将需要另一种方式.

So, we inevitably found a way to print to different trays and with different settings, but not directly. We found it impossible to send attributes via the printJob.print method, and that much hasn't changed. However, we were able to set the name of the print job, then intercept the print job with a low-level Perl script, parse the name, and set the tray and duplex settings there. It's an extreme hack, but it works. It still remains true that Java Printer Attributes do not work, and you will need to find another way if you want to set them.

这篇关于使用javax.print库以属性(纸盘控制,双面打印等)进行打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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