当前位置: 首页 > 知识库问答 >
问题:

使用javax.print库打印属性(托盘控件、双工等)

梁丘高朗
2023-03-14

一段时间以来,我一直在尝试确定一种方法,使用标准的Java打印库来打印具有某些属性的文件——特别是PDF文档——特别是某些托盘或使用双面打印。

有很多关于如何做到这一点的文档,事实上,我已经研究并尝试了这些方法。典型的方式如下:

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

简而言之,您可以执行以下操作

  1. 查找打印机

这里的问题是,尽管有文件证明的方法,以及我从几个教程中发现的方法,这种方法......不起作用。现在记住,我知道这听起来不太描述,但是听我说完。我不会轻易这么说...

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

显然,您需要该类的某种扩展版本,它可能基于特定的打印机及其功能?我试图编写一些测试代码来告诉我这些功能——我们在办公室里设置了各种各样的打印机,大大小小,简单或充满了铃铛和哨子——更不用说我的计算机上有几个驱动程序,它们只是用于创建文档和模拟打印机的伪打印机驱动程序,而不需要任何硬件。测试代码如下:

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

我发现的结果是,每台打印机都毫无例外地返回“副本”受支持,而所有其他属性都不受支持。此外,每台打印机的功能都是相同的,不管这看起来有多么难以置信。

不可避免的问题是多层次的:如何以注册属性的方式发送属性?此外,如何正确检测打印机的功能?事实上,PrinterJob类实际上是以可用的方式扩展的,还是属性总是被忽略?

我在互联网上找到的例子似乎告诉我,后一个问题的答案是“不,他们总是被忽视”,这对我来说似乎很荒谬(但当我在数百页中筛选时,越来越可信)。这段代码是Sun简单设置的,但从未运行到完成状态吗?如果有,还有其他选择吗?

共有3个答案

端木志诚
2023-03-14

我们对打印PDF有类似的要求,希望将一些页面发送到特定的托盘,还希望将文档装订。我们使用Java代码ghost脚本组合,首先将PDF转换为ghost脚本,然后将PJL(打印作业语言)命令添加到ghost脚本文件中,以选择托盘并装订文档。然后将编辑后的重影脚本文件发送到打印机。

这里是完整的例子写在Java

http://reddymails.blogspot.com/2014/07/how-to-print-documents-using-java-how.html

-随机存取存储器

燕英奕
2023-03-14

因此,我们不可避免地找到了一种方法来打印到不同的托盘和不同的设置,但不是直接打印。我们发现不可能通过printJob.print方法发送属性,而且这一点没有改变。但是,我们能够设置打印作业的名称,然后用低级Perl脚本拦截打印作业,解析名称,并在那里设置托盘和双工设置。这是一个极端的黑客,但它是有效的。Java打印机属性仍然不起作用,如果你想设置它们,你需要找到另一种方法。

魏鹤轩
2023-03-14

问题是Java打印API是世界之间的桥梁。打印机制造商不发布JVM驱动程序。他们发布了Windows、Macintosh的驱动程序,也许有人有一个特定打印机的驱动程序,可以在一个或多个*nix平台上运行。

随附的还有一些Java代码,这些代码在某个主机系统上的JVM中运行。当您开始查询打印机html" target="_blank">功能时,您不是在与打印机对话,而是在与java中的桥类对话。awt。将该钩子打印到JVM,JVM钩子到主机操作系统,主机操作系统钩子到为给定打印机安装的任何特定驱动程序。因此,有几个地方,这可能会分崩离析。。。您所在的特定JVM可能完全实现或不完全实现查询打印机功能的API,更不用说为给定作业传递这些参数了。

一些建议:

  1. 查看javax.print类作为java.awt.print的替代方案--我在那里打印的运气更好。
  2. 尝试为您的打印机使用替代打印驱动程序——您可以为给定打印机定义多个命名连接,每个连接都有不同的驱动程序。如果您有制造商提供的驱动程序,请尝试更通用的驱动程序,如果您有通用驱动程序,请尝试安装更具体的驱动程序。
  3. 在您平台的备用JVM实现下运行您的代码
 类似资料:
  • 我有一个连接到CUPS的打印机,它支持双面打印,如何通过java例程将其设置为单面打印或双面打印? 我曾尝试使用它的库使用ASET添加和addViewer首选项没有任何运气。 有人能提供一些建议吗?

  • 我们有一个管理打印文档的项目。起初,我想知道为什么不能在一个地方设置打印选项。例如,可以使用MS Word自动化完成首页和其他页面的打印机托盘选择: 在上面的代码中,打印机托盘被指定为整数,因为一些打印机没有托盘的标准值(我们在HP中遇到了这个问题-这里描述了托盘代码)。因此,我们首先使用代码检索打印机的托盘: 这段代码工作正常。 但这里无法指定双面打印和装订选项。可以使用OpenPrinter和

  • 我有一个家庭作业要写“先到先得”和“循环模拟”,并对它们进行比较。我开始创建一个链表来制作事件列表。我已经实现了插入和打印列表功能,但无法正常工作。我的朋友告诉我使用双链表,所以我重新创建了链表,并试图使打印功能工作。我有一个关于插入函数的问题,因为我在while循环中的语句顺序有误。在修复了许多错误后,print函数会多次打印同一个节点,而不是整个列表。我不知道程序的哪一部分是错的。我认为我在i

  • 问题内容: 我有一个动物类,具有几个属性,例如: 我现在想将所有这些属性打印到文本文件中。我现在做的丑陋方式是: 有没有更好的Pythonic方式可以做到这一点? 问题答案: 在这种简单情况下,您可以使用: 如果要将Python对象存储在磁盘上,则应查看一下货架- Python对象持久性 。

  • 我有一个打印PDF的java程序。它使用Apache PDFBox创建一个对象(在某些情况下来自pdf文档或流),然后使用API将其发送到打印机: 现在我需要能够告诉打印机装订东西。。。 我熟悉javax.print.attributesAPI,并成功地使用它来指定托盘或设置双工,例如: 我知道装订有一个属性: 我有一个施乐Versalink B7035,带有Finisher XL附件,完全支持装

  • 主要内容:控件类型,控件基本属性我们知道,一个完整的 GUI 程序,其实是由有许多小的控件(widgets)构成的,比如按钮、文本框、输入框、选择框、菜单栏等等。在学习 Tkinter GUI 编程的过程中,不仅要学会如何摆放这些控件,还是掌握各种控件的功能、属性,只有这样才能开发出一个界面设计优雅,功能设计完善的 GUI 程序。 在创作本套教程的过程中,我们以控件的功能、属性作为切入点进行讲解。只有了解了控件的基本功能,才能在