更改其他PDF文档的链接 [英] Alter Links to Other PDF Documents

查看:99
本文介绍了更改其他PDF文档的链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有大量的pdf文件,每个文件都有打开其他pdf文件的链接.单击链接时,它将在同一文件系统中打开其他pdf文档.问题是我们需要更改某些目录的名称,这将需要更改指向该目录中pdf文档的所有链接.我们将手动执行此操作,但实际上有成千上万的链接需要更改.

We have a ton of pdf documents that each have links that open other pdf documents. When clicking on the links it will open up the other pdf document in the same file system. The problem is that we need to change the name of some of the directories which will require the changing of all the links that point to pdf documents in that directory. We would do this manually but there are literally thousands of links that need to be alter.

我们试图使用iTextSharp和PdfSharp来更改链接,但是要找到正确的对象却很困难.下面显示了带有两个链接的示例pdf文件的内容.您可以看到,对象12是引用对象21的链接,而对象21使用对象20中的引用打开了一个新窗口.对象类型为Filespec的对象20包含链接的pdf的路径Folder-Name/A.pdf.第二个链接遵循相同的模式,但是使用对象16、23和22.

We have tried to use iTextSharp and PdfSharp to alter the links but are having a difficult time getting to the right object. Below shows the contents of a sample pdf file with two links. You can see that object 12 is a link that references object 21 and object 21 opens a new window using the reference in object 20. Object 20, of type Filespec contains the path to the linked pdf, Folder-Name/A.pdf. The second link follows the same pattern but uses objects 16, 23, and 22.

12 0 obj<</Type/Annot/P 5 0 R/F 4/C[1 0 0]/Subtype/Link/A 21 0 R/M(D:20130710103035-07'00')/Border[0 0 0]/Rect[144 612 216 630]/NM(QVDTKWKAZGVAAGHJ)/BS 13 0 R>>
endobj
13 0 obj<</W 0/S/S/Type/Border>>
endobj
16 0 obj<</Type/Annot/P 5 0 R/F 4/C[1 0 0]/Subtype/Link/A 23 0 R/M(D:20130710103040-07'00')/Border[0 0 0]/Rect[126 594 216 612]/NM(WFAYQFGTTIESQOKW)/BS 17 0 R>>
endobj
17 0 obj<</W 0/S/S/Type/Border>>
endobj
20 0 obj<</Type/Filespec/F(Folder-Name/A.pdf)/UF(Folder-Name/A.pdf)/Desc()>>
endobj
21 0 obj<</S/GoToR/D[0/Fit]/NewWindow true/F 20 0 R>>
endobj
22 0 obj<</Type/Filespec/F(Folder-Name-2/B.pdf)/UF(Folder-Name-2/B.pdf)/Desc()>>
endobj
23 0 obj<</S/GoToR/D[0/Fit]/NewWindow true/F 22 0 R>>
endobj

如何使用iTextSharp或PdfSharp将文件夹名称"和文件夹名称-2"更改为其他任意文件夹路径?

How can we use iTextSharp or PdfSharp to change "Folder-Name" and "Folder-Name-2" to some other arbitrary folder path?

推荐答案

万一有人在意,我可以使用Chris Haas在上面的第一条评论中链接的代码,但可以对其进行如下修改:

In case anyone cares, I was able to use the code linked by Chris Haas in the first comment above but modified it as follows:

foreach (FileInfo file in files)
{                    

    PdfReader reader = default(PdfReader);

    bool linkReplaced = false;

    //Setup some variables to be used later
    reader = new PdfReader(file.FullName);

    int pageCount = reader.NumberOfPages;
    PdfDictionary pageDictionary = default(PdfDictionary);
    PdfArray annots = default(PdfArray);

    //Loop through each page
    for (int i = 1; i <= pageCount; i++)
    {
        //Get the current page
        pageDictionary = reader.GetPageN(i);

        //Get all of the annotations for the current page
        annots = pageDictionary.GetAsArray(PdfName.ANNOTS);

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

        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;

            string fValue = string.Empty;
            string ufValue = string.Empty;
            string uriValue = string.Empty;

            PdfObject a = AnnotationDictionary.Get(PdfName.A);
            if (a.IsDictionary())
            {
                //Get the ACTION for the current annotation
                PdfDictionary AnnotationAction = (PdfDictionary)a;

                //Test if it is a URI action
                if (AnnotationAction.Get(PdfName.S).Equals(PdfName.URI))
                {
                    uriValue = AnnotationAction.Get(PdfName.URI).ToString();

                    if ((uriValue.IndexOf(findValue, StringComparison.OrdinalIgnoreCase) > -1))
                    {
                        string uriValueReplace = Replace(uriValue, findValue, replaceValue, StringComparison.OrdinalIgnoreCase);

                        //Change the URI to something else
                        AnnotationAction.Put(PdfName.URI, new PdfString(uriValueReplace));                                          
                        linkReplaced = true;
                    }
                }                                               
            }
            else if (a.IsIndirect())
            {
                // Get the indirect reference
                PdfIndirectReference indirectRef = (PdfIndirectReference)a;

                // Get the GoToR type object which is at the document level
                PdfDictionary goToR = (PdfDictionary)reader.GetPdfObject(indirectRef.Number);

                // Get the FileSpec object whic his at the document lelvel
                PdfObject f = goToR.Get(PdfName.F);

                if (f == null || !f.IsIndirect())
                    continue;

                PdfObject fileSpecObject = reader.GetPdfObject(((PdfIndirectReference)goToR.Get(PdfName.F)).Number);

                if (!fileSpecObject.IsDictionary())
                    continue;

                PdfDictionary fileSpec = (PdfDictionary)fileSpecObject;

                fValue = fileSpec.Get(PdfName.F).ToString();
                ufValue = fileSpec.Get(PdfName.UF).ToString();

                if ((fValue.IndexOf(findValue, StringComparison.OrdinalIgnoreCase) > -1) || (ufValue.IndexOf(findValue, StringComparison.OrdinalIgnoreCase) > -1))
                {
                    string fValueReplace = Replace(fValue, findValue, replaceValue, StringComparison.OrdinalIgnoreCase);// fValue.Replace(findValue, replaceValue);
                    string ufValueReplace = Replace(fValue, findValue, replaceValue, StringComparison.OrdinalIgnoreCase);// ufValue.Replace(findValue, replaceValue);

                    // Update the references to the file
                    fileSpec.Put(PdfName.F, new PdfString(fValueReplace));
                    fileSpec.Put(PdfName.UF, new PdfString(ufValueReplace));                                    

                    linkReplaced = true;
                }
            }                                
        }
    }
}   

这篇关于更改其他PDF文档的链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆