如何获取任意PDF对象的页码?

时间:2015-06-15 21:41:17

标签: java pdf itext

我正在尝试使用itext的Java API查找PDF对象的页码。以下代码读入PDF文件,并获取包含open操作的对象。如何获取该对象的页码?

PdfReader soPdfItext = null;
      try {
        soPdfItext = new PdfReader(new FileInputStream("C:\\Temp\\sample.pdf"));
      } catch (IOException e) {
        /* barf here */
      }
      /* Get the catalog */
      PdfDictionary soCatalog = soPdfItext.getCatalog();
      /* Get the object referring to the open action */
      PRIndirectReference soOpenActionReference = (PRIndirectReference) soCatalog.get(PdfName.OPENACTION);
     /* Get the actual object containing the open action */
     PdfObject soOpenActionObject = originalPdfItext.getPdfObject(soOpenActionReference.getNumber());

现在怎样?有一个类文档包含一个方法getPageNumber(),但我不确定a)它与我想做的事情有关,b)是否相关,如何实现。

1 个答案:

答案 0 :(得分:3)

PDF中没有页码等内容。页面是页面树的一部分。此页面树由/Pages元素(树的分支)和/Page元素(树的叶子)组成。通过遍历树的不同分支和叶子来计算页面索引。可选地,PDF还定义/PageLabels。如果您知道页面索引并且是否有页面标签的定义,则可以派生页码。

您正在提取代表开放操作的PdfObject。它可以是PdfDictionaryPdfArray

<强> PdfDictionary

如果PdfObjectPdfDictionary的实例,那么您需要查看此词典的/S项,以找出将触发的操作类型。

  • 这个动作可能是一些JavaScript。如果该JavaScript包含跳转到特定页面的操作,则该方法中可能存在页码。
  • 该操作可能是GoTo操作,在这种情况下,您需要查看目标(*)的/D条目。

有20种可能的操作类型,操作可以链接,因此您可以循环操作操作链并检查每个可能的操作。

这是一个例子:

/OpenAction<</D[8 0 R/Fit]/S/GoTo>>

<<>>表示使用字典描述了打开操作。 /S表示您有/GoTo个操作,/D描述了目的地。

<强> PdfArray

如果PdfActionPdfArray的实例,则此数组是目标(*)。

这是一个例子:

/OpenAction[6 0 R/XYZ 0 806 0]

目标

目标是一个由可变数量的元素组成的数组。这些是一些例子:

[8 0 R/Fit]
[6 0 R/XYZ 0 806 0]

第一个示例是一个包含两个元素8 0 R/Fit的数组。第二个示例是一个包含四个元素6 0 R/XYZ08060的数组。你需要第一个元素。它没有为您提供页码(因为没有页码等),但它为您提供了对/Page对象的引用。基于该引用,您可以通过循环页面树并将特定页面的对象编号与目标中的对象编号进行比较来推断页码。

P.S。在我对这个问题的回答中解释了其他要素:iTextPDF hyperlink not linking to the right place