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();
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();