【问题标题】:Missing fields when merging PDF by using iText使用 iText 合并 PDF 时缺少字段
【发布时间】:2014-04-26 17:09:15
【问题描述】:

我使用 OpenOffice 创建 odt 文件,在该文件中创建表单域,并将 odf 文件保存为 PDF 文件。然后使用 itext 将数据填充到 pdf 文件中。每个 pdf 中显示的每个表单字段。但是当我合并 pdf 文件时,所有表单字段都丢失了。请帮忙。

设置字段代码:

            FileOutputStream fos = new FileOutputStream(outpath);
            PdfReader reader= new PdfReader(templateinputsream);
            PdfStamper stamp = new PdfStamper(reader, fos);
            AcroFields form = stamp.getAcroFields();
            setField(form, fieldsMap);

private void setField(AcroFields form, Map<String, String> map) {
    Iterator<Entry<String, String>> it = map.entrySet().iterator();
    while (it.hasNext()) {
        Entry<String, String> entry = it.next();
        String key = entry.getKey();
        String value = entry.getValue();
        try {
            form.setField(key, value);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}

合并pdf的代码:

private void mergePdf(List<String> files, String savepath) {
    try {
        List<InputStream> pdfs = new ArrayList<InputStream>();
        for (int i = 0; i < files.size(); i++) {
            pdfs.add(new FileInputStream(files.get(i)));
        }
        OutputStream output = new FileOutputStream(savepath);
        Document document = new Document(new PdfReader(files.get(0)).getPageSize(1));
        concatPDFs(document, pdfs, output);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public static void concatPDFs(Document document, List<InputStream> streamOfPDFFiles, OutputStream outputStream) {

    try {
        List<InputStream> pdfs = streamOfPDFFiles;
        List<PdfReader> readers = new ArrayList<PdfReader>();
        int totalPages = 0;
        Iterator<InputStream> iteratorPDFs = pdfs.iterator();
        while (iteratorPDFs.hasNext()) {
            InputStream pdf = iteratorPDFs.next();
            PdfReader pdfReader = new PdfReader(pdf);
            readers.add(pdfReader);
            totalPages += pdfReader.getNumberOfPages();
        }
        PdfWriter writer = PdfWriter.getInstance(document, outputStream);
        document.open();
        PdfContentByte cb = writer.getDirectContent(); // Holds the PDF
        PdfImportedPage page;
        int pageOfCurrentReaderPDF = 0;
        Iterator<PdfReader> iteratorPDFReader = readers.iterator();
        while (iteratorPDFReader.hasNext()) {
            PdfReader pdfReader = iteratorPDFReader.next();

            while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
                document.newPage();
                pageOfCurrentReaderPDF++;
                page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF);
                cb.addTemplate(page, 0, 0);
            }
            pageOfCurrentReaderPDF = 0;
        }
        outputStream.flush();
        document.close();
        outputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (document.isOpen())
            document.close();
        try {
            if (outputStream != null)
                outputStream.close();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }
}

【问题讨论】:

  • 您选择使用代码进行合并,这会显式丢弃所有交互式内容。你会找到解释和替代方案here

标签: java pdf itext


【解决方案1】:

我看到三个可能的问题:

[1.]

使用 OpenOffice 生成的表单存在一个已知问题:缺少外观! (实际上,应该有人告诉 OpenOffice 开发人员来解决这个问题)。您可以通过添加以下行来解决此问题:

fields.setGenerateAppearances(true);

有关完整示例,请参阅 FillDataSheet

[2.]

您犯了与"Duplicate questions" versus "RTFM"中所述相同的错误

如文档所述,使用PdfWriter 会丢弃所有交互功能。由于您没有展平您的文档,因此这些字段保持交互性,因此通过选择PdfWriter 而不是PdfCopy,您故意丢弃这些字段...

[3.]

当您使用PdfCopy 时,请确保您使用的是最新版本的 iText,因为最近才实现了表单的连接。请参阅 https://stackoverflow.com/a/20659958/1622493 以找到与您的问题几乎完全相同的副本。

【讨论】:

  • 合并页面时,似乎一个字段的所有值都相同。看起来,合并文件不同页面中的一个字段名称只能有一个值。例如,我有一个字段名称 PageNumber,不同的应该是不同的。但是现在所有的值都保持不变。
  • 如果您阅读 PDF 参考 (ISO-32000-1),您会发现一个具有一个明确名称的字段只能有一个明确的值。您是否在抱怨引用受到尊重?请阅读文档?如果您希望这些字段保持交互性,您可以重命名这些字段(如我的书中所述);如果它们不需要交互,请在合并文档之前展平字段。无论如何:请阅读文档...
  • 扁平化后,每个字段都丢失了。已经添加了这一行:fields.setGenerateAppearances(true);
  • 我们无法重现该问题。请参阅itextpdf.com/examples/iia.php?id=122,我们在其中获取使用 OpenOffice examples.itextpdf.com/resources/pdfs/datasheet.pdf 创建的表单,并将其填写为结果:examples.itextpdf.com/results/part2/chapter06/imdb0413300.pdf
猜你喜欢
  • 1970-01-01
  • 2015-12-23
  • 1970-01-01
  • 1970-01-01
  • 2019-03-28
  • 2012-04-23
  • 1970-01-01
  • 2016-11-22
  • 1970-01-01
相关资源
最近更新 更多