【发布时间】:2012-12-07 17:49:42
【问题描述】:
我在这里看到过关于这个问题的类似问题,尽管主要是在 C#/iTextSharp 的上下文中。
我有以下 Java 方法:
public byte[] prependCoversheet(byte[] pdfBytes)
{
InputStream pdfTemplate = getClass().getResourceAsStream("coversheet.pdf");
PdfReader reader = new PdfReader(pdfTemplate);
ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
PdfCopyFields copy = new PdfCopyFields(baos1);
PdfStamper stamper = new PdfStamper(reader, baos2);
AcroFields coversheet = stamper.getAcroFields();
/* Set all the field values here, etc. */
coversheet.setField("fieldName", "Lorem ipsum dolor sit amet.");
stamper.setFormFlattening(true);
stamper.close();
copy.addDocument(new PdfReader(baos2.toByteArray()));
copy.addDocument(new PdfReader(pdfBytes));
copy.close();
baos.flush();
return baos1.toByteArray();
}
返回的 byte[] 非常好,并且可以在 Adobe Reader 中正确打开(与类似但可能不相关的 earlier question of mine 不同)。 问题是当 PDF 关闭时,Reader 会抛出一个确认对话框:
“是否要在关闭前保存对 'someFilename.pdf' 的更改?”
显然,没有要保存的更改。 SO 上的其他线程将初始缓冲区数量尾部的无关的、未使用的字节作为罪魁祸首。我不清楚该模式是否适用于这种情况,尽管如果我在调试模式下停止我的 IDE,并在返回之前检查byte[],有大量连续字节与零 (0)。
不过,在这种情况下,我不知道如何确定字节数组的“正确”大小应该是多少。
更新: 上面的代码示例现在反映了 cmets 中 hoaz 使用两个 ByteArrayOutputStreams 的建议。这样就解决问题了!
【问题讨论】:
-
您确定重复使用相同的 BAOS 来标记和合并 PDF 是一个好主意吗?
-
@hoaz 实际上,不,我完全不确定。到目前为止它工作得很好。那里的潜在问题可能是什么——或者这是我的问题?
-
我会创建两个 BAOS 实例,一个用于压模,另一个用于拼接
-
如果在应用 @hoaz 建议使用单独的字节数组输出流(我确实支持)后,您仍然得到一个有问题的 PDF,请提供一个示例 PDF 以供检查。
-
我刚刚尝试了两个 ByteArrayOutputStreams。我将编辑上面的问题以说明我做了什么。
标签: java stream adobe bytearray itext