2013-07-12 75 views
1

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

我们尝试过使用iTextSharp和PdfSharp来改变链接,但是很难找到合适的对象。下面显示了带有两个链接的示例pdf文件的内容。您可以看到对象12是一个链接,引用对象21和对象21使用对象20中的引用打开一个新窗口。Filespec类型的对象20包含链接的pdf文件夹名称/ 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更改“文件夹名称”和“文件夹名称-2”的一些其他任意文件夹路径?

+0

这是任何帮助吗? http://stackoverflow.com/a/8141831/231316 –

+0

这实际上是我开始。我试图调整你提供的代码,使其工作,但不能。正如您在提供的PDF文档中看到的那样,没有URI引用。 Annotation引用一个GoToR对象,然后引用一个Filespec对象。这是一个不同于你提供代码的链接结构。 –

+0

不幸的是,我生产的PDF看起来像这样的问题。我可以使用'A'动作创建一个链接到文件的文件,或者我可以创建一个普通的'FileSpec',但是对于我来说我无法创建一个指向'FileSpec'的动作。你能提供任何示例文件吗?或者你可以通过电子邮件发送给我,我的地址在我的个人资料中。 –

回答

2

万一有人关心,我能够使用由克里斯·哈斯链接的代码在上面的第一个评论,但它修改如下:

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