iText直接打印

时间:2015-04-20 18:11:08

标签: java pdf printing itext

我正在使用iText生成pdf并将其写入文件系统,如下所示:

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文件,而不是将其写入文件系统。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:9)

这个问题有一个理论上和一个实际的答案。

让我们从理论答案开始。有一个名为PrintStream的Java类,允许您将OutputStream发送到打印机:

  

Printstream延伸FilterOutputStream延伸OutputStream

     

PrintStream为另一个输出流添加功能,即   能够方便地打印各种数据值的表示。   还提供了另外两个功能。与其他输出流不同,   PrintStream永远不会抛出IOException;相反,特殊   情况只是设置一个内部标志,可以通过   checkError方法。可选地,可以创建PrintStream以便   自动冲洗;这意味着flush方法是自动的   在写入字节数组后调用,其中一个println方法是   调用,或写入换行符或字节('\n')。

因此,假设您想在内存中创建PDF并将其写入打印机,您可以执行以下操作:

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

PrintStream扩展OutputStream并且PdfWriter接受任何类型的OutputStream时,您正在将PDF字节写入打印机,如果您想要PDF字节,则为可以做baos.toByteArray()

但是,上面的代码段会将PDF字节发送到打印机。您的打印机可能无法理解PDF并且只打印出以下内容:

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/

这实际上是打印文件的更好方法:

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,则始终可以将ByteArrayOutputStream创建为PDF,并使用生成的byte[]创建ByteArrayInputStream。< / p>

这就是实际答案:在内存中创建PDF并不困难。这是这样做的:

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

问题是:你打算用pdf做什么?

您的打印机可以理解这些字节(有些打印机可以接受PDF语法),或者您必须找到将PDF转换为打印机可以理解的格式的软件。通常,人们使用PDF渲染软件(如Adobe Reader)来打印文档。其中许多观众(Adobe Reader就是其中之一),要求文件作为文件存在:Adobe Reader不接受字节数组。

这解释了为什么实际答案并不像理论答案那么简单:在实践中,你的问题远非微不足道:它取决于打印机(它接受哪种格式)和PDF查看器(如果你需要一个) )。

答案 1 :(得分:1)

试试这个:

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.