0

我正在为一个小 Java 项目苦苦挣扎:我制作了一个自动填充 PDF 公式的程序。大多数情况下对我来说一切都很好,但是有一个问题:在这个 PDF 公式中(由我的公司提供,所以我必须处理这个文件)是一个方程字段,用于计算项目数量的成本和单价。当我将单个项目的价格作为字符串插入我的 PDF 时

    public void setEinzelpreis(String Einzelpreis)
{
    try {
        fieldList.get(30).setValue(Einzelpreis);
...

在此处输入图像描述

第一行的空白字段中应该有一个价格。该行的最后一个单元格由 pdf 自动计算。当我在“空”字段中单击 PDF 时,会出现值: 在此处输入图像描述 当我单击另一个字段时,值会消失。这是我的问题。我通过 pdfbox 获取 FieldList,获取我的 PFD 的 fieldList 的代码是:

try {
    pdfTemplate = PDDocument.load(template);
    PDDocumentCatalog docCatalog = pdfTemplate.getDocumentCatalog();
    PDAcroForm acroForm = docCatalog.getAcroForm();
    if (acroForm != null)
    {
    // Get field names
    fieldList = acroForm.getFields();
    
    }
...

那么,谁能告诉我做错了什么?也许 PDF 想要等式的双精度值,而我给出的是字符串?但我不知道如何在 FieldList 中写一个 double。非常感谢每一个提示!

编辑:
我正在使用的 PDF 文件: https ://1drv.ms/b/s!Av6exjPNXlgOioouAuXL6QV4eUGkqg?e=ocfhvC

这是我生成的文件: https ://1drv.ms/b/s!Av6exjPNXlgOioovK-HuRuXW2aRy_w?e=D1ZCA8

奇怪的是:当我手动更改文档中的值时,一切正常,即使使用不同的文档查看器也是如此。

4

1 回答 1

1

首先,PDF 中的 AcroForm 表单结构很奇怪。看起来有人使用了他不理解的图形表单生成工具,然后单击、拖放、复制……直到查看器中的表单完成了他想要的操作,而不关心它变得难以维护。

特别是 Einzelpreis 字段具有完全不必要的中间字段和最终字段结构,例如

截屏

因此,该字段Einzelpreis in € exkl USt1(上面的树中缺少“€”)不是要填写的字段,它只是一个中间字段。要填写的实际表单域是Einzelpreis in € exkl USt1.0.0.0.0

不幸的是,您在您的代码中只是简单地获取了返回的字段列表中的第 30 个字段PDAcroForm,而该字段恰好是中间字段Einzelpreis in € exkl USt1;作为中间字段,它没有自己的可见小部件,因此您的setValue调用不会更改可见的 Einzelpreis。

计算 Gesamtpreis 的 JavaScript 指令也使用来自 final 字段的值:

AFSimple_Calculate("PRD", new Array ("Anzahl1", "Einzelpreis in € exkl USt1.0.0.0.0"));

但是由于字段值是可继承的,并且 .0 字段都没有自己的值,因此一旦触发了表单计算并使用它,计算就会看到 100。

因此,您应该填写该Einzelpreis in € exkl USt1.0.0.0.0字段。更安全的检索方式不是通过字段列表中的索引,而是通过名称:

PDField fieldByName = acroForm.getField("Einzelpreis in € exkl USt1.0.0.0.0");

(摘自FillInForm测试testFill2020_04BeschaffungsantragEinzelpreis

填写该字段后,“100”应该在您的表单中可见。

未计算 Gesamtpreis 值的剩余问题是由于@Tilman 在对该问题的评论中已经提到的事实:PDFBox doesn't use javascript。因此,您必须自己计算这些值并相应地更新相关字段。

如果您需要知道表单字段的正确名称,您可以按照 Tilman 的建议进行操作并使用 PDFBox PDFDebugger。如果您将鼠标悬停在该字段上,它将在底部的状态栏中显示名称。

顺便说一句,该AcroForm方法getFields无论如何都不会返回此处所需的字段。正如其 JavaDocs 中所记录的,此方法将返回所有文档根字段,层次结构中没有更向下的字段,至少不会立即返回。(从用户的角度来看,方法名称getFields用词不当。不过,从 PDF 规范的角度来看,它是准确的,因为AcroForms对象中的相应条目具有键Fields。)

但请注意,您可能必须更新您的 PDFBox 版本。在早期版本中,PDFBox 不会使用 JavaScript 操作更新字段的外观(相信一些 JavaScript 无论如何都会填充它)。我使用了当前的 3.0.0-SNAPSHOT,其中该行为已更改。

于 2020-11-20T11:20:10.353 回答