【问题标题】:How do I get a destination page of a link in PDF file?如何获取 PDF 文件中链接的目标页面?
【发布时间】:2018-03-29 02:54:16
【问题描述】:

使用iText,我们可以轻松更改链接的缩放级别。甚至有一块code 可以为GoTo 目标类型执行此操作。为方便起见,请在下方查找。

PdfReader reader = new PdfReader(src);
        PdfDictionary page = reader.getPageN(11);
        PdfArray annots = page.getAsArray(PdfName.ANNOTS); 
        for (int i = 0; i < annots.size(); i++) {
            PdfDictionary annotation = annots.getAsDict(i);
            if (PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) {
                PdfArray d = annotation.getAsArray(PdfName.DEST);
                if (d != null && d.size() == 5 && PdfName.XYZ.equals(d.getAsName(1)))
                    d.set(4, new PdfNumber(0));
            }
        }

该代码仅处理 PDF 文件中的一种目标类型。我有兴趣更改其他类型目的地的缩放(如果有人想知道,它们列在 32000-1 中)。具体来说,我想将每个目的地更改为GoTo 类型并指定我自己的坐标。我希望左坐标与要跳转的页面的页面高度相同。为此,我显然需要页码。如何获得?

到目前为止我做了什么? 指令 PdfArray d = annotation.getAsArray(PdfName.DEST) 给 su 一个数组,其中它的第一个(基于 0 的)元素是页面引用,而不是像 Bruno Lowagie 在他的 iText in Action, 2nd edition, p. 202). The array looks like this:[1931 0 R, /XYZ, 0, 677, 0]` 中解释的页码。我找不到正确的命令来自己获取页码,因此这篇文章。

【问题讨论】:

  • menteith,您能否使用安东回答中的信息确定页码?或者您对更多示例代码感兴趣?还是您认为您的问题没有以另一种方式得到解答?
  • 今天我将检查Anton的建议并编写一些处理页码的代码。完成后我会回复你。
  • @mkl 使用调试器我很容易找到带有引用的 ar 数组 (see),但我不知道如何使用 iText API 获取它。我检查了 Anton 提供的链接,但我发现很难理解应该做什么。
  • 我添加了一些特定代码的答案。
  • 你的意思是在标题中说“get a get”吗?

标签: java itext


【解决方案1】:

据此: https://developers.itextpdf.com/fr/node/1750

第一个示例是一个包含两个元素 8 0 R 和 /Fit 的数组。这 第二个例子是一个有四个元素的数组 6 0 R, /XYZ, 0, 806 和 0. 你需要第一个元素。它没有给你页码(因为没有页码之类的东西),但它给了你一个 对 /Page 对象的引用。基于该参考,您可以推断 通过遍历页面树并比较对象来获得页码 目标中具有对象编号的特定页面的编号。

您可以递归地提取页码,如下所示: Extract page number from PDF file

希望对您有所帮助。祝你好运!

【讨论】:

    【解决方案2】:

    我希望左坐标与要跳转的页面的页面高度相同。为此,我显然需要页码。如何获得?

    您需要页码的假设是错误的。 PdfReader 实用程序方法主要基于页码工作,是的,但这些方法中没有太多内容。因此,如果您对一些低级数据访问没问题,则不需要页码。

    以下是您的代码以及用于检索裁剪框(定义左侧、底部、右侧和顶部坐标)的附加代码,一次直接来自您在目标中的对象引用,一次通过页码。

    PdfReader reader = new PdfReader(src);
    PdfDictionary page = reader.getPageN(11);
    PdfArray annots = page.getAsArray(PdfName.ANNOTS); 
    for (int i = 0; i < annots.size(); i++) {
        PdfDictionary annotation = annots.getAsDict(i);
        if (PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) {
            PdfArray d = annotation.getAsArray(PdfName.DEST);
            if (d == null) {  // in case the link has not a Dest but instead a GoTo action
                PdfDictionary action = annotation.getAsDict(PdfName.A);
                if (action != null)
                    d = action.getAsArray(PdfName.D);
            }
    
            if (d != null && d.size() > 0) {
                System.out.println("Next destination -");
                PdfIndirectReference pageReference = d.getAsIndirectObject(0);
    
                // Work with target dictionary directly
                PdfDictionary pageDict = d.getAsDict(0);
                PdfArray boxArray = pageDict.getAsArray(PdfName.CROPBOX);
                if (boxArray == null) {
                    boxArray = pageDict.getAsArray(PdfName.MEDIABOX);
                }
                Rectangle box = PdfReader.getNormalizedRectangle(boxArray);
                System.out.printf("* Target page object %s has cropbox %s\n", pageReference, box);
    
                // Work via page number
                for (int pageNr = 1; pageNr <= reader.getNumberOfPages(); pageNr++) {
                    PRIndirectReference pp = reader.getPageOrigRef(pageNr);
                    if (pp.getGeneration() == pageReference.getGeneration() && pp.getNumber() == pageReference.getNumber()) {
                        System.out.printf("* Target page %s has cropbox %s\n", pageNr, reader.getCropBox(pageNr));
                        break;
                    }
                }
            }
        }
    }
    

    (ProcessLink 测试testDetermineTargetPage)


    顺便说一下,目的地也可以是命名目的地。因此,如果某些 PDF 的 Dest 值碰巧不是数组而是字符串,您只需在 Dests 名称树中查找即可。

    【讨论】:

      猜你喜欢
      • 2018-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-17
      • 1970-01-01
      • 1970-01-01
      • 2012-03-14
      相关资源
      最近更新 更多