2013-07-12 123 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; 
       } 
      }         
     } 
    } 
}