如何使用 iTextSharp 添加回复注释

How to add in reply to annotation using iTextSharp

我正在尝试使用 iTextSharp 在 pdf 中添加便签回复。我能够在 pdf 中创建新注释。但是我不能 link 它作为已经存在的注释的子项。我将父级中的大部分属性复制到它的子级中。我通过分析回复的属性,手动添加来自 Adob​​e Reader 的回复来复制它。我缺少的是 属性 /IRT。它需要对父弹出窗口的引用。像 /IRT 16 0 R。 下面是我正在尝试的代码。

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 没有提供答案代码。

请查看 AddInReplyTo 示例。

我们有一个名为 hello_sticky_note.pdf 的文件,如下所示:

我将跳过检测便利贴注释的方法(在你的问题中,你已经有了这段代码)。在我的示例中,我知道此注释是 /Annots 数组中的第一个条目(索引为 0 的注释)。

这就是我要添加 "in reply to" 注释的方式:

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.

这就是你已经拥有的。现在我添加缺失的部分:

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

在您的代码中,您添加了注释字典,但您实际需要的是对该字典的引用。

生成的 PDF 看起来像 hello_in_reply_to.pdf: