iText直接打印 [英] iText direct Printing
问题描述
我正在使用iText生成pdf并将其写入文件系统,如下所示:
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();
}
}
但是,我想将pdf发送到打印机并打印pdf文件,而不是将其写入文件系统。我怎样才能做到这一点?
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?
推荐答案
这个问题有一个理论上和一个实际的答案。
There's a theoretical and a practical answer to this question.
让我们从理论答案开始。有一个名为 PrintStream
允许您向打印机发送 OutputStream
:
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
Printstream
extendsFilterOutputStream
extendsOutputStream
A PrintStream
为另一个输出流添加功能,即
能够方便地打印各种数据值的表示。
还提供了另外两个功能。与其他输出流不同,
a PrintStream
从不抛出 IOException
;相反,特殊的
情况只是设置一个内部标志,可以通过
checkError
方法进行测试。 (可选)可以创建 PrintStream
,以便自动刷新
;这意味着在写入字节数组后,flush方法会自动调用
,其中一个println方法是
调用,或者是换行字符或字节('\ n'写了
)。
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.
所以,假设您想在内存中创建PDF并编写它到打印机,你会做这样的事情:
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
和 PdfWriter
接受任何类型的 OutputStream
,您正在编写PDF字节到打印机,如果你想要PDF字节,你可以做 baos.toByteArray()
。
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()
.
但是,上面的代码片段将PDF字节发送到打印机。您的打印机可能无法理解PDF,只打印出以下内容:
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
更新:
在评论中添加了以下链接: https://blog.idrsolutions.com/2010/01/printing-pdf-files-from-java/
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();
如果您不想使用 FileInputStream
,您始终可以创建PDF作为 ByteArrayOutputStream
并使用生成的 byte []
来创建 ByteArrayInputStream
。
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
.
这就是实际答案:在内存中创建PDF并不困难。这是这样做的:
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();
问题是:你打算怎么做 pdf
?
The question is: what are you going to do with pdf
?
您的打印机是否理解这些字节(有些打印机接受PDF语法),或者您必须找到将PDF转换为格式的软件打印机了解。通常,人们使用PDF渲染软件(如Adobe Reader)来打印文档。其中许多观众(Adobe Reader就是其中之一)要求文件作为文件存在:Adobe Reader不接受字节数组。
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.
这解释了为什么实际答案并不像理论答案那么容易:在实践中,你的问题远非微不足道:它取决于打印机(它接受哪种格式)和PDF查看器(如果你需要)。
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).
这篇关于iText直接打印的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!