2015-02-11 3 views
0

Я пытаюсь добавить клейкий заметку в pdf с помощью iTextSharp. Я могу создать новую аннотацию в pdf. Но я не могу связать его как дочерний элемент уже существующей аннотации. Я скопировал большую часть свойств родительского элемента для своего дочернего элемента. Я скопировал его, проанализировав свойства ответа, вручную добавив ответ от Adobe Reader. Что мне не хватает, это свойство/IRT. Ему нужна ссылка на родительское всплывающее окно. Like/IRT 16 0 R. Ниже приведен код, который я пытаюсь.Как добавить в ответ на аннотацию с помощью iTextSharp

private void annotateReplyPdf() 
 
     { 
 
      string outputFile = @"D:\temp\temp.pdf"; 
 
      // Creating iTextSharp.text.pdf.PdfReader object to read the Existing PDF Document 
 
      using (PdfReader reader = new PdfReader(FILE_NAME)) 
 
      { 
 
       using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
 
       { 
 
        // Creating iTextSharp.text.pdf.PdfStamper object to write Data from iTextSharp.text.pdf.PdfReader object to FileStream object 
 
        using (PdfStamper stamper = new PdfStamper(reader, fs)) 
 
        { 
 
         //get page 1             
 
         PdfDictionary pageDic = reader.GetPageN(1); 
 

 
         //get annotations in page 1 
 
         PdfArray pageAnnotsArray = pageDic.GetAsArray(PdfName.ANNOTS); 
 
         if (pageAnnotsArray != null) 
 
         { 
 
          PdfDictionary curAnnotDic = pageAnnotsArray.GetAsDict(0); 
 
          PdfArray rect = curAnnotDic.GetAsArray(PdfName.RECT); 
 
          Rectangle rectangle = new Rectangle(float.Parse(rect[0].ToString()), float.Parse(rect[1].ToString()), float.Parse(rect[2].ToString()), float.Parse(rect[3].ToString())); 
 
          PdfAnnotation newAnnot = new PdfAnnotation(stamper.Writer, rectangle); 
 
          
 
          newAnnot.Title = "john.conor"; 
 
          var dtNow = DateTime.Now; 
 
          newAnnot.Put(PdfName.C, curAnnotDic.Get(PdfName.C)); 
 
          newAnnot.Put(PdfName.CONTENTS, new PdfString("Reply using prog")); 
 
          newAnnot.Put(PdfName.CREATIONDATE, new PdfDate(dtNow)); 
 

 
          // newAnnot.Put(PdfName.IRT, curAnnotDic.); stuck here 
 

 

 
          newAnnot.Put(PdfName.M, new PdfDate(dtNow)); 
 
          newAnnot.Put(PdfName.NAME, curAnnotDic.Get(PdfName.NAME)); 
 
          newAnnot.Put(PdfName.RC, curAnnotDic.Get(PdfName.RC)); 
 
          newAnnot.Put(PdfName.SUBTYPE, PdfName.TEXT); 
 
          newAnnot.Put(PdfName.SUBJECT, curAnnotDic.Get(PdfName.SUBJECT)); 
 

 
          stamper.AddAnnotation(newAnnot, 1); 
 
         } 
 
        } 
 
       } 
 
      } 
 
     }
методы я использовал не может быть точным или эффективным, так как большая часть кода были найдены методом проб и ошибок и проверка других подобных примеров (также проверить спецификацию в формате PDF). Может кто-нибудь заполнить этот код, который делает магию. примечание: SO question не содержит кода для ответа.

ответ

0

Пожалуйста, взгляните на пример AddInReplyTo.

У нас есть файл с именем hello_sticky_note.pdf который выглядит следующим образом:

PDF with a sticky note

Я собираюсь пропустить метод обнаружение аннотации заметки (в вашем вопросе, у вас уже есть этот код) , В моем примере я знаю, что эта аннотация является первой записью в массиве /Annots (аннотация с индексом 0).

Это, как я собираюсь добавить «в ответ на» аннотаций:

public void manipulatePdf(String src, String dest) throws IOException, DocumentException { 
    PdfReader reader = new PdfReader(src); 
    PdfDictionary page = reader.getPageN(1); 
    PdfArray annots = page.getAsArray(PdfName.ANNOTS); 
    PdfDictionary sticky = annots.getAsDict(0); 
    PdfArray stickyRect = sticky.getAsArray(PdfName.RECT); 
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
    PdfWriter writer = stamper.getWriter(); 
    Rectangle stickyRectangle = new Rectangle(
     stickyRect.getAsNumber(0).floatValue(), stickyRect.getAsNumber(1).floatValue(), 
     stickyRect.getAsNumber(2).floatValue(), stickyRect.getAsNumber(3).floatValue() 
    ); 
    PdfAnnotation replySticky = PdfAnnotation.createText(
      writer, stickyRectangle, "Reply", "Hello PDF", true, "Comment"); 
    replySticky.put(PdfName.IRT, annots.getAsIndirectObject(0)); 
    stamper.addAnnotation(replySticky, 1); 
    stamper.close(); 
} 

Как и вы, я получаю оригинальную аннотацию (в моем коде, он называется sticky) и я получаю положение этой аннотации (stickyRect). Я создаю объект stickyRectangle несколько иначе, чем вы (мой путь лучше, но это не имеет большого значения), и я использую этот stickyRectangle для создания нового PdfAnnotation с именем .

Это то, что у вас уже есть. Теперь я добавить недостающую часть:

replySticky.Put(PdfName.IRT, annots.GetAsIndirectObject(0)); 

В коде, вы добавить словарь аннотаций, но то, что вы на самом деле нужно, это ссылка на этот словарь.

В результате PDF выглядит hello_in_reply_to.pdf:

PDF with a sticky note and a reply to this note

+0

Спасибо. Поэтому проблема заключалась в том, что я пытался преобразовать объект PdfDictionary в косвенный объект. Вместо этого я должен был извлечь из массива Annotation сам как косвенный объект. Таким образом, отсутствующий код: newAnnot.Put (PdfName.IRT, pageAnnotsArray.GetAsIndirectObject (0)); –

+0

Свойство NM отсутствует для ответа. Я думал, он будет автоматически сгенерирован. Можно ли сохранить свойство NM во внешней БД? т.е. если пользователь редактирует PDF-файл, есть ли вероятность, что NM получит новые значения. Если ЯМ изменяет, я больше не смогу идентифицировать комментарий. Как я буду генерировать новый уникальный NM для ответа. –

+0

Запись '/ NM' определяется как * (Необязательно) Имя аннотации, текстовая строка, однозначно идентифицирующая ее среди всех аннотаций на своей странице. * Вы можете выбрать, какой из' String' вы хотите для ответа, пока нет другой аннотации с тем же именем на странице.Как только имя определено, его не следует изменять. Вы можете хранить NM в базе данных, а также идентификатор файла PDF и номер страницы. –

Смежные вопросы