0

TLDR; Having below issues with IText solution, and have not found a "better" option.

Project currently is finding the best way to fill forms programatically from a database. After researching heavily I found a few solutions based on the following criteria and have created a (somewhat working) solution:

  • We are currently using Access but are moving to SQL in coming months.
  • Filling multiple unique forms that are created by state agencies based on user entered. (so we can't just create our own forms.)
  • Forms are regularly updated by the agencies, but the data required remains the same, and will be stored in a database.

To solve this I researched things like IText which has a ton of tools for PDF manipulation, one small part of that is it can fill a form using AcroField technology.

I also read through a number of resources here including:

  • This description on using AcroFields and IText to fill forms
  • This older solution using Docotic
  • This even older solution with Java

    Among many other resources. I found that IText seemed to be the best supported with some examples and API that helped me create the following:

    //Creates form
    public virtual void ManipulatePdf(string src, string dst, DataGridViewRow dataRow)
    {
        //Initialize PDF document
        PdfDocument pdf = new PdfDocument(new PdfReader(src), new PdfWriter(dst));
        PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
        //form.RemoveXfaForm();
        //form.SetNeedAppearances(true);
        IDictionary fields = form.GetFormFields();
        PdfFormField toSet;
        //visits each field, fills dependant on whether dgv column exists
        foreach (string field in fields.Keys)
        {
            switch (dataGridView1.Columns.Contains(field))
            {
                case false:
                    switch (field)
                    {
                        case "Date":
                            fields.TryGetValue(field, out toSet);
                            toSet.SetValue(dateTime.ToString("MM/dd/yy"));
                            break;
                        case "Period_YY":
                            fields.TryGetValue(field, out toSet);
                            toSet.SetValue(dateTime.ToString("yy"));
                            break;
                        case "Period_YY2":
                            fields.TryGetValue(field, out toSet);
                            toSet.SetValue(dateTime.ToString("yy"));
                            break;
                        case "Period_Month_Start":
                            fields.TryGetValue(field, out toSet);
                            toSet.SetValue(dateTime.AddMonths(-1).ToString("MMMM"));
                            break;
                        case "Client_Name2":
                            fields.TryGetValue(field, out toSet);
                            toSet.SetValue(dataRow.Cells["Client_Name"].Value.ToString());
                            break;
                        default:
                            fields.TryGetValue(field, out toSet);
                            toSet.SetValue("0");
                            //this setting does not commit, issue with hybrid XFA/AcroForm
                            //.SetBackgroundColor(ColorConstants.YELLOW);
                            break;
                    }
                    break;
    
            case true:
                if (dataRow.Cells[field].Value != null && !DBNull.Value.Equals(dataRow.Cells[field].Value))
                {
                    string value = dataRow.Cells[field].Value.ToString();
                    fields.TryGetValue(field, out toSet);
                    //this value is sometimes not visable on finished form
                    toSet.SetValue(value);
                }
                break;
    
            default:
                break;
        }
    }
    //form.RemoveXfaForm();
    //pdf.GetCatalog().Remove(PdfName.Perms);
    //form.FlattenFields();
    pdf.Close();
    }
    

This solution does fill forms, but there are some very big issues with it I have not been able to solve:

  1. Changes do not always commit to form (for instance .backgroundcolor)/will show empty until user clicks into form box.
  2. Value will print but so will form box changes such as .backgroundcolor.
  3. These forms have redundant fields and AcroForm seems to have issues with parent/child field names from Adobe. (For instance it will rename any like fields)
  4. There is not an API for C# for Itext7, and I have not been able to solve these problems.

Any help, articles or insight would be appreciated, I know "open ended" questions don't get much help on here but had to try. Thank you.

Talldave
  • 11
  • 4
  • Have you tried working with Paragraphs and Cells? You will have to write a lot more code, but on the other hand you’ll have more control on the outcome – Davide Vitali Mar 20 '19 at 20:00
  • With regard to creating the entire PDF? Unfortunately the forms are not created by us so we have to be sure the data input fits into the are provided by the state agencies. Thanks for your reply. – Talldave Mar 20 '19 at 20:13
  • _There is not an API for C# for Itext7_ -> that is incorrect. However, the fact that you say this, means that you (and possibly other customers) were not able to find it. How can we improve the iText website so you can find iText 7 for .NET? – Amedee Van Gasse Mar 21 '19 at 07:37
  • @AmedeeVanGasse Thank you for your reply, I had gone to this link to find the API: https://itextpdf.com/en/resources/api-documentation but when clicking the link under "Visit or Itext7 API repository" it only goes to the Java - VB API, which while usually workable into C# there are some differences I was unable to reconcile especially in itextpdf.forms.fields. Also when searching, the only pages that come up are the java API's. Maybe I am just dull but that's what I was looking through. Thank you! – Talldave Mar 21 '19 at 17:05
  • @AmedeeVanGasse As far as documentation, examples are generally Java first which is understandable, but .NET beyond the actual introduction chapter examples is pretty sparse. Part of it may be that the code I used the API for isn't working, and I assumed that could be due to differences there. Thanks again. – Talldave Mar 21 '19 at 17:13
  • Thank you for the info. I first thought that you didn't find the C# download at all. So, to summarize, you did find the tutorials, which are available in both Java and C#, but when you were looking for the API documentation, you only found the Javadocs. I actually have a question for you: what is, in the .NET world, the counterpart of Javadocs? Something that generates API documentation, based on comments that are in the source code. If such software exists then it could be automatically generated. But I haven't heard of it. – Amedee Van Gasse Mar 21 '19 at 22:22
  • 1
    I guess the real issue with the Javadocs vs C# is that some of the API information seems to be incorrect for use in C#, or at least the recommended solutions. I am working with IText support now to try and resolve the problems but I am starting to think that there is no resolution, and I will need to find a different way to do this. Maybe it's time to swap to Java! :) – Talldave Mar 22 '19 at 17:21

0 Answers0