Как печатать PDF-файлы автоматически

У нас есть ряд систем, которые создают PDF-файлы, которые необходимо распечатать. Они хранятся в центральном хранилище документов. Затем в очередь JMS поступает сообщение о том, что документ необходимо напечатать. Служба, написанная на Java, подхватывает их, а затем вызывает нативную команду. Это вызов Adobe Reader с флагом /t. Это приводит к тому, что документ печатается без отображения графического интерфейса.

Однако после отключения электроэнергии это больше не работает. Тем временем нам приходится вручную печатать сотни документов. Первоначально мы пытались использовать печать с помощью Java, но PDF-файлы получались искаженными.

Что является лучшим решением для этого?


person pledge    schedule 03.02.2010    source источник
comment
Так почему бы не дублировать сервис локально. Есть ли какие-либо проблемы с этим?   -  person Adeel Ansari    schedule 03.02.2010
comment
Отключение электричества? Что ты имеешь в виду?   -  person Jeremy Stein    schedule 03.02.2010
comment
Мы потеряли электричество в здании, и эта машина не была включена в ИБП :(   -  person pledge    schedule 04.02.2010


Ответы (5)


Этот код работает, только если принтер поддерживает PDF. В противном случае вам нужно использовать собственный принтер или библиотеку Java. Об этом есть статья в блоге по адресу http://pdf.jpedal.org/java-pdf-blog/bid/25566/Printing-PDF-files-from-Java

person mark stephens    schedule 03.02.2010
comment
Спасибо. Это очень близко к работе с вариантом 1. Принтер говорит, что поддерживает прямую печать PDF. Это HP CM8050. Просто есть пара проблем со шрифтами, но нет проблем с макетом, как раньше. - person pledge; 04.02.2010
comment
3 года спустя этот ответ был полезен, и, поскольку данная ссылка не работает, вот ссылка новый - person Jorge Pinho; 27.11.2013

Покажите нам код. Я помню, как печатал PDF без проблем, используя Java Print API. Ниже приведен код, который может потребовать некоторых изменений, но должен работать как есть,

        InputStream in = new FileInputStream(file);
        DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;

        // find the printing service
        AttributeSet attributeSet = new HashAttributeSet();
        attributeSet.add(new PrinterName("FX", null));
        attributeSet.add(new Copies(1));

        PrintService[] services = PrintServiceLookup.lookupPrintServices(
                DocFlavor.INPUT_STREAM.PDF, attributeSet);

        //create document
        Doc doc = new SimpleDoc(in, flavor, null);

        // create the print job
        PrintService service = services[0];
        DocPrintJob job = service.createPrintJob();

        // monitor print job events
        PrintJobWatcher watcher = new PrintJobWatcher(job);

        System.out.println("Printing...");
        job.print(doc, null);

        // wait for the job to be done
        watcher.waitForDone();
        System.out.println("Job Completed!!");

Примечание:

  • Flavor не нужно в 2-х местах, достаточно 1 места. Вы это узнаете.
  • PrintJobWatcher — это вложенный класс, чтобы добавить PrintJobListener.
person Adeel Ansari    schedule 03.02.2010
comment
Это примерно то, что у нас было. Это отлично работает для простых макетов, но что-то более сложное с разными шрифтами и макетами начинает давать сбой. Вот почему мы вернулись к использованию Adobe Reader. - person pledge; 03.02.2010
comment
Так почему бы не дублировать сервис локально? Есть ли какие-либо проблемы с этим. - person Adeel Ansari; 03.02.2010
comment
Это на самом деле требует, чтобы базовая (специфическая для ОС) система печати поддерживала PDF, и в случае, если поддержка печати ОС для PDF ограничена, ваш код не будет работать. Код вообще не будет работать под Windows, и я полагаю, что большинство диспетчеров очереди печати Linux построены на основе ghostscript, который имеет довольно много ограничений в поддержке PDF. - person jarnbjo; 03.02.2010
comment
Как сказал @jarnbjo, INPUT_STREAM_PDF возвращает мне неверный вариант в Windows. При использовании AUTO_SENSE выводит пустую распечатку. - person Robin Jonsson; 08.09.2016

Начиная с Java 1.5, Sun разработала библиотеку рендеринга PDF для обработки PDF. Теперь это осталось за Swing Labs. И не уверен, будет ли он добавлен в будущие API Java. http://java.net/projects/pdf-renderer/

Он используется для просмотра или печати файлов PDF. для печати файлов PDF вы можете вызвать этот libray. Вот некоторая часть кода.

File input = new File(docName);
FileInputStream fis = new FileInputStream(input);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());

PDFFile curFile=null;
PDFPrintPage pages=null;
curFile = new PDFFile(bb); // Create PDF Print Page
pages = new PDFPrintPage(curFile);
PrinterJob pjob = PrinterJob.getPrinterJob();

PrintService[] services = pjob.lookupPrintServices();
for(PrintService ps:services){
    String pName = ps.getName();
    if(pName.equalsIgnoreCase("PrinterName")){
        pjob.setPrintService(ps);
        System.out.println(pName);
        break;
    }
}

pjob.setJobName(docName);
Book book = new Book();
PageFormat pformat = PrinterJob.getPrinterJob().defaultPage();
book.append(pages, pformat, curFile.getNumPages());
pjob.setPageable(book);

// print
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();


// Print it
pjob.print(aset);
person Alex    schedule 10.01.2012

Попробуйте использовать ICEpdf. Вот пример из страницы документации:

Document pdf = new Document();
pdf.setFile(filePath);

// create a new print helper with a specified paper size and print
// quality
PrintHelper printHelper = new PrintHelper(null, pdf.getPageTree(),
        0f, MediaSizeName.NA_LEGAL, PrintQuality.DRAFT);
// try and print pages 1 - 10, 1 copy, scale to fit paper.
printHelper.setupPrintService(selectedService, 0, 0, 1, true);
// print the document
printHelper.print();
person Lalith    schedule 03.02.2010

Вы можете использовать Apache PDFBox. Примеры:

а) Печать PDF как Pageable

PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = printService.createPrintJob();

PDDocument pdDocument = PDDocument.load(new File("doc.pdf"));
PDFPageable pdfPageable = new PDFPageable(pdDocument);
SimpleDoc doc = new SimpleDoc(pdfPageable, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);

printJob.print(doc, null);

б) Печать PDF как Printable

Преимущество этой опции в том, что вы можете контролировать размеры страницы, поля и т. д., изменяя переменную pageFormat.

PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = printService.createPrintJob();
PageFormat pageFormat = PrinterJob.getPrinterJob().defaultPage();

PDDocument pdDocument = PDDocument.load(new File("doc.pdf"));
PDFPrintable pdfPrintable = new PDFPrintable(pdDocument);

Book book = new Book();
book.append(pdfPrintable, pageFormat);
SimpleDoc doc = new SimpleDoc(book, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);

printJob.print(doc, null);
person user11153    schedule 20.02.2016