这个问题有理论和实践的答案。
让我们从理论上的答案开始。有一个名为 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()。
但是,上面的代码 sn-p 将 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,您始终可以将PDF 创建为ByteArrayOutputStream,然后使用生成的byte[] 创建ByteArrayInputStream。
这就是实际答案的意义所在:在内存中创建 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 查看器(如果您需要一个)。