FormDataSubmit.cs
// 完毕:
using System.Drawing;
using System.IO;
using System.Linq;
using System.Xml;
using System.Text;
using System.Collections.Generic;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Pdf.AcroForms;
using GrapeCity.Documents.Pdf.Actions;
using GrapeCity.Documents.Pdf.Annotations;
using GrapeCity.Documents.Text;

namespace DsPdfWeb.Demos
{
    // 此示例创建一个可以提交到服务器的 AcroForm PDF。
    // 然后服务器使用(GcDocs.Pdf v3 中的新功能)GcPdfDocument.ImportFormDataFromCollection()
    // 方法将提交的数据导入到包含类似结构的 PDF 中
    // PDF表单,并将填写有用户提供的数据的表单发送回客户端。
    // 
    // 请注意,生成的 PDF 包含已填写的表单字段
    // 显示在客户端浏览器的默认 PDF 查看器中。
    // 
    // 此示例​​类似于现已过时的FormSubmitXml示例,
    // 但服务器端要简单得多,因为它使用新的 ImportFormDataFromCollection()
    // 接受与从客户端表单发送数据的方式非常相似的数据结构的方法,
    // 因此几乎不需要任何代码来操作该数据。
    // 另请参阅FormSubmit 示例。
    public class FormDataSubmit
    {
        public int CreatePDF(Stream stream)
        {
            var doc = new GcPdfDocument();
            var page = doc.NewPage();

            var rc = Common.Util.AddNote(
                "填写表单中的字段,然后单击“提交”将其发送回服务器。" +
                "",
                page);

            var g = page.Graphics;
            var tf = new TextFormat() { Font = StandardFonts.Times, FontSize = 14 };
            var ip = new PointF(72, rc.Bottom + 36);
            float fldOffset = 72 * 2 + 46;
            float fldHeight = tf.FontSize * 1.2f;
            float dY = 32;

            // 文本域:
            g.DrawString("First name:", tf, ip);
            var fldFirstName = new TextField() { Name = "FirstName", Value = "John" };
            fldFirstName.Widget.Page = page;
            fldFirstName.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight);
            fldFirstName.Widget.DefaultAppearance.Font = tf.Font;
            fldFirstName.Widget.DefaultAppearance.FontSize = tf.FontSize;
            doc.AcroForm.Fields.Add(fldFirstName);
            ip.Y += dY;

            // 文本域:
            g.DrawString("Last name:", tf, ip);
            var fldLastName = new TextField() { Name = "LastName", Value = "Smith" };
            fldLastName.Widget.Page = page;
            fldLastName.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight);
            fldLastName.Widget.DefaultAppearance.Font = tf.Font;
            fldLastName.Widget.DefaultAppearance.FontSize = tf.FontSize;
            doc.AcroForm.Fields.Add(fldLastName);
            ip.Y += dY;

            // 复选框:
            g.DrawString("Subscribe to Mailing List:", tf, ip);
            var fldCheckbox = new CheckBoxField() { Name = "Subscribe", Checked = true };
            fldCheckbox.Widget.Page = page;
            fldCheckbox.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, fldHeight, fldHeight);
            doc.AcroForm.Fields.Add(fldCheckbox);
            ip.Y += dY;

            // 多行文本框:
            g.DrawString("Additional information:", tf, ip);
            var fldAdditionalInfo = new TextField() { Name = "AdditionalInfo", Multiline = true };
            fldAdditionalInfo.Widget.Page = page;
            fldAdditionalInfo.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72 * 3, fldHeight * 2);
            fldAdditionalInfo.Widget.DefaultAppearance.Font = tf.Font;
            fldAdditionalInfo.Widget.DefaultAppearance.FontSize = tf.FontSize;
            doc.AcroForm.Fields.Add(fldAdditionalInfo);
            ip.Y += dY * 2;

            // 提交表单按钮:
            var btnSubmit = new PushButtonField();
            btnSubmit.Widget.Rect = new RectangleF(ip.X + fldOffset, ip.Y, 72, fldHeight);
            btnSubmit.Widget.ButtonAppearance.Caption = "Submit";
            btnSubmit.Widget.Highlighting = HighlightingMode.Invert;
            btnSubmit.Widget.Page = page;

            // 提交网址:
            btnSubmit.Widget.Activate = new ActionSubmitForm("/Samples/HandleFormDataSubmit");
            doc.AcroForm.Fields.Add(btnSubmit);

            // 重置表单按钮:
            var btnReset = new PushButtonField();
            btnReset.Widget.Rect = new RectangleF(ip.X + fldOffset + 72 * 1.5f, ip.Y, 72, fldHeight);
            btnReset.Widget.ButtonAppearance.Caption = "Reset";
            btnReset.Widget.Highlighting = HighlightingMode.Invert;
            btnReset.Widget.Page = page;
            btnReset.Widget.Activate = new ActionResetForm();
            doc.AcroForm.Fields.Add(btnReset);
            ip.Y += dY;

            // 完毕:
            doc.Save(stream);
            return doc.Pages.Count;
        }

        // 注意:下面的代码由 Web 示例浏览器控制器在表单时使用
        // 提交此示例准备的内容,它不是由 CreatePDF() 方法直接调用的。

        // 创建一个 GcPdfDocument,将 AcroForm PDF 加载到其中,并用数据填充它
        // 使用 GcPdfDocument.ImportFormDataFromCollection() 方法。
        // 
        // 当此样本准备表单时,样本控制器将调用此方法
        // 由用户提交。控制器方法将 IFormCollection 转换为它
        // 接收数组或键值对,其中键是字段名称,值是
        // 字符串值列表,然后调用此方法将值导入到
        // 兼容 ImportFormXML.pdf PDF 表单。然后将该表格发送回客户。
        // 
        // 调用此方法的控制器代码如下所示:
        // 
        // public IActionResult HandleFormDataSubmit(IFormCollection fields)
        // {
        //   var values = fields.ToList();
        //   var fieldValues = values.Select(kvp_ => new KeyValuePair<string, IList<string>>(kvp_.Key, kvp_.Value.ToArray())).ToArray();
        //   var ms = Samples.FormDataSubmit.ImportFormData(fieldValues);
        //   var result = new FileStreamResult(ms, "application/pdf");
        //   return result;
        // }
        public static Stream ImportFormData(KeyValuePair<string, IList<string>>[] fieldValues)
        {
            var pdf = new GcPdfDocument();
            using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "ImportFormFromCollection.pdf"));
            // 加载兼容的空表单:
            pdf.Load(fs);
            // 导入提交的数据:
            pdf.ImportFormDataFromCollection(fieldValues);
            // 完毕:
            var outMs = new MemoryStream();
            pdf.Save(outMs);
            outMs.Seek(0, SeekOrigin.Begin);
            return outMs;
        }
    }
}