2009-10-31 41 views
13

¿Hay alguna forma en Java para imprimir en una impresora IPP específica? Todo el código de ejemplo y tutoriales que he encontrado enfoque sobre cómo imprimir un determinado tipo de documento, usando algo como lo siguiente:Imprimir en una impresora específica (IPP URI) en Java

DocFlavor flavor = DocFlavor.INPUT_STREAM.POSTSCRIPT; 
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); 
aset.add(MediaSizeName.ISO_A4); 
PrintService[] pservices = 
      PrintServiceLookup.lookupPrintServices(flavor, aset); 
if (pservices.length > 0) { 
    DocPrintJob pj = pservices[0].createPrintJob(); 
    try { 
     FileInputStream fis = new FileInputStream("test.ps"); 
     Doc doc = new SimpleDoc(fis, flavor, null); 
     pj.print(doc, aset); 
    } catch (FileNotFoundException fe) { 
    } catch (PrintException e) { 
    } 
} 

Este fragmento simplemente imprime a la primera impresora encontró que es capaz de imprimir el documento. En mi caso, quiero buscar una impresora por su URI, pero PrintServiceLookup no parece apoyar esto. Intenté usar un PrintServiceAttributeSet, en lugar de PrintRequestAttributeSet, y agregué un atributo PrinterURI, pero eso no devuelve ninguna impresora. Sospecho que el servicio de búsqueda está buscando una impresora que pueda cambiar su URI de destino, en lugar de buscar la impresora con ese URI.

Como último recurso, pensé simplemente en enumerar a través de todos los PrintService devueltos por lookupPrintServices, pero el URI no está en ninguno de los atributos. El nombre de la impresora está allí, pero necesito el URI.

Para el fondo, mi aplicación necesita imprimir un código de barras a una impresora específica, según el usuario actual. Cada usuario está asociado con un URI de impresora, que apunta a una impresora en un servidor CUPS. El URI de la impresora es la única información que tengo, y no puedo restringir el nombre de la impresora para que coincida con el URI o una subcadena del URI.

Edit: Para aclarar un poco, no necesito renderizar los datos, solo tengo que copiar un blob en una impresora determinada. La parte que no puedo descifrar es cómo identificar una impresora por su URI IPP.

Respuesta

11

fin he encontrado una manera de hacer esto, mediante el uso de jipsi:

URI printerURI = new URI("ipp://SERVER:631/printers/PRINTER_NAME"); 
IppPrintService svc = new IppPrintService(printerURI); 
InputStream stream = new BufferedInputStream(new FileInputStream("image.epl")); 
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; 
Doc myDoc = new SimpleDoc(stream, flavor, null); 
DocPrintJob job = svc.createPrintJob(); 
job.print(myDoc, null); 

Tengo que admitir que estoy decepcionado por tener que utilizar una biblioteca tercera proveedores para hacer algo tan aparentemente simple como la impresión a una impresora específica.

ACTUALIZACIÓN

DR señala en el comments que jipsi tiene un nuevo home, y un nuevo nombre.

Cups4J es una buena alternativa, pero como su nombre lo indica, puede no funcionar correctamente si el destino no es un servidor CUPS. He obtenido buenos resultados utilizando Cups4J para imprimir directamente en una impresora térmica Zebra.

+0

Parece que el enlace está muerto, pero parece que el código original está disponible en code.google.com, aunque con un nombre diferente (jspi): http://code.google.com/p/jspi/ (Solo svn pago, no hay descargas) –

+0

@DR Gracias por el enlace, he actualizado la respuesta con la información. –

+0

¿Cómo descubrió a PRINTER_NAME para virar al final de la url? – rancidfishbreath

0

No creo que pueda obtener una impresora como a usted le gustaría (creo que el mecanismo de impresión Java es anterior a IPP).

Sin embargo, si recuerdo correctamente, puedo renderizar su trabajo de impresión localmente y luego enviar los bytes de la secuencia de salida al servidor CUPS de destino "a mano". ¿Sería esto "lo suficientemente bueno" para ti?

+0

En realidad, el trabajo de impresión ya ha sido procesado por un proceso externo en EPL, que es nativo de la impresora (similar a PostScript o PCL). Entonces sí, si puedo enviar los bytes al servidor CUPS eso sería lo suficientemente bueno. Me gustaría evitar implementar un cliente IPP a mano, si es posible. –

Cuestiones relacionadas