HonChung Liau
HonChung Liau

Reputation: 21

Copy annotations

I have a source PDF with some Free Text Annotations.

I would like to perform a mail merge like function on PDF. I would like to make a copy of the PDF and replace the Free Text Annotation based on some text replacement method.

For simplicity, I have a program that takes the annotations and add "LHC" behind it. Alas, the copy works, but the annotations remains unchanged.

I would have tried to use PdfAnnotation however, I am unsure how to convert from the PdfDictionary to PdfAnnotation

See my code below

string oldFile = "C:\\Temp\\oldFile.pdf";
string newFile = "C:\\Temp\\newFile.pdf";

// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);

// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfCopy writer = new PdfCopy(document,fs);
document.Open();

// the pdf content
PdfContentByte cb = writer.DirectContent;

// adding Free Text Annotation 

for (int pg = 1; pg < reader.NumberOfPages; pg++)
{
    PdfDictionary pageDict = reader.GetPageN(pg);
    PdfArray annotArray = pageDict.GetAsArray(PdfName.ANNOTS);
    for (int i = 0; i < annotArray.Size; ++i)
    {
        PdfDictionary curAnnot = annotArray.GetAsDict(i);
        PdfName contents = new PdfName("Contents");
        PdfString str = curAnnot.GetAsString(contents);
        String newString = str.ToString() + "LHC";
        curAnnot.Remove(contents);
        curAnnot.Put(contents, new PdfString(newString));
    }

    PdfImportedPage page = writer.GetImportedPage(reader, pg);
    // PdfImportedPage pageOut = writer.destinationPdfReader(reader, pg);
    //cb.AddTemplate(page, 0, 0);
    writer.AddPage(page);
    PdfAnnotation annot = new PdfAnnotation(writer, new Rectangle(0, 0));
    writer.AddAnnotation(annot);
}

document.Close();
fs.Close();
writer.Close();
reader.Close();

Upvotes: 0

Views: 2256

Answers (1)

HonChung Liau
HonChung Liau

Reputation: 21

References: http://itextsharp.10939.n7.nabble.com/How-to-edit-annotations-td3352.html

(There is another link in stackoverflow, that I can't find, when I find it I will add it here)

The steps:

Step 1. Create a stamper from a reader.

Step 2. Read all the annotations

Step 3. Delete a set of keys and as a fallback any dictionary items

You now have performed an edit/copy of the annotation and changed the values.

The following is the code:

// Step 1. Create the stamper

        string oldFile = "C:\\Temp\\oldFile.pdf";
        string newFile = "C:\\Temp\\newFile.pdf";
        // open the reader
        PdfReader reader = new PdfReader(oldFile);
        Rectangle size = reader.GetPageSizeWithRotation(1);
        Document document = new Document(size);

        // open the writer

        // remember to set the page size before opening document
        // otherwise the page is already set.
        /* chapter02/HelloWorldMetadata.java */
        document.Open();

        // the pdf content
        // cb does not work with stamper 


        // create the new pagez and add it to the pdf
        // this segment of code is meant for writer
        FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.ReadWrite);


        PdfStamper writer = new PdfStamper(reader, fs, reader.PdfVersion, false);

        for (int pg = 1; pg < reader.NumberOfPages; pg++)
        {

            // taken from http://itextsharp.10939.n7.nabble.com/How-to-edit-annotations-td3352.html

            PdfDictionary pagedic = reader.GetPageN(pg);
            PdfArray annotarray = (PdfArray)PdfReader.GetPdfObject(pagedic.Get(PdfName.ANNOTS));

            if (annotarray == null || annotarray.Size == 0)
                continue;

// step 2. read all the annotations

            foreach (PdfIndirectReference annot in annotarray.ArrayList)
            {
                PdfDictionary annotationDic = (PdfDictionary)PdfReader.GetPdfObject(annot);
                PdfName subType = (PdfName)annotationDic.Get(PdfName.SUBTYPE);
                if (subType.Equals(PdfName.TEXT) || subType.Equals(PdfName.FREETEXT))
                {

// 3. Change values of different properties of a certain annotation and delete a few keys & dictionaries

                    annotationDic.Put(PdfName.CONTENTS, new PdfString("These are changed contents", PdfObject.TEXT_UNICODE));
                }
                PdfString contents = annotationDic.GetAsString(PdfName.CONTENTS);
                if (contents != null)
                {
                    String value = contents.ToString();
                    annotationDic.Put(PdfName.CONTENTS, new PdfString(value));
                    annotationDic.Remove(PdfName.AP);
                    List<PdfName> tobeDel = new List<PdfName>();
                    foreach (PdfName key in annotationDic.Keys)
                    {
                        if (key.CompareTo(PdfName.AP) == 0 ||
                            key.CompareTo(PdfName.RC) == 0 ||
                            annotationDic.Get(key).IsDictionary())
                        {
                            tobeDel.Add(key);
                        }
                    }
                    foreach (PdfName key in tobeDel)
                    {
                        annotationDic.Remove(key);
                    }
                }
                writer.MarkUsed(annotationDic);

            }
            if ((pg + 1) < reader.NumberOfPages)
            {
                document.NewPage();
            }
        }


        // close the streams and voilá the file should be changed :)

        writer.Close();
        reader.Close();

Upvotes: 2

Related Questions