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

Java打印PDF,带选项(装订、双面打印等)

阎阳
2023-03-14

我有一个打印PDF的java程序。它使用Apache PDFBox创建一个PDDocument对象(在某些情况下来自pdf文档或流),然后使用javax.printAPI将其发送到打印机:

private boolean print(File pdf, String printer)
{
    boolean success = false;

    try (PDDocument document = PDDocument.load(pdf))
    {
        PrintService[] printServices = PrinterJob.lookupPrintServices();
        PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPageable(new PDFPageable(document));

        // set printer
        if (printer != null)
        {
            for (PrintService selected : printServices)
            {
                if (selected.getName().equals(printer))
                {
                    printService = selected;
                    break;
                }
            }
        }
        job.setPrintService(printService);
        job.print();
        success = true;
    }
    catch (Exception e)
    {
        myLog.error("Printer error.", e);
    }
    return success;
}

现在我需要能够告诉打印机装订东西。。。

我熟悉javax.print.attributesAPI,并成功地使用它来指定托盘或设置双工,例如:

// this works fine
if (duplex != null)
{               
    if (duplex.equalsIgnoreCase("short"))
    {
        myLog.debug("Setting double-sided: Short");
        attr.add(Sides.TWO_SIDED_SHORT_EDGE);
    }
    else
    {
        myLog.debug("Setting double-sided: Long");
        attr.add(Sides.TWO_SIDED_LONG_EDGE);
    }
}

我知道装订有一个属性:

attr.add(javax.print.attribute.standard.Finishings.STAPLE);

我有一个施乐Versalink B7035,带有Finisher XL附件,完全支持装订(即它可以从MS Office文档设置中工作),但是打印机忽略了Java设置的STAPLE属性。我尝试了所有其他订书钉属性的变体,但很快发现打印机不支持任何Java整理属性。

或者用代码表示,以下打印没有结果:

DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
Object finishings = myPrinter.getSupportedAttributeValues(Finishings.class, flavor, null);
if (finishings != null && o.getClass().isArray())
{
    for (Finishings finishing : (Finishings[]) finishings)
    {
        System.out.println(finishing.getValue() + " : " + finishing);
    }
}

在阅读了这篇文章并尝试了一些不同的东西后,我得出结论,打印机不会接受装订属性,因为分页装订器是一个附件,或者只是因为施乐不喜欢Java或其他东西。因此,现在我试图通过在发送pdf之前将PJL命令预先添加到pdf来解决这个问题,如本文所述*PJL=打印作业语言

例如:

<ESC>%-12345X@PJL<CR><LF>
@PJL SET STAPLE=LEFTTOP<CR><LF>
@PJL ENTER LANGUAGE = PDF<CR><LF>
[... all bytes of the PDF file, starting with '%PDF-1.' ...]
[... all bytes of the PDF file ............................]
[... all bytes of the PDF file ............................]
[... all bytes of the PDF file, ending with '%%EOF' .......]
<ESC>%-12345X

起初,我假设Apache PDFBox库中只有一些方法可以做到这一点,但运气不好。然后,我检查了Ghost4J的API,没有看到任何关于预处理的内容。还有其他人解决了这个问题吗?

共有1个答案

蒋昊天
2023-03-14

恢复Java套接字打印使PJL成为一件事:

// this works, it also printed faster than javax.print when tested
private static void print(File document, String printerIpAddress, boolean staple)
{
    try (Socket socket = new Socket(printerIpAddress, 9100))
    {
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        byte[] bytes = Files.readAllBytes(document.toPath());

        out.write(27); //esc
        out.write("%-12345X@PJL\n".getBytes());
        out.write("@PJL SET DUPLEX=ON\n".getBytes());

        if (staple) 
        {
            out.write("@PJL SET STAPLEOPTION=ONE\n".getBytes());
        }
        out.write("@PJL ENTER LANGUAGE=PDF\n".getBytes());
        out.write(bytes);
        out.write(27); //esc
        out.write("%-12345X".getBytes());
        out.flush();
        out.close();
    }
    catch (Exception e)
    {
        System.out.println(e);
    }
}

所需的PJL命令来自此Xerox数据表。

需要注意的是,相同的PJL命令适用于两种不同的Xerox型号和Lexmark打印机,这就是我可以方便地测试的全部内容。不知道其他模特是否会想要不同的东西。

不再需要Apache PDFBox库。或者任何外部库。

这可能适用于PDF以外的其他类型的文档。

 类似资料:
  • 我有一个连接到CUPS的打印机,它支持双面打印,如何通过java例程将其设置为单面打印或双面打印? 我曾尝试使用它的库使用ASET添加和addViewer首选项没有任何运气。 有人能提供一些建议吗?

  • 1.打印订单的间距怎么修改? 打印订单的模板是系统自带的。需要改的话参考二开手册。

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

  • 我目前的工作是创建机械图纸,用于发送给客户和作为施工图。当我的绘图完成后,我导出一个. pdf文件,并将其发送给客户端。 我们的客户非常喜欢黑白画,所以我试着提供他们。但是我用来画画的软件效果不好。它只有一个选项“所有颜色都是黑色”,我的画上有一些白色的“隐藏线”。当然,这些显示使用所有颜色作为黑色选项。 我找到了一个解决方案,那就是使用pdf打印机。效果很好,效果也很好。 现在我想打印这个。pd

  • WooCommerce的订单页面内容繁多,如果直接打印后台页面,想必是惨不忍睹,还好有一款免费插件可以解决这个问题——WooCommerce Print Invoices & Delivery Notes,这个插件的好处是通过修改模版,你可以打印订单中的任何内容,漂亮的打印出来。 关于该插件的使用不再赘述,本文介绍如何修改打印模版,加入自己需要的数据。比如,加入产品缩略图和产品分类,效果如下图所示

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