填写PDF表单的问题。我应该将C#与IText AcroFields一起使用,以编程方式从数据库填写表单吗?还是这个解决方案过时了?

时间:2019-03-20 19:53:40

标签: c# itext itext7 acrofields

TLDR; IText解决方案存在以下问题,并且找不到“更好”的选项。

当前,项目正在寻找从数据库中以编程方式填写表格的最佳方法。经过大量研究,我发现了一些基于以下标准的解决方案,并创建了(某种程度上可行的)解决方案:

  • 我们目前正在使用Access,但在接下来的几个月中将转向SQL。
  • 填写国家机构根据输入的用户创建的多个唯一表单。 (所以我们不能只创建自己的表单。)
  • 代理商会定期更新表格,但所需的数据保持不变,并将存储在数据库中。

为解决这个问题,我研究了IText之类的东西,其中有大量的PDF操作工具,其中一小部分可以使用AcroField技术填写表格。

我还在这里阅读了许多资源,包括:

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

    还有许多其他资源。我发现通过一些示例和API可以最好地支持IText,这有助于我创建以下内容:

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

此解决方案确实可以填写表格,但是有一些非常大的问题我无法解决:

  1. Changes do not always commit to form (for instance .backgroundcolor)/will show empty until user clicks into form box.
  2. 将打印值,但也会更改表格框,例如.backgroundcolor。
  3. 这些表单具有多余的字段,并且AcroForm似乎在Adobe的父/子字段名称中存在问题。 (例如,它将重命名任何类似的字段)
  4. 没有用于Itext7的C#API,并且我无法解决这些问题。

任何帮助,文章或见解将不胜感激,我知道“开放式”问题在这里没有太多帮助,但必须尝试。谢谢。

0 个答案:

没有答案