iText direct Printing
Solution 1
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
extendsFilterOutputStream
extendsOutputStream
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, aPrintStream
never throws anIOException
; instead, exceptional situations merely set an internal flag that can be tested via thecheckError
method. Optionally, aPrintStream
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).
Solution 2
Try this :
filename = "aaaaaaa.pdf";
java.io.File fileout = new File(filename);
com.lowagie.tools.Executable.printDocumentSilent(fileout));
fileout.delete(); // if you don't want to keep it.
![fareed](https://i.stack.imgur.com/EY5w6.jpg?s=256&g=1)
Comments
-
fareed over 2 years
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?
-
fareed about 9 yearsI have implemented your code, I'm getting the java.io.IOException: The document has no pages Exception.
-
Bruno Lowagie about 9 yearsThat's because you didn't add anything where it says
// add content
. -
fareed about 9 yearsI'm adding the details there!
-
Bruno Lowagie about 9 yearsThe exception tells me that you aren't adding anything to the
Document
instance. So whatever the details are, it's not content. -
fareed about 9 yearsI used the same code to write the file into the file system and it was working properly. Can you please see the complete code here? codeshare.io/tFXNL
-
Bruno Lowagie about 9 yearsWell, the exception is clear: it is only thrown if you're not adding any actual content.
-
fareed about 9 yearsI have researched and found that adding document.add(new Chunk("")); will solve the problem. Then after that nothing happens! How would I know that the job was sent to the printer? Nothing appears and even windows print dialog is not appearing
-
Bruno Lowagie about 9 yearsThe process sets an internal flag that can be tested via the
checkError
method. My bet is that the printer doesn't accept PDF. -
fareed about 9 yearsBut I can print any pdf file successfully with the connected printer! It appears that the printing job is not invoked
-
Bruno Lowagie about 9 yearsMaybe you can print any PDF successfully from an application such as Adobe Reader, but that doesn't mean you can print that PDF from Java!
-
fareed about 9 yearsThank you for your answer! So based on your answer, it is not possible to print a pdf file from Java memory because this would mean that a pdf processor such as Adobe Reader would need to access Java memory which is impossible. Correct me if I'm wrong.
-
Bruno Lowagie about 9 yearsYou are wrong. If your printer understands PDF, you can print directly to a printer (but many printers don't understand PDF). It may be possible with a PDF rendering library such as idrsolutions.com/pdf-print-quick-start (you'd have to ask the people of IDR Solutions of JPedal accepts a
byte[]
instead of a path to a PDF file). -
fareed about 9 yearsI see. I think I need to find a better way of doing it then! Thanks anyways! I will accept your answer
-
Sibi John over 6 years@fareed did you find a way? i also need to print an in memory pdf
-
fareed over 6 years@SibiJohn yes, you can send the pdf to the printing service and it will print.
-
Sibi John over 6 years@fareed in my case the printer is not able to understand the PDF byte syntax. i was hoping you had found a workaround.