【问题标题】:Using iText PdfCopy or PdfSmartCopy to assemble stamped pages leads to invalid PDF使用 iText PdfCopy 或 PdfSmartCopy 组装盖章页面会导致 PDF 无效
【发布时间】:2014-10-15 05:55:54
【问题描述】:

我正在使用 iText 一遍又一遍地标记 PDF 表单,并尝试将生成的单页 pdf 编译成一个在 RAM 中有许多页面的单个 pdf,并在 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);
        }
    }
}

【问题讨论】:

    标签: java pdf itext


    【解决方案1】:

    看看下面一行:

    response.setContentLength(mainBaos.size());
    

    您告诉响应您将向浏览器发送多少字节。但是:此时,您不知道 PDF 的确切大小,因为您还没有关闭文档。

    您可以通过移动以下行来解决您的问题:

    doc.close();
    

    这将完成文档。不要在此行之前设置内容长度。

    【讨论】:

    • 非常感谢您抓住这位洛瓦吉大师。你是男人!我刚刚从 iText 2.1.1 升级到 5.5.3,升级非常轻松。很抱歉看到您的名字从包裹中消失。做正确的事,但你值得称赞。
    • 谢谢!这正确的做法,因为现在有一个完整的团队支持 iText。它不再是一个或两个人的项目;-)
    猜你喜欢
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    相关资源
    最近更新 更多