tags:

views:

1222

answers:

2

Is there any way in Java to print to a specific IPP printer? All of the sample code and tutorials I've found focus on how to print a particular type of document, using something like the following:

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

This snippet simply prints to the first printer found that is capable of printing the document. In my case, I want to lookup a printer by its URI, but PrintServiceLookup doesn't seem to support this. I've tried using a PrintServiceAttributeSet, instead of PrintRequestAttributeSet, and adding a PrinterURI attribute, but that doesn't return any printers. I suspect the lookup service is looking for a printer that can change its destination URI, rather than looking for the printer with that URI.

As a last resort, I thought about just enumerating through all of the PrintServices returned by lookupPrintServices, but the URI is not in any of the attributes. The printer name is there, but I need the URI.

For background, my webapp needs to print a barcode to a specific printer, based on the current user. Each user is associated with a printer URI, which points to a printer on a CUPS server. The printer URI is the only information I have, and I can't constrain the printer name to match the URI or a substring of the URI.

Edit: To clarify a bit, I don't need to render the data, I just need to copy a blob to a given printer. The part I can't figure out is how to identify a printer by its IPP URI.

A: 

I do not think you can get a printer the way you would like to (I think the Java Print mechanism predates IPP).

You may, however, if I recall correctly be able to render your print job locally and then ship the bytes of the output stream to the target CUPS server "by hand". Would this be "good enough" for you?

Thorbjørn Ravn Andersen
Actually, the print job has already been rendered by an external process into EPL, which is native to the printer (similar to postscript or PCL). So yes, if I can ship the bytes to the CUPS server that would be good enough. I'd like to avoid implementing an IPP client by hand though if possible.
Jason Day
A: 

I finally found a way to do this, by using 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);

I have to admit I'm disappointed at having to use a 3rd-party library to do something so seemingly simple as printing to a specific printer.

Jason Day