我正在尝试使用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)是否相关,如何实现。
答案 0 :(得分:3)
PDF中没有页码等内容。页面是页面树的一部分。此页面树由/Pages
元素(树的分支)和/Page
元素(树的叶子)组成。通过遍历树的不同分支和叶子来计算页面索引。可选地,PDF还定义/PageLabels
。如果您知道页面索引并且是否有页面标签的定义,则可以派生页码。
您正在提取代表开放操作的PdfObject
。它可以是PdfDictionary
或PdfArray
。
<强> PdfDictionary 强>
如果PdfObject
是PdfDictionary
的实例,那么您需要查看此词典的/S
项,以找出将触发的操作类型。
GoTo
操作,在这种情况下,您需要查看目标(*)的/D
条目。有20种可能的操作类型,操作可以链接,因此您可以循环操作操作链并检查每个可能的操作。
这是一个例子:
/OpenAction<</D[8 0 R/Fit]/S/GoTo>>
<<
和>>
表示使用字典描述了打开操作。 /S
表示您有/GoTo
个操作,/D
描述了目的地。
<强> PdfArray 强>
如果PdfAction
是PdfArray
的实例,则此数组是目标(*)。
这是一个例子:
/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
,/XYZ
,0
,806
和0
的数组。你需要第一个元素。它没有为您提供页码(因为没有页码等),但它为您提供了对/Page
对象的引用。基于该引用,您可以通过循环页面树并将特定页面的对象编号与目标中的对象编号进行比较来推断页码。
P.S。在我对这个问题的回答中解释了其他要素:iTextPDF hyperlink not linking to the right place