从PDF文件中读取超链接

4

我正在尝试读取一个PDF文件并获取该文件中的所有超链接。我正在使用C# .net的iTextSharp。

PdfReader reader = new PdfReader("test.pdf");           
List<PdfAnnotation.PdfImportedLink> list = reader.GetLinks(36); 

这个方法 "GetLinks" 返回一个关于链接的大量信息列表,但是该方法不返回我想要的超链接字符串值,而我确切地知道在第36页中有超链接。

2个回答

4

PdfReader.GetLinks()仅适用于文档内部的链接,而不是外部超链接。为什么?我不知道。

下面的代码基于我之前编写的代码,但我将其限制为存储在PDF中的链接,作为PdfName.URI。其可能将链接存储为最终执行相同操作的Javascript,并且可能存在其他类型,但您需要进行检测。我不认为规范中有任何内容说链接实际上需要是URI,只是暗示了这一点,因此下面的代码返回一个字符串,您可以(可能)自己转换为URI。

    private static List<string> GetPdfLinks(string file, int page)
    {
        //Open our reader
        PdfReader R = new PdfReader(file);

        //Get the current page
        PdfDictionary PageDictionary = R.GetPageN(page);

        //Get all of the annotations for the current page
        PdfArray Annots = PageDictionary.GetAsArray(PdfName.ANNOTS);

        //Make sure we have something
        if ((Annots == null) || (Annots.Length == 0))
            return null;

        List<string> Ret = new List<string>();

        //Loop through each annotation
        foreach (PdfObject A in Annots.ArrayList)
        {
            //Convert the itext-specific object as a generic PDF object
            PdfDictionary AnnotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(A);

            //Make sure this annotation has a link
            if (!AnnotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK))
                continue;

            //Make sure this annotation has an ACTION
            if (AnnotationDictionary.Get(PdfName.A) == null)
                continue;

            //Get the ACTION for the current annotation
            PdfDictionary AnnotationAction = (PdfDictionary)AnnotationDictionary.Get(PdfName.A);

            //Test if it is a URI action (There are tons of other types of actions, some of which might mimic URI, such as JavaScript, but those need to be handled seperately)
            if (AnnotationAction.Get(PdfName.S).Equals(PdfName.URI))
            {
                PdfString Destination = AnnotationAction.GetAsString(PdfName.URI);
                if (Destination != null)
                    Ret.Add(Destination.ToString());
            }
        }

        return Ret;

    }

并称其为:

        string myfile = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Output.pdf");
        List<string> Links = GetPdfLinks(myfile, 1);

Chris:你上面的代码几乎和我的一样,而且大部分时间似乎都能正常工作。但是我遇到的问题是,在尝试获取 PdfName.ANNOTS 时,有时会得到一个 null 值,而我明明可以看到文档中有超链接。你有什么想法吗?谢谢。 - one.beat.consumer
我会建议你做的第一件事是在Acrobat Pro中打开PDF(如果你有),对其运行Preflight,在选项中进入浏览内部PDF结构并查看是否有任何注释。另外一件事是确保你从一开始统计页面编号而不是零,我犯过这个错误很多次。如果这些不能帮助你,而且文件不是机密的话,你可以把它发给我,我的地址在我的个人资料里。 - Chris Haas
我想根据获取到的 URI 附加一个 JavaScript 操作。我猜想你必须将其附加到找到的 PdfObject 上,但是如何实现呢? - Florian Leitgeb

3

我注意到在PDF上看起来像URL的任何文本都可以通过PDF查看器模拟成注释链接。在Adobe Acrobat中,有一个名为“从URL创建链接”的页面显示首选项,它控制着这一点。我正在编写代码以删除URL链接注释,却发现没有这些注释。但是Acrobat会自动将看起来像URL的文本转换成似乎是注释链接的东西。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接