2017-04-07 23 views
1

使用iTextJava中更改縮放級別的代碼在iText home page中給出。我想將它轉換爲C#。無數小時後,我終於重寫了代碼,只是發現它沒有改變任何鏈接。這意味着我一定犯了錯誤。以PDF格式更改所有鏈接目標中的縮放級別

編輯:

按照要求,請看看在simple PDF example

我的代碼如下:

using (var reader = new PdfReader(input)) 
{ 
    using (var stamper = new PdfStamper(reader, ms)) 
    { 
     for (int i = 1; i <= reader.NumberOfPages; i++) 
     { 
      // Get a page of a PDF page 
      PdfDictionary page = reader.GetPageN(i); 

      // Get all the annotations of page i 
      PdfArray annotsArray = page.GetAsArray(PdfName.ANNOTS); 

      // If page does not have annotations 
      if (annotsArray == null) 
      { 
       continue; 
      } 

      // For each annotation 
      for (int j = 0; j < annotsArray.Size; j++) 
      { 
       // for current annotation 
       PdfDictionary annotation = annotsArray.GetAsDict(j); 

       // test if it is LINK 
       PdfDictionary annotationAction = annotation.GetAsDict(PdfName.A); 
       if (annotationAction == null || PdfName.LINK.Equals(annotationAction.Get(PdfName.S))) 
       { 
        PdfArray d = annotation.GetAsArray(PdfName.DEST); 
        if (d != null && d.Length == 5 && PdfName.XYZ.Equals(d.GetAsName(1))) 
        { 
         d[4] = new PdfNumber(150); 
        } 
       } 

      } 
     } 
    } 
} 
在Java中

原始代碼要短得多:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException { 
     PdfReader reader = new PdfReader(src); 
     PdfDictionary page = reader.getPageN(11); 
     PdfArray annots = page.getAsArray(PdfName.ANNOTS); 
     for (int i = 0; i < annots.size(); i++) { 
      PdfDictionary annotation = annots.getAsDict(i); 
      if (PdfName.LINK.equals(annotation.getAsName(PdfName.SUBTYPE))) { 
       PdfArray d = annotation.getAsArray(PdfName.DEST); 
       if (d != null && d.size() == 5 && PdfName.XYZ.equals(d.getAsName(1))) 
        d.set(4, new PdfNumber(0)); 
      } 
     } 
     PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
     stamper.close(); 
    } 

修訂EDIT 2

感謝@mkl我已經想出了與解決方案。

for (int i = 1; i <= reader.NumberOfPages; i++) 
{ 
    PdfDictionary page = reader.GetPageN(i); 

    PdfArray annotsArray = page.GetAsArray(PdfName.ANNOTS); 

    if (annotsArray == null) 
    { 
     continue; 
    } 

    for (int j = 0; j < annotsArray.Size; j++) 
    { 
     PdfDictionary annotation = annotsArray.GetAsDict(j); 

     PdfDictionary annotationAction = annotation.GetAsDict(PdfName.A); 
     if (PdfName.GOTO.Equals(annotationAction.Get(PdfName.S))) 
     { 
      PdfArray d = annotationAction.GetAsArray(PdfName.D); 
      if (d != null) 
      { 
       Console.WriteLine(d[4]); 
       d[4] = new PdfNumber(1.20); 
      } 

     } 

    } 
}  
+0

您的代碼僅處理** XYZ **類型的目標。可能你的例子pdf使用其他類型的目的地。因此,請分享您的測試pdf。 – mkl

+0

@mkl我剛剛添加了一個示例文件。 – menteith

+0

*'PdfArray d = annotation.GetAsArray(PdfName.GOTO)'* - 這在兩種方式上是錯誤的:您想要名爲** D **的數組,而不是名爲** GoTo **的數組,並且此數組包含在'annotationAction'中,不直接在'annotation'中。因此:'PdfArray d = annotationAction.GetAsArray(PdfName.D)' – mkl

回答

1

如果你看一下鏈接註釋的規範,你會看到

一個 dictionar y (可選; PDF 1.1)激活鏈接註釋時應執行的操作(請參閱12.6「操作」)。

站Dest 陣列,名稱或 字節串 (可選;如果一個條目存在不允許)當註釋被激活時將被顯示的目的地(見12.3.2,「目的地」)。

(表173 - 特定於鏈接註釋附加條目 - ISO 32000-1)

即原來的Java代碼和你的端口只處理一種鏈接註釋,這種使用目的地條目。

檢查您的樣本PDF,但是,人們發現鏈接註釋與一個項,例如

/A << 
    /D [ 1 /XYZ 0.000001 842 0.724 ] 
    /S /GoTo 
>> 

因此,您的代碼必須考慮所有可能的選項。特別是如果你操作PDF反而定義的目的地萌發的的一個 ction,就必須正確處理d estination的一個 ction,而不是僅僅是不存在的鏈接的目的地

+0

感謝您的指導,我可以找到'GoTo'行動(呃,我花了一些時間,但我擁有它。)請問我該如何改變縮放係數? – menteith

+0

任何對實際解決方案感興趣的人都可以看到我更新的帖子。 – menteith

1

不知道如果您使用的是不同的PDF作爲輸入,但使用the source PDF from the iText web site你的問題掛鉤的例子,這對我的作品,並改變縮放級別的所有鏈接文檔縮放級別:

using (reader) 
{ 
    PdfDictionary page = reader.GetPageN(11); 
    PdfArray annots = page.GetAsArray(PdfName.ANNOTS); 
    for (int i = 0; i < annots.Size; i++) 
    { 
     PdfDictionary annotation = annots.GetAsDict(i); 
     if (PdfName.LINK.Equals(annotation.GetAsName(PdfName.SUBTYPE))) 
     { 
      PdfArray d = annotation.GetAsArray(PdfName.DEST); 
      if (d != null && d.Size == 5 && PdfName.XYZ.Equals(d.GetAsName(1))) 
       d.Set(4, new PdfNumber(0)); 
     } 
    } 
    using (var stream = new MemoryStream()) 
    { 
     using (var stamper = new PdfStamper(reader, stream)) { } 
     File.WriteAllBytes(outputFile, stream.ToArray()); 
    } 
} 
+0

非常感謝您的幫助!不幸的是,你的代碼不適用於我的測試文件。我不確定,但我認爲它使用** XYZ **作爲跳轉到下一頁的技術。 – menteith

相關問題