How do I mark/unmark, write as Accepted/Rejected/Cancelled a text annotation using iTextSharp C#

99封情书 提交于 2019-12-24 05:54:44

问题


I'm working with iTextSharp on Visual Studio. I created a Pdfannotation like that:

PdfAnnotation annotation = PdfAnnotation.CreateText(stamper.Writer, rect, "Author", "I write my text", true, "New Paragraph");
stamper.AddAnnotation(annotation, 1);

So my annotation contents a text "I write my text". When I go on Adobe Acrobat Reader to open my pdf, and when I click on the button "Comment" to see all the comments I wrote on my pdf, I see my comment and near to my comment "I write my text", I see a little square that I can check or uncheck. This is a little Checkbox which was automatically created when I created my Pdf annotation. I didn't create it by myself.

I would like to check or uncheck this little checkbox using iTextSharp.

I thought about doing that, but it doesn't work :

  RadioCheckField checkbox = new RadioCheckField(stamper.Writer, rect, "bonjour", "on");
        checkbox.CheckType = RadioCheckField.TYPE_CHECK;
        checkbox.Checked = true;
        PdfFormField field = checkbox.CheckField;

        annotation.Put(PdfName.A, field);

Does anyone know how to do it ?

Thank you a lot!

Have a good day! :)


回答1:


The question was somewhat confusion because of the terminology "check/uncheck" in the context of a text (or Sticky Note) annotation. The correct terminology would have been: How to I mark/unmark a text annotation?

Checking/unchecking immediately makes us think about check boxes, but the following screen shot shows what is meant when we talk about marking a text annotation:

Marking a text annotation isn't a matter of checking a check box. Marking a text annotation is done by adding a hidden "In Reply To" (IRT) annotation. See How to add an "In Reply To" annotation? on the official site for more information about "In Reply To" annotations.

I've adapted the AddInReplyTo example with the AddMarked as result:

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);
    PdfDictionary popup = annots.getAsDict(1);
    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, "Bruno", "Marked set by Bruno", false, "Comment");
    replySticky.put(PdfName.IRT, annots.getAsIndirectObject(0));
    replySticky.put(PdfName.STATE, new PdfString("Marked"));
    PdfNumber n = sticky.getAsNumber(PdfName.F);
    replySticky.put(PdfName.F, new PdfNumber(n.intValue() | PdfAnnotation.FLAGS_HIDDEN));
    replySticky.put(new PdfName("StateModel"), new PdfString("Marked"));
    stamper.addAnnotation(replySticky, 1);
    stamper.close();
}

The example is in Java, but it should be fairly easy to adapt it to C#. It's important to know that marking the original annotation sticky is done by adding an extra annotation replySticky. The difference with an ordinary IRT annotation, is that we are going to hide the annotation by adding FLAGS_HIDDEN to the flags of the annotation. We also set the /State to Marked and the /StateModel to Marked.

This code turns hello_sticky_note.pdf into hello_marked.pdf as was requested, but there's a catch! The check box will only be visible if you are logged in as user "Bruno". This check box is for personal use only.

If you want others to see a review status, you shouldn't use the "Marked" feature. Instead you should use "Review". This is poorly documented in ISO-32000. See the table with title "Additional entries specific to a text annotation":

This table refers to the table with title "Annotation States":

We have used the combination StateModel = Marked; State = Marked, which means that the annotation has been marked by the user. I didn't find any reference in the spec that this mark is only visible on the machine of the user who marked the document.

After discovering this, I've created the AddAccepted example:

PdfAnnotation replySticky = PdfAnnotation.createText(
        writer, stickyRectangle, "Bruno", "Accepted by Bruno", false, "Comment");
replySticky.put(PdfName.IRT, annots.getAsIndirectObject(0));
replySticky.put(PdfName.STATE, new PdfString("Accepted"));
PdfNumber n = sticky.getAsNumber(PdfName.F);
replySticky.put(PdfName.F, new PdfNumber(n.intValue() | PdfAnnotation.FLAGS_HIDDEN));
replySticky.put(new PdfName("StateModel"), new PdfString("Review"));
stamper.addAnnotation(replySticky, 1);
stamper.close();

This example is identical to what we had before, except that we now use the combination: StateModel = Review; State = Accepted. As you can tell from the "Annotation states" table, other possible options for the State are "Rejected", "Cancelled", "Completed" and "None" (which is the default value).

The result looks like this:

As you can see, a green check mark appears in the comments panel. It shows "Bruno Accepted" on a computer where the logged in user isn't Bruno. You can check this for yourself here: hello_accepted.pdf



来源:https://stackoverflow.com/questions/37652181/how-do-i-mark-unmark-write-as-accepted-rejected-cancelled-a-text-annotation-usi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!