在 Java 中使用 pdfbox 为 PDF 中的方程式插入双精度值
Insert double Value for equation in PDF with pdfbox in Java
我正在为一个 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
奇怪的是:当我手动更改文档中的值时,一切正常,即使使用不同的文档查看器也是如此。
首先,您PDF中的AcroForm表单结构很奇怪。看起来有人使用了他不理解的图形表单生成工具并单击、拖放、复制、...直到查看器中的表单完成了他想要的操作,而不关心它变得难以维护。
特别是 Einzelpreis 字段具有完全不必要的中间字段和最终字段结构,例如
因此,字段 Einzelpreis in € exkl USt1
(上面的树中缺少 '€')不是要填写的字段,它只是一个中间字段。实际要填写的表单字段是 Einzelpreis in € exkl USt1.0.0.0.0
.
不幸的是,你在你的代码中简单地获取了由PDAcroForm
编辑的字段列表return中的第30个字段,而这个字段恰好是中间字段Einzelpreis in € exkl USt1
;作为中间字段,它没有自己的可见小部件,因此您的 setValue
调用不会更改可见的 Einzelpreis。
计算Gesamtpreis的JavaScript指令也使用了final字段的值:
AFSimple_Calculate("PRD", new Array ("Anzahl1", "Einzelpreis in € exkl USt1.0.0.0.0"));
但是由于字段值是可继承的,并且 .0 字段的 none 有自己的值,一旦表单计算被触发,计算就会看到 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 不使用 javascript.因此,您必须自己计算这些值并相应地更新相关字段。
如果您需要知道表单域的正确名称,您可以按照 Tilman 的建议使用 PDFBox PDFDebugger。如果将鼠标悬停在此处的字段上,它会在底部的状态栏中显示名称。
顺便说一下,AcroForm
方法 getFields
无论如何都不会 return 这里需要的字段。正如其 JavaDocs 中所述,此方法 将 return 所有文档 根字段 ,没有字段在层次结构中进一步向下,位于至少不是立即。 (从用户的角度来看,方法名称 getFields
是用词不当。不过,从 PDF 规范的角度来看,它是准确的,因为 AcroForms 对象中的相应条目具有键 字段.)
但是请注意,您可能必须更新 PDFBox 版本。在早期版本中,PDFBox 没有使用 JavaScript 操作更新字段的外观(相信一些 JavaScript 无论如何都会填充它)。我使用了当前的 3.0.0-SNAPSHOT,其中该行为已更改。
我正在为一个 Java 项目苦苦挣扎: 我制作了一个自动填充 PDF 公式的程序。大多数情况下一切对我来说都很好,但有一个问题:在这个 PDF 公式(这是我公司提供的,所以我必须处理这个文档)中是一个方程式字段,用于计算项目数量的成本和单一的价格。当我将单个项目的价格作为字符串插入到我的 PDF
public void setEinzelpreis(String Einzelpreis)
{
try {
fieldList.get(30).setValue(Einzelpreis);
...
第一行空白处应该有一个价格。该行的最后一个单元格由 pdf 自动计算。
当我在“空白”字段中单击 PDF 时,会出现以下值:
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
奇怪的是:当我手动更改文档中的值时,一切正常,即使使用不同的文档查看器也是如此。
首先,您PDF中的AcroForm表单结构很奇怪。看起来有人使用了他不理解的图形表单生成工具并单击、拖放、复制、...直到查看器中的表单完成了他想要的操作,而不关心它变得难以维护。
特别是 Einzelpreis 字段具有完全不必要的中间字段和最终字段结构,例如
因此,字段 Einzelpreis in € exkl USt1
(上面的树中缺少 '€')不是要填写的字段,它只是一个中间字段。实际要填写的表单字段是 Einzelpreis in € exkl USt1.0.0.0.0
.
不幸的是,你在你的代码中简单地获取了由PDAcroForm
编辑的字段列表return中的第30个字段,而这个字段恰好是中间字段Einzelpreis in € exkl USt1
;作为中间字段,它没有自己的可见小部件,因此您的 setValue
调用不会更改可见的 Einzelpreis。
计算Gesamtpreis的JavaScript指令也使用了final字段的值:
AFSimple_Calculate("PRD", new Array ("Anzahl1", "Einzelpreis in € exkl USt1.0.0.0.0"));
但是由于字段值是可继承的,并且 .0 字段的 none 有自己的值,一旦表单计算被触发,计算就会看到 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 不使用 javascript.因此,您必须自己计算这些值并相应地更新相关字段。
如果您需要知道表单域的正确名称,您可以按照 Tilman 的建议使用 PDFBox PDFDebugger。如果将鼠标悬停在此处的字段上,它会在底部的状态栏中显示名称。
顺便说一下,AcroForm
方法 getFields
无论如何都不会 return 这里需要的字段。正如其 JavaDocs 中所述,此方法 将 return 所有文档 根字段 ,没有字段在层次结构中进一步向下,位于至少不是立即。 (从用户的角度来看,方法名称 getFields
是用词不当。不过,从 PDF 规范的角度来看,它是准确的,因为 AcroForms 对象中的相应条目具有键 字段.)
但是请注意,您可能必须更新 PDFBox 版本。在早期版本中,PDFBox 没有使用 JavaScript 操作更新字段的外观(相信一些 JavaScript 无论如何都会填充它)。我使用了当前的 3.0.0-SNAPSHOT,其中该行为已更改。