【问题标题】:Java printing PDF with options (staple, duplex, etc)带有选项(装订、双面打印等)的 Java 打印 PDF
【发布时间】:2019-09-10 16:07:22
【问题描述】:

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

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.attributes API 并成功使用它来指定托盘或设置双面打印,例如:

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

我有一台带有 Finisher XL 附件的 Xerox Versalink B7035,该附件完全支持装订(即,它适用于 MS Office 文档设置),但是打印机忽略了 Java 设置的 STAPLE 属性。我尝试了装订属性的所有其他变体,但很快发现打印机不支持任何 Java 整理属性。

或者将其放入代码中,以下打印 NO 结果:

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

在阅读this 并尝试了一些不同的事情后,我得出结论,打印机不会接受 STAPLE 属性,因为装订器是附件,或者仅仅是因为施乐不喜欢 Java 或其他东西。所以现在我试图通过在发送之前将 PJL 命令添加到 pdf 来解决这个问题,as covered here。 *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 library 中只有一些方法可以做到这一点,但没有运气。然后我检查了Ghost4J 的API,并没有看到任何前置。其他人已经解决了这个问题吗?

【问题讨论】:

    标签: java printing pdfbox pjl stapler


    【解决方案1】:

    恢复到 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 datasheet

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

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

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

    【讨论】:

    • 这对于在设备上报告文件名也很有用:out.write(("@PJL SET JOBNAME=\"" + fileName + "\"\n").getBytes());
    猜你喜欢
    • 1970-01-01
    • 2012-06-28
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多