fareed fareed - 6 days ago 7
Java Question

iText direct Printing

I am using iText to generate a pdf and write it to the file system as the following:

private void createPDF() throws Exception{
com.itextpdf.text.Document doc = new com.itextpdf.text.Document();
PdfWriter docWriter = null;
path = "C:\\PATH\\TO\\Desktop\\EXAMPLE_FOLDER\\" + pdfFilename;
docWriter = PdfWriter.getInstance(doc, new FileOutputStream(path));
doc.addTitle("Invoice");
doc.setPageSize(PageSize.A4);
doc.open();
PdfContentByte cb = docWriter.getDirectContent();
fillPDFDetails(cb);
if (doc != null) {
doc.close();
}
if (docWriter != null) {
docWriter.close();
}
}


However, I want to send the pdf to the printer and print the pdf file instead of writing it to the file system. How can I achieve this?

Answer

There's a theoretical and a practical answer to this question.

Let's start with the theoretical answer. There's a Java class called PrintStream that allows you to send an OutputStream to a printer:

Printstream extends FilterOutputStream extends OutputStream

A PrintStream adds functionality to another output stream, namely the ability to print representations of various data values conveniently. Two other features are provided as well. Unlike other output streams, a PrintStream never throws an IOException; instead, exceptional situations merely set an internal flag that can be tested via the checkError method. Optionally, a PrintStream can be created so as to flush automatically; this means that the flush method is automatically invoked after a byte array is written, one of the println methods is invoked, or a newline character or byte ('\n') is written.

So, suppose that you would like to create a PDF in memory and write it to a printer, you'd do something like this:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
Document document = new Document();
PdfWriter.getInstance(document, ps);
document.open();
// add content
document.close();

As PrintStream extends OutputStream and as PdfWriter accepts any type of OutputStream, you are writing the PDF bytes to the printer and if you want the PDF bytes, you can do baos.toByteArray().

However, the code snippet above sends PDF bytes to the printer. Chances are that your printer doesn't understand PDF and just prints out stuff like:

PDF-1.4
%âãÏÓ
2 0 obj
<</Length 64/Filter/FlateDecode>>stream
*binary stuff*
endstream
endobj
4 0 obj
<</Parent 3 0 R/Contents 2 0 R/Type/Page/Resources<</Font<</F1 1 0 R>>>>
/MediaBox[0 0 595 842]>>
endobj
1 0 obj
<</BaseFont/Helvetica/Type/Font/Encoding/WinAnsiEncoding/Subtype/Type1>>
endobj
3 0 obj
<</Type/Pages/Count 1/Kids[4 0 R]>>
endobj
5 0 obj
<</Type/Catalog/Pages 3 0 R>>
endobj
6 0 obj
<</Producer(iText® 5.4.2 ©2000-2012 1T3XT BVBA \(AGPL-version\))
/ModDate(D:20130502165150+02'00')/CreationDate(D:20130502165150+02'00')>>
endobj
xref
0 7
0000000000 65535 f 
0000000302 00000 n 
0000000015 00000 n 
0000000390 00000 n 
0000000145 00000 n 
0000000441 00000 n 
0000000486 00000 n 
trailer
<</Root 5 0 R/ID [<91bee3a87061eb2834fb6a3258bf817e><91bee3a87061eb2834fb6a3258bf817e>]
/Info 6 0 R/Size 7>>
%iText-5.4.2
startxref
639
%%EOF

Update:

In a comment, the following link was added: https://blog.idrsolutions.com/2010/01/printing-pdf-files-from-java/

This is actually a better way to print your file:

FileInputStream fis = new FileInputStream(“C:/mypdf.pdf”);
Doc pdfDoc = new SimpleDoc(fis, null, null);
DocPrintJob printJob = printService.createPrintJob();
printJob.print(pdfDoc, new HashPrintRequestAttributeSet());
fis.close();

If you don't want to use a FileInputStream, you can always create the PDF as a ByteArrayOutputStream and use the resulting byte[] to create a ByteArrayInputStream.

That's what the practical answer is about: it's not that difficult to create a PDF in memory. That's done like this:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
Document document = new Document();
PdfWriter.getInstance(document, baos);
document.open();
// add content
document.close();
byte[] pdf = baos.toByteArray();

The question is: what are you going to do with pdf?

Either your printer understands those bytes (there are printers that accept PDF syntax), or you'll have to find software that converts PDF into a format that printers understand. Usually, people use PDF rendering software (such as Adobe Reader) to print a document. Many of these viewers (Adobe Reader is one of them), require the file to exist as a file: Adobe Reader does not accept a byte array.

This explains why the practical answer isn't as easy as the theoretical answer: in practice, your question is far from trivial: it depends on the printer (which formats does it accept) and the PDF viewer (should you require one).

Comments