Печать на конкретный принтер (IPP URI) в Java
Есть ли какой-либо способ в Java для печати на определенный IPP-принтер? Все примеры кода и учебников, которые я нашел, сосредоточены на том, как печатать определенный тип документа, используя что-то вроде следующего:
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) {
}
}
Этот фрагмент просто печатает на первом найденном принтере, который способен печатать документ. В моем случае я хочу искать принтер по его URI, но PrintServiceLookup
, похоже, не поддерживает это. Я попытался использовать PrintServiceAttributeSet
вместо PrintRequestAttributeSet
и добавить атрибут PrinterURI
, но не возвращает никаких принтеров. Я подозреваю, что служба поиска ищет принтер, который может изменить URL-адрес получателя, вместо того, чтобы искать принтер с этим URI.
В крайнем случае я подумал о просто перечислении всего PrintService
, возвращаемого lookupPrintServices
, но URI не принадлежит ни одному из атрибутов. Имя принтера есть, но мне нужен URI.
Для фона мой webapp должен печатать штрих-код на конкретном принтере на основе текущего пользователя. Каждый пользователь связан с URI принтера, который указывает на принтер на сервере CUPS. URI принтера - единственная информация, которую я имею, и я не могу ограничить имя принтера в соответствии с URI или подстрокой URI.
Изменить: Чтобы немного уточнить, мне не нужно отображать данные, мне просто нужно скопировать blob на данный принтер. Часть, которую я не могу понять, заключается в том, как идентифицировать принтер по его IPP URI.
Ответы
Ответ 1
Наконец-то я нашел способ сделать это, используя 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);
Я должен признать, что я разочарован тем, что должен использовать стороннюю библиотеку, чтобы сделать что-то такое, казалось бы, простое, как печать на конкретном принтере.
UPDATE
DR указывает в комментариях, что jipsi имеет новый home, и новое имя.
Cups4J - хорошая альтернатива, но, как видно из названия, она может работать неправильно, если пункт назначения не является сервером CUPS. У меня были хорошие результаты, используя Cups4J для печати непосредственно на термопринтер Zebra.
Ответ 2
Я не думаю, что вы можете получить принтер так, как вам хотелось бы (я думаю, что механизм печати Java предшествует IPP).
Однако, если я правильно помню, я смогу выполнить локальное задание печати и затем отправить байты выходного потока на целевой сервер CUPS "вручную". Будет ли это "достаточно хорошим" для вас?