【问题标题】:How to get AcroField Properties using iText?如何使用 iText 获取 AcroField 属性?
【发布时间】:2013-11-25 07:27:16
【问题描述】:

我正在使用 iText 阅读 pdf 文件。我的 pdf 中有 20 个具有不同 fillColor 属性的 Acro 文本字段。我试图读取属性但无法读取。有什么方法可以在java中获取具有特定颜色的字段作为它们的fillcolor属性?

编辑: 我使用以下 Adob​​e Javascript 在 pdf 中创建了 acro 字段

   var oFld = this.addField("nameOfField", "button", 0, fldRect);
    if (oFld != null) {
        oFld.buttonSetCaption("");
        oFld.borderStyle = border.s;
        oFld.fillColor = color.gray;
        oFld.textColor = color.white;
        oFld.lineWidth = 1;
    }

更新:

现在我可以读取颜色属性了。

不确定这样做是否正确?

  if(dict.getAsDict(PdfName.MK).get(PdfName.BG) !=null){
            if(dict.getAsDict(PdfName.MK).get(PdfName.BG).toString().trim().equals("     
    [0.0, 1.0, 0.0]")){
                System.out.println(entry.getKey());
                System.out.println("Green");
            }
            if(dict.getAsDict(PdfName.MK).get(PdfName.BG).toString().trim().equals("
        [1.0, 0.0, 0.0]")){
                System.out.println(entry.getKey());
                System.out.println("Red");
            }

        }

【问题讨论】:

  • 请提供有问题的 PDF。只是为了确保 Javascript 在 iText 处理它之前已应用于 PDF,并且您不希望 iText 执行 Javascript,对吗?
  • 做与不做的正确方法 - 好吧,用字符串比较检查不是正确的方法。这些是数字,应该检查为数字。此外,您最初的 if 子句 if(dict.getAsDict(PdfName.MK).get(PdfName.BG) !=null) 在没有 MK 字典的情况下失败。
  • 感谢您指出, if(ict.getAsDict(PdfName.MK)!=null) 应该避免空指针异常以及比较,我应该遍历 [1.0, 0.0, 0.0] 和比较每个数字或如何进行数字比较? @mkl
  • PdfName.BG 的值是一个(直接或间接)数组。因此,将其作为数组获取。然后你可以迭代。但请记住,数组元素的数量可能不同。 @Bruno 的回答包含相关信息。
  • @mkl 我正在使用以下代码来比较颜色。 stackoverflow.com/questions/20193997/…

标签: java pdf itext


【解决方案1】:

Chapter 8 of my book 从相当高的层次讨论 AcroForm 字段。如果你想深入挖掘,你需要chapter 13。在第 449 页,表 13.11 列出了不同的 AcroFields.Item 方法。如您所知,表单字段是使用表单字典描述的。使用一个或多个小部件注释来描述(或正在)一个或多个字段的视觉表示。您正在寻找外观的属性,因此您需要注解字典。

你也知道,当一个字段对应一个小部件注解时,字段字典和小部件字典通常会合并,这就是为什么AcroFields.Item类有一个名为getMerged()的方法。对于特定字段的每个小部件注释,它返回该字段的合并属性和小部件注释。

这就是理论。我们来看一个例子:InspectForm

Map<String,AcroFields.Item> fields = form.getFields();
AcroFields.Item item;
PdfDictionary dict;
int flags;
for (Map.Entry<String,AcroFields.Item> entry : fields.entrySet()) {
    out.write(entry.getKey());
    item = entry.getValue();
    dict = item.getMerged(0);
    // inspect dict
}

在示例中,我们检查字段标志 (/FF),它们是字段字典的属性。您对外观特征感兴趣,所以我想您会想要检查 /MK 条目,即(ISO-32000-1 表 188):

外观特征字典(见表 189) 用于构建动态外观流,指定 注释在页面上的视觉呈现。这个名字MK 条目仅具有历史意义,没有直接意义。

您需要查看表 189 以找出您想要的特定属性:

R 整数(可选): 小部件的度数 注释应相对于页面逆时针旋转。这 值应为 90 的倍数。默认值:0。

BC 数组(可选): 应在 0.0 到 1.0 范围内指定的数字数组 小部件注释边框的颜色。数组个数 元素确定颜色应在其中的颜色空间 被定义: 0 无颜色;透明 1 DeviceGray 3 DeviceRGB 4 DeviceCMYK

BG array(可选): 一个范围为 0.0 的数字数组 到 1.0 指定小部件注释背景的颜色。 数组元素的数量应确定颜色空间,如 为 BC 描述的。

CA 文本字符串(可选;仅限按钮字段): 小部件注解的正常标题,当它出现时会显示 不与用户交互。与列出的其余条目不同 在此表中,仅适用于与 按钮字段(请参阅第 12.7.4.2 节“按钮字段”中的按钮), CA 条目可以与任何类型的按钮字段一起使用,包括检查 框(请参阅第 12.7.4.2 节中的复选框,“按钮字段”)和单选按钮 (12.7.4.2 中的单选按钮,“按钮字段”)。

RC 文本字符串(可选;仅限按钮字段): 小部件注释的翻转 标题,当用户将光标滚动到 它的活动区域,无需按下鼠标按钮。

AC 文本字符串(可选;仅限按钮字段):小部件注释的备用 (down) 标题,当鼠标按钮按下时显示 在其活动区域内按下。

当您询问填充颜色时,我假设您指的是背景颜色,这意味着您必须查看颜色空间的 BC 条目,然后在 BG 实际颜色值的条目。

【讨论】:

  • 我使用 dict.getAsDict(PdfName.MK).get(PdfName.BG) 来获取颜色值,你提到表 189 来找出具体属性,我在哪里可以找到表?它在 PDF 规范中吗?
  • 是的,我在答案中完全复制了它:R、BC、BG、CA、RC 和 AC 是该表中列出的条目。假设 BC 为 3,那么 BG 将是一个包含三个值的数组:红色、绿色和黄色值,表示为 0 到 1 之间的数字。
  • 感谢您的明确解释。现在我可以读取 acro 字段的颜色属性了。我更新了我的问题。 @BrunoLowagie
猜你喜欢
  • 1970-01-01
  • 2013-06-14
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 2023-01-23
  • 1970-01-01
  • 2011-09-11
  • 2021-10-04
相关资源
最近更新 更多