我有一个可打印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精加工属性。
或者将其放入代码中,以下内容不会显示任何结果:
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并尝试了一些其他操作之后,我得出结论,由于装订器是附件,或者仅仅是因为Xerox不喜欢Java或其他东西,所以打印机将不接受STAPLE属性。因此,现在我尝试通过在发送as covered here之前在pdf之前添加PJL命令来解决此问题。 * 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,却没有看到任何可以作为前缀的内容。有人解决了吗?
答案 0 :(得分:0)
恢复为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打印机,这些都是我方便测试的。 Dunno,如果其他模特想要其他东西。
不再需要Apache PDFBox库。或任何外部库。
这可能适用于除PDF之外的其他类型的文档。