0
votes

I'm generating a new PDF from an existing template that has been created in LibreOffice. It contains one Text Box.

After the code compiles and successfully saves the PDF to a new file, if I open the newly created document in Acrobat Reader XI, it renders correctly, but, even if I don't modify the final document, upon closing the document, it asks "Do you want to save changes to "filename.pdf" before closing?"

I've read other posts on StackOverflow and their official site (iTextSharp), and found a solution, that maybe I'm implementing in a wrongful manner.

    public string spdftemplate = @"C:\test\input.pdf";
    public string newFile = @"C:\test\output.pdf";

    private void FillFormsProperly()
    {

        PdfReader reader = new PdfReader(spdftemplate);
        byte[] bytes;
        using (MemoryStream ms = new MemoryStream())
        {
            PdfStamper stamper = new PdfStamper(reader, ms);

            #region ForTesting
            //PdfContentByte cb = stamper.GetOverContent(1);
            //ColumnText ct = new ColumnText(cb);
            //ct.SetSimpleColumn(100, 100, 500, 200);
            //ct.AddElement(new Paragraph("This was added using ColumnText"));
            //ct.Go();
            #endregion ForTesting

            AcroFields pdfFormFields = stamper.AcroFields;

            foreach (DictionaryEntry de in reader.AcroFields.Fields)
            {
                pdfFormFields.SetField(de.Key.ToString(), "test"); //"Text Box 1"
            }

            //string sTmp = "W-4 Completed for " + pdfFormFields.GetField("Text Box 1");
            //MessageBox.Show(sTmp, "Finished");

            //Flush the PdfStamper's buffer
            stamper.FormFlattening = true;
            stamper.Close();
            //Get the raw bytes of the PDF
            bytes = ms.ToArray();

        }

        //Do whatever you want with the bytes
        //Below I'm writing them to disk 
        using (FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write, FileShare.None))
        {
            fs.Write(bytes, 0, bytes.Length);
        }
    }

The best answer I found was this : creating a pdf from a template in itextsharp and outputting as content disposition.

The above code is my (copy-paste more or less) implementation.

It's obvious that the file is corrupted (but still readable), how can I fix this ?

1
I can attach the template, if needed.StefanS
Please provide both the input template and the output document.mkl
It seems that LibreOffice is guilty, the input PDF also prompts the save file dialog.StefanS

1 Answers

1
votes

Your input.pdf contains a form field and the flag /NeedAppearances true. Your output.pdf does not contain a field anymore (obviously... you flattened the form after all) but it still contains that flag /NeedAppearances true.

This flag tells the PDF viewer (Acrobat Reader) to generate appearance streams for some form fields. Thus, the Reader inspects all fields to create the appearances where necessary. Afterwards it removes the flag. Because of this the document then is changed; even if there are no fields, at least the flag removal is a change.

This reminds of an iText issue which has been fixed in February last year in iText:

In some cases, Adobe Reader X asks if you want to "save changes" after closing a flattened PDF form. This was due to the presence of some unnecessary entries in the /AcroForm dictionary (for instance added when the form was created with OOo).

(iText revision 5089, February 29th, 2012, blowagie)

This change has been ported to iTextSharp in iTextSharp revision 323, March 3rd, 2012, psoares33.

Thus, you might want to update the iTextSharp version you use.