我正在使用iText反复标记PDF表单并尝试将生成的单页pdfs编译成单个pdf,其中RAM中有许多页面并将其返回到http响应中。无论我做什么,都会出现无效的PDF。如果我在没有单页副本的情况下做同样的事情,那么PDF就是完美的。我尝试过使用PdfSmartCopy和PdfCopy,但结果总是无效的。我想我正在做的就像互联网上的例子所示,但我必须遗漏一些东西。谢谢你的建议!
ByteArrayOutputStream mainBaos;
PdfReader reader;
PdfStamper stamp;
AcroFields form;
OutputStream out = null;
try
{
List<PrintableCheck> checks = service.getChecksToPrint();
mainBaos = new ByteArrayOutputStream();
Document doc = new Document();
PdfSmartCopy mainPDF = new PdfSmartCopy(doc, mainBaos);
doc.open();
for (PrintableCheck check : checks)
{
reader = new PdfReader(PDF_FILENAME);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
stamp = new PdfStamper(reader, baos);
form = stamp.getAcroFields();
form.setField("checkDate", check.getDate());
form.setField("checkNumber", check.getNumber());
form.setField("amountAlpha", check.getAmountAlpha());
form.setField("amount", check.getAmount());
...
stamp.setFormFlattening(true);
stamp.close();
reader.close();
PdfReader reader2 = new PdfReader(baos.toByteArray());
PdfImportedPage page = mainPDF.getImportedPage(reader2, 1);
mainPDF.addPage(page);
mainPDF.freeReader(reader2);
reader2.close();
}
response.setContentType("application/pdf");
response.setContentLength(mainBaos.size());
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.addHeader("Content-Description", "File Transfer");
response.addHeader("Content-Disposition", "attachment; filename=checks"
+ bank + "-" + DATE_FORMAT.format(new Date()) + ".pdf");
response.addHeader("Content-Transfer-Encoding", "binary");
out = response.getOutputStream();
doc.close();
mainBaos.writeTo(out);
out.flush();
}
catch (Exception e)
{
log.error("Failed to print checks", e);
}
finally
{
if (out != null)
{
try
{
out.close();
}
catch (IOException e)
{
log.error("Could not close output stream", e);
}
}
}
答案 0 :(得分:2)
看一下以下一行:
response.setContentLength(mainBaos.size());
您告诉响应您将向浏览器发送多少字节。但是:在那一刻,您不知道PDF的确切大小,因为您还没有关闭文档。
您可以通过移动以下行来解决您的问题:
doc.close();
这最终确定了文件。不要在这一行之前设置内容长度。