acroform field.setRichTextValue 不工作

acroform field.setRichTextValue is not working

我有一个来自 acroform 的字段,我看到 field.setValue()field.setRichTextValue(...)。第一个设置了正确的值,但第二个似乎不起作用,不显示富文本值。 这是我使用的代码:

PDDocument pdfDocument = PDDocument.load(new File(SRC));
            pdfDocument.getDocument().setIsXRefStream(true);
            PDAcroForm acroForm = pdfDocument.getDocumentCatalog().getAcroForm();
            acroForm.setNeedAppearances(false);

            acroForm.getField("tenantDataValue").setValue("Deuxième texte");
            acroForm.getField("tradingAddressValue").setValue("Text replacé");
            acroForm.getField("buildingDataValue").setValue("Deuxième texte");
            acroForm.getField("oldRentValue").setValue("750");
            acroForm.getField("oldChargesValue").setValue("655");
            acroForm.getField("newRentValue").setValue("415");
            acroForm.getField("newChargesValue").setValue("358");
            acroForm.getField("increaseEffectiveDateValue").setValue("Texte 3eme contenu");


            // THIS RICH TEXT NOT SHOW ANYTHING
            PDTextField field = (PDTextField) acroForm.getField("tableData");
            field.setRichText(true);
            String val = "\rtpara[size=12]{para1}{This is 12pt font, while \span{size=8}{this is 8pt font.} OK?}";
            field.setRichTextValue(val);

我希望名为 "tableData" 的字段设置为富文本值!

您可以下载我使用此代码的 PDF 表格:download pdf form 您可以在运行此代码并展平表单数据后下载输出 download output here

总结问题评论中所说的内容以及对工作版本的一些研究...

错误的富文本格式

OP在他的原始代码中将其用作富文本

String val = "\rtpara[size=12]{para1}{This is 12pt font, while \span{size=8}{this is 8pt font.} OK?}";

他从 this document 中获取的。但是该文档是 LaTeX richtext 包的手册,其中 提供了“轻松”生成如此丰富的字符串所需的命令和文档。 即上面的 \rtpara... 不是 PDF 富文本,而是 而是 一个 生成 PDF 的 LaTeX 命令富文本(如果在 LaTeX 上下文中执行)。

该文档甚至使用示例

实际演示了这一点
\rtpara[indent=first]{para1}{Now is the time for
    \span{style={bold,italic,strikeit},color=ff0000}{J4rgen}
    and all good men to come to the aid of \it{their}
    \bf{country}. Now is the time for \span{style=italic}
    {all good} women to do the same.}

指令为其生成两个值,一个富文本值和一个纯文本值:

\useRV{para1}: <p dir="ltr" style="text-indent:12pt;
    margin-top:0pt;margin-bottom:0pt;">Now is the time
    for <span style="text-decoration:line-through;
    font-weight:bold;font-style:italic;color:#ff0000;
    ">J4rgen</span> and all good men to come to the
    aid of <i>their</i> <b>country</b>. Now is the
    time for <span style="font-style:italic;">all
    good</span> women to do the same.</p>
\useV{para1}: Now is the time for J4rgen and all
    good men to come to the aid of their country. Now
    is the time for all good women to do the same.

正如在 \useRV{para1} 结果中看到的那样,PDF 富文本使用(减少)HTML 富文本标记。

更多详细信息请查阅 PDF 规范,例如Adobe here

发布的 ISO 32000-1 副本中的第 12.7.3.4 "Rich Text Strings" 节

PDFBox 不创建富文本外观

他原代码中的OP使用

acroForm.setNeedAppearances(false);

这设置了一个标志,声称所有表单字段都有外观流(其中详细说明了相应表单字段的视觉外观及其内容)并且这些流代表字段的当前值,因此它有效地告诉 PDF 的下一个处理器它可以按原样使用这些外观流,不需要自己生成它们。

正如 @Tilman 从 JavaDocs 中引用的那样,

/**
 * Set the fields rich text value.
 * 
 * <p>
 * Setting the rich text value will not generate the appearance
 * for the field.
 * <br>
 * You can set {@link PDAcroForm#setNeedAppearances(Boolean)} to
 * signal a conforming reader to generate the appearance stream.
 * </p>
 * 
 * Providing null as the value will remove the default style string.
 * 
 * @param richTextValue a rich text string
 */
public void setRichTextValue(String richTextValue)

所以 setRichTextValue 而不是 为该字段创建适当的外观流。因此,要向 PDF 的下一个处理器(特别是查看器或表单拼合器)发出信号,表明它必须生成外观,因此需要使用

acroForm.setNeedAppearances(true);

使 Adob​​e Acrobat (Reader) 从富文本生成外观

当要求为富文本字段生成字段外观时,Adobe Acrobat 可以选择基于富文本值 RV 或纯文本值 V。我做了一些快速检查,Adobe Acrobat 似乎使用了这些策略:

  1. 如果设置RVV的值等于RV[的值=106=] 如果没有富文本标记,Adobe Acrobat 会假定 RV 的值是最新的,并根据 PDF 规范从该富文本字符串生成外观。 否则 RV 的值(如果存在的话)被假定为已过时并被忽略!

  2. 否则,如果 V 值包含富文本标记,Adobe Acrobat 会假定此值为富文本并根据此样式创建外观。

    根据 PDF 规范,这不是

    可能是某些软件产品用于将富文本错误地放入 V 值中,Adobe Acrobat 开始支持这种误用以实现更大的兼容性。

  3. 否则 V 值将用作普通字符串并相应地生成外观。

这解释了为什么 OP 的原始方法仅使用

field.setRichTextValue(val);

显示没有变化 - 富文本值被 Adob​​e Acrobat 忽略。

这也解释了他的观察

then instead of setRichTextValue simply using field.setValue("<body xmlns=\"http://www.w3.org/1999/xhtml\"><p style=\"color:#FF0000;\">Red&#13;</p><p style=\"color:#1E487C;\">Blue&#13;</p></body>") works ! in acrobat reader (without flatten) the field is correctly formatted

不过请注意,这超出了 PDF 规范。如果要生成有效的 PDF,则必须同时设置 RVV 并让后者包含富文本的纯文本版本前者。

例如使用

String val = "<?xml version=\"1.0\"?>"
        + "<body xfa:APIVersion=\"Acroform:2.7.0.0\" xfa:spec=\"2.1\" xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:xfa=\"http://www.xfa.org/schema/xfa-data/1.0/\">"
        + "<p dir=\"ltr\" style=\"margin-top:0pt;margin-bottom:0pt;font-family:Helvetica;font-size:12pt\">"
        + "This is 12pt font, while "
        + "<span style=\"font-size:8pt\">this is 8pt font.</span>"
        + " OK?"
        + "</p>"
        + "</body>";
String valClean = "This is 12pt font, while this is 8pt font. OK?";
field.setValue(valClean);
field.setRichTextValue(val);

String val = "<body xmlns=\"http://www.w3.org/1999/xhtml\"><p style=\"color:#FF0000;\">Red&#13;</p><p style=\"color:#1E487C;\">Blue&#13;</p></body>";
String valClean = "Red\rBlue\r";
field.setValue(valClean);
field.setRichTextValue(val);