iText直接打印 [英] iText direct Printing

查看:209
本文介绍了iText直接打印的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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 extends FilterOutputStream extends OutputStream

Printstream extends FilterOutputStream extends OutputStream

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆