Imprimindo com atributos (Controle de Bandeja, Duplex, etc…) usando a biblioteca javax.print
Eu tenho tentado por algum tempo para determinar uma maneira de usar obiblioteca padrão de impressão Java para imprimir arquivos - especificamente, documentos PDF - comcertos atributos - especificamente, para determinadas bandejas ou usando duplex.
Existe muita documentação sobre como isso deve ser feito e, de fato, pesquisei e experimentei esses métodos. A maneira típica é algo assim:
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();
}
}
Em suma, você faz o seguinte
Encontre a impressoraCrie um PrinterJobCrie um AttributeSetAdicionar Atributos ao AttributeSet, como Bandeja e DuplexChame a impressão no trabalho da impressora usando o AttributeSetO problema aqui é que, apesar de ser a maneira documentada de fazer isso, bem como o que eu encontrei de vários tutoriais, esse método ...não funciona. Agora lembre-se, eu sei que isso não soa muito descritivo, mas me ouça.Eu não digo isso levemente...
A documentação oficial do PrinterJob Na verdade, menciona que o AttributeSet é ignorado na implementação padrão.Código fonte visto aqui mostra que isso é verdade - os atributos são passados e ignorados inteiramente.
Então, aparentemente, você precisa de algum tipo de versão estendida da classe, que é possivelmente baseada nas impressoras específicas e suas capacidades? Eu tentei escrever algum código de teste que me diria tais capacidades - nós temos uma grande variedade de impressoras configuradas no escritório, grandes ou pequenas, simples ou cheias de sinos e assobios - para não mencionar vários drivers no meu computador apenas para pseudo Drivers de impressoras que apenas criam documentos e simulam impressoras sem precisar de nenhum tipo de hardware. O código de teste é o seguinte:
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"));
}
Os resultados que encontrei foram que todas as impressoras, sem exceção, retornaram que "cópias" eram suportadas e todos os outros atributos não eram. Além disso, todos os recursos da impressora eram idênticos, independentemente de quão implausível isso pudesse parecer.
A questão inevitável é multi-camadas: como alguém envia atributos de uma maneira que eles são registrados? Além disso, como se detecta adequadamente os recursos de uma impressora? De fato, a classe PrinterJob é realmente estendida de uma maneira utilizável, ou os atributos são sempre ignorados?
Exemplos que eu encontrei em toda a Internet parecem sugerir que a resposta para a última questão é "Não, eles são sempre ignorados", o que parece ridículo para mim (mas cada vez mais mais crível à medida que vasculho centenas de páginas).É este código que a Sun simplesmente configurou, mas nunca funcionou para um estado completo? Se então,Existem alternativas?