Julien
Julien

Reputation: 119

How to save PDF using ITextSharp?

I working with PDF annotations using ITextSharp. I was able to add annotations pretty smoothly. But now I'm trying to edit them. It looks like my PdfReader object is actually updated. But for some reason I can't save it. As shown in the snippet below, I try to get the byte array from using a stamper. The byte array is only 1 byte longer than the previous version no matter how long is the annotation. And when I open the PDF saved on the file system, I still have the old annotation...

    private void UpdatePDFAnnotation(string title, string body)
    {
        byte[] newBuffer;
        using (PdfReader pdfReader = new PdfReader(dataBuffer))
        {

            int pageIndex = 1;
            int annotIndex = 0;

            PdfDictionary pageDict = pdfReader.GetPageN(pageIndex);
            var annots = pageDict.GetAsArray(PdfName.ANNOTS);
            if (annots != null)
            {
                PdfDictionary annot = annots.GetAsDict(annotIndex);
                annot.Put(PdfName.T, new PdfString(title));
                annot.Put(PdfName.CONTENTS, new PdfString(body));
            }

            // ********************************
            // this line shows the new annotation is in here. Just have to save it somehow !!
            var updatedBody = pdfReader.GetPageN(pageIndex).GetAsArray(PdfName.ANNOTS).GetAsDict(0).GetAsString(PdfName.CONTENTS);
            Debug.Assert(newBody == updatedBody.ToString(), "Annotation body should be equal");


            using (MemoryStream outStream = new MemoryStream())
            {
                using (PdfStamper stamp = new PdfStamper(pdfReader, outStream, '\0', true))
                {
                    newBuffer = outStream.ToArray();
                }
            }

           }
           File.WriteAllBytes( @"Assets\Documents\AnnotedPdf.pdf", newBuffer);
        }

Any idea what's wrong with my code?

Upvotes: 0

Views: 6693

Answers (2)

Julien
Julien

Reputation: 119

Allright, I finally got it to work. The trick was the two last parameter in the PdfStamper instantiation. I tried it before with only 2 parameters and ended up with a corrupted file. Then I tried again and now it works... here's the snippet

    private void UpdatePDFAnnotation(string title, string body)
    {
        using (PdfReader pdfReader = new PdfReader(dataBuffer))
        {
            PdfDictionary pageDict = pdfReader.GetPageN(pageIndex);
            var annots = pageDict.GetAsArray(PdfName.ANNOTS);

            PdfDictionary annot = annots.GetAsDict(annotIndex);
            annot.Put(PdfName.T, new PdfString(title));
            annot.Put(PdfName.CONTENTS, new PdfString(body));

            using (MemoryStream ms = new MemoryStream())
            {
                PdfStamper stamp = new PdfStamper(pdfReader, ms);    
                stamp.Dispose();                
                dataBuffer = ms.ToArray();
            }
        }
    }

Upvotes: 0

mkl
mkl

Reputation: 96029

PdfStamper does much of the writing at the time it is being closed. This implicitly happens at the end of its using block. But you retrieve the MemoryStream contents already in that block. Thus, the PDF is not yet written to the retrieved byte[].

Instead either explicitly close the PdfStamper instance before retrieving the byte[]:

using (PdfStamper stamp = new PdfStamper(pdfReader, outStream, '\0', true))
{
    stamp.Close();
    newBuffer = outStream.ToArray();
}

or retrieve the byte[] after that using block:

using (PdfStamper stamp = new PdfStamper(pdfReader, outStream, '\0', true))
{
}
newBuffer = outStream.ToArray();

Upvotes: 1

Related Questions