【问题标题】:Alter Links to Other PDF Documents更改指向其他 PDF 文档的链接
【发布时间】:2013-07-12 03:39:52
【问题描述】:

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

我们尝试使用 iTextSharp 和 PdfSharp 来更改链接,但很难找到正确的对象。下面显示了带有两个链接的示例 pdf 文件的内容。您可以看到对象 12 是一个引用对象 21 的链接,对象 21 使用对象 20 中的引用打开一个新窗口。对象 20,类型为 Filespec 包含链接的 pdf 的路径,Folder-Name/A.pdf。第二个链接遵循相同的模式,但使用对象 16、23 和 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 将“Folder-Name”和“Folder-Name-2”更改为其他任意文件夹路径?

【问题讨论】:

  • 这实际上是我开始的。我试图调整您提供的代码以使其工作但不能。正如您在提供的 PDF 文档中所见,没有 URI 参考。 Annotation 引用了一个 GoToR 对象,该对象随后引用了一个 Filespec 对象。它的链接结构与您提供的代码不同。
  • 不幸的是,我在生成看起来像这样的 PDF 时遇到了一些问题。我可以使用A 操作创建一个链接到文件的链接,也可以只创建一个普通的FileSpec,但对于我来说,我无法创建指向FileSpec 的操作。你能提供任何示例文件吗?或者您可以通过电子邮件将它们发送给我,我的地址在我的个人资料中。
  • @ChrisHaas 刚刚向您发送了一封电子邮件,其中包含一些示例文档。正如我提到的,这些文件是使用名为 Blue Beam 而不是 Adob​​e 的应用程序创建的。这可能就是为什么它有点不同。我正在考虑使用普通的 StreamReader 打开文件并使用 RegEx 查找 Filespec 对象并使用它替换名称。如果我们知道每个链接看起来都像上面的示例,这将起作用,但显然如果有任何变化,我们可能会遇到问题。

标签: pdf itextsharp pdfsharp


【解决方案1】:

如果有人关心,我可以使用上面第一条评论中 Chris Haas 链接的代码,但修改如下:

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;
                }
            }                                
        }
    }
}   

【讨论】:

    猜你喜欢
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-24
    • 2012-12-01
    相关资源
    最近更新 更多