1

i require to send a pdf document to print on the server side of a web app, the printer fully supports pdf printing etc, it is networked as well to the server. The pdf is also stored on the server.

what i am trying to is on a button click, print out the pdf file, currently i have the code below :

//Server side printing
public class PrintDocument {

    public void printText(String text) throws PrintException, IOException {

        //Looks for all printers
        //PrintService[] printServices = PrinterJob.lookupPrintServices();

        PrintService service = PrintServiceLookup.lookupDefaultPrintService();
        InputStream is = new ByteArrayInputStream(text.getBytes("UTF8"));
        PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
        pras.add(new Copies(1));

        DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
        Doc doc = new SimpleDoc(is, flavor, null);
        DocPrintJob job = service.createPrintJob();

        PrintJobWatcher pjw = new PrintJobWatcher(job);
        job.print(doc, pras);
        pjw.waitForDone();
        is.close();
    }
}

class PrintJobWatcher {

    boolean done = false;

    PrintJobWatcher(DocPrintJob job) {
        job.addPrintJobListener(new PrintJobAdapter() {
            public void printJobCanceled(PrintJobEvent pje) {
                allDone();
            }

            public void printJobCompleted(PrintJobEvent pje) {
                allDone();
            }

            public void printJobFailed(PrintJobEvent pje) {
                allDone();
            }

            public void printJobNoMoreEvents(PrintJobEvent pje) {
                allDone();
            }

            void allDone() {
                synchronized (PrintJobWatcher.this) {
                    done = true;
                    System.out.println("Printing has successfully completed, please collect your prints)");
                    PrintJobWatcher.this.notify();
                }
            }
        });
    }

    public synchronized void waitForDone() {
        try {
            while (!done) {
                wait();
            }
        } catch (InterruptedException e) {
        }
    }
}

But i have a few questions / issues, how do i put the pdf into the input stream for this to be printed out, can i select options such as duplex printing, and how can i call this from inside a JSF web app

Thanks

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555

3 Answers3

1

After reading through this Q&A I spent awhile working with the javax.print library only to discover that it is not very consistent with printer option support. I.e. even if a printer has an option like stapling, the javax.printer library showed it as "stapling not supported".

So I then tried out PJL commands using a plain java socket and it worked great, in my tests it also printed faster than the javax.print library, it has a much smaller code footprint and best part is no libraries are needed at all:

private static void print(File document, String printerIpAddress)
{
    try (Socket socket = new Socket(printerIpAddress, 9100))
    {
        DataOutputStream out = new DataOutputStream(socket.getOutputStream());
        String title = document.getName();
        byte[] bytes = Files.readAllBytes(document.toPath());

        out.write(27);
        out.write("%-12345X@PJL\n".getBytes());
        out.write(("@PJL SET JOBNAME=" + title + "\n").getBytes());
        out.write("@PJL SET DUPLEX=ON\n".getBytes());
        out.write("@PJL SET STAPLEOPTION=ONE\n".getBytes());
        out.write("@PJL ENTER LANGUAGE=PDF\n".getBytes());
        out.write(bytes);
        out.write(27);
        out.write("%-12345X".getBytes());
        out.flush();
        out.close();
    }
    catch (Exception e)
    {
        System.out.println(e);
    }
}

See this for more info on attempts with javax.print.

egerardus
  • 11,316
  • 12
  • 80
  • 123
  • This worked perfectly for me with an HP laser printer. Just wondering what the `out.write(27)` calls are doing? – Daniel Black May 26 '23 at 14:42
  • I found the answer in the article linked by another answer. It is the escape character, details here https://www.tachytelic.net/2010/10/hp-direct-pdf-printing-and-printer-tray-control/#article-comment-3197 – Daniel Black May 26 '23 at 15:59
0

According to this article it should be possible to start a print job with a PJL block (Wikipedia link includes pointers to the PJL reference documentation), followed by the PDF data.

Thank to PJL you should be able to control all features the printer has to offer including duplex, etc - the blog article even mentions stapling of a combined printout of 2 pdfs.

Be sure to read the comments on the article as well, there is a comment from the guy who's listed as inventor on the patent as well with extra information on the PJL commands.

fvu
  • 32,488
  • 6
  • 61
  • 79
0

Take a look at this blog. We had to print documents with duplex print option. Its not possible to duplex print directly in java. However the work around is to use ghostscript and convert PDF to PS (Post script file). To that you can add either PJL Commands or Post script commands.

More info at

http://reddymails.blogspot.com/2014/07/how-to-print-documents-using-java-how.html

Also read similar question

Printing with Attributes(Tray Control, Duplex, etc...) using javax.print library

Community
  • 1
  • 1
Reddymails
  • 793
  • 1
  • 10
  • 24
  • In addition I also found this jars from bfo.com which supports duplex printing using pure java for PDF's only. But Its COMMERCIAL. You need to Pay. http://bfo.com/blog/2012/02/15/using_java_to_print_pdf_documents.html – Reddymails – Reddymails Jan 30 '15 at 14:48