how to make pdf annotation as read only using itext?

3k views Asked by At

I am trying to make a program that multiple users can share one PDF document , and every one can put his comments on the PDF using add sticky note without changing/modifying other notes. For example , The program will transfer that PDF file to another person for review and checking , the reviewer will put his comments on the PDF and send it to Approver person . The approver can't edit reviewer comments and change it at all , he can add new sticky note to it for his comments.

if I use the security on the PDF ( ~ PdfWriter.AllowModifyAnnotations ) , I will disable entering new sticky note.

is there any solution for that ?

please help me and thanks in advance

1

There are 1 answers

1
mkl On

PDF annotation objects can have flags; one of these flags is a read-only flag. Thus, you only have to iterate over all annotations on all pages and set their respective read-only flag.


In iText 5.5.x this can be done like this:

PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream);

for (int page = 1; page <= reader.getNumberOfPages(); page++)
{
    PdfDictionary pageDictionary = reader.getPageN(page);
    PdfArray annotationArray = pageDictionary.getAsArray(PdfName.ANNOTS);
    if (annotationArray == null)
        continue;
    for (PdfObject object : annotationArray)
    {
        PdfObject directObject = PdfReader.getPdfObject(object);
        if (directObject instanceof PdfDictionary)
        {
            PdfDictionary annotationDictionary = (PdfDictionary) directObject;
            PdfNumber flagsNumber = annotationDictionary.getAsNumber(PdfName.F);
            int flags = flagsNumber != null ? flagsNumber.intValue() : 0;
            flags |= PdfAnnotation.FLAGS_READONLY;
            annotationDictionary.put(PdfName.F, new PdfNumber(flags));
        }
    }
}

stamper.close();

(iText 5 MarkAnnotationReadOnly.java)


In iText 7.0.x it can be done like this

try (   PdfReader pdfReader = new PdfReader(resourceStream);
        PdfWriter pdfWriter = new PdfWriter(outputStream);
        PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter) )
{
    for (int page = 1; page <= pdfDocument.getNumberOfPages(); page++)
    {
        PdfPage pdfPage = pdfDocument.getPage(page);
        for (PdfAnnotation pdfAnnotation : pdfPage.getAnnotations())
        {
            pdfAnnotation.setFlag(PdfAnnotation.READ_ONLY);
        }
    }
}

(iText 7 MarkAnnotationReadOnly.java)

Only the kernel iText 7 artifact is required.