如何使用 iTextSharp 添加回复注释
How to add in reply to annotation using iTextSharp
我正在尝试使用 iTextSharp 在 pdf 中添加便签回复。我能够在 pdf 中创建新注释。但是我不能 link 它作为已经存在的注释的子项。我将父级中的大部分属性复制到它的子级中。我通过分析回复的属性,手动添加来自 Adobe 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:
我正在尝试使用 iTextSharp 在 pdf 中添加便签回复。我能够在 pdf 中创建新注释。但是我不能 link 它作为已经存在的注释的子项。我将父级中的大部分属性复制到它的子级中。我通过分析回复的属性,手动添加来自 Adobe 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);
}
}
}
}
}
请查看 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: