当前位置: 首页 > 知识库问答 >
问题:

自动填写I-9 PDF XFA表单

楚雪松
2023-03-14

考虑到字段名称结构可能发生了变化,我尝试像第一次那样阅读format/fields。(代码如下)。但是,现在它告诉我没有要读取的字段(acrofields.fields.count=0)。

Private Sub ListFieldNames(pdfTemplate As String)
    Dim pdfTemplate As String = "c:\Temp\PDF\fw4.pdf"
    Dim pdfReader As PdfReader = New PdfReader(pdfTemplate)
    Dim de As KeyValuePair(Of String, iTextSharp.text.pdf.AcroFields.Item)

    For Each de In pdfReader.AcroFields.Fields
        Console.WriteLine(de.Key.ToString())
    Next
End Sub

所以,我开始做一些搜索,并找到了参考另一种类型的PDF结构,他们可以切换到;XFA.老实说,我还没有找到任何令人满意的文档/示例,但我确实找到了一些代码,看起来应该可以在XFA PDF的结构中阅读。(代码如下)。我尝试了两种不同的方法。第一个基本说明XfaFields中没有xmlNodes。第二个节点找到了一个叫做“data”的节点(这是它找到的唯一一个),但没有找到任何子节点。

Private Sub ReadXfa(pdfTemplate As String)
    pdfReader.unethicalreading = True
    Dim readerPDF As New PdfReader(pdfTemplate)

    Dim xfaFields = readerPDF.AcroFields.Xfa.DatasetsSom.Name2Node

    For Each xmlNode In xfaFields
        Console.WriteLine(xmlNode.Value.Name + ":" + xmlNode.Value.InnerText)
    Next
    'Example of how to get a field value
    '   Dim lastName = xfaFields.First(Function(a) a.Value.Name = "textFieldLastNameGlobal").Value.InnerText


    Dim reader As New PdfReader(pdfTemplate)
    Dim xfa As New XfaForm(reader)
    Dim node As XmlNode = xfa.DatasetsNode()
    Dim list As XmlNodeList = node.ChildNodes()
    For i As Integer = 0 To list.Count - 1
        Console.WriteLine(list.Item(i).LocalName())
        If "data".Equals(list.Item(i).LocalName()) Then
            node = list.Item(i)
            Exit For
        End If
    Next
    list = node.ChildNodes()
    For i As Integer = 0 To list.Count - 1
        Console.WriteLine(list.Item(i).LocalName())
    Next
    reader.Close()
End Sub

https://www.uscis.gov/system/files_force/files/form/I-9.pdf?download=1

非常感谢你的时间/帮助!

共有1个答案

韩安顺
2023-03-14

首先,很抱歉我不再使用VB.NET,但您应该能够转换后面的代码。

您已经发现新的表单是XFA。有一种简单的非编程方式可以查看表单字段和数据。您注意到您升级了Adobe Reader版本,所以我猜您使用的是Reader DC。从菜单选项中:

Edit => Form Options => Export Data...

它将表单导出到您可以检查的xml文件。XML文件提示您需要相应的XML文档来填充表单,这与Acroform的处理方式有很大不同。

public string FillXml(Dictionary<string, string> fields)
{
    // XML_INFILE => physical path to XML file exported from I-9
    XDocument xDoc = XDocument.Load(XML_INFILE);
    foreach (var kvp in fields)
    {
        // handle multiple elements in I-9 form
        var elements = xDoc.XPathSelectElements(
            string.Format("//{0}", kvp.Key)
        );
        if (elements.Count() > 0)
        {
            foreach (var e in elements) { e.Value = kvp.Value; }
        }
    }

    return xDoc.ToString();
}

现在我们有了一个创建有效XML的方法,请使用一些示例数据填充表单字段:

var fields = new Dictionary<string, string>()
{
    { "textFieldLastNameGlobal", "Doe" },
    { "textFieldFirstNameGlobal", "Jane" }
};
var filledXml = FillXml(fields);

using (var ms = new MemoryStream())
{
    // PDF_READER => I-9 PdfReader instance
    using (PDF_READER)
    {
        // I-9 has password security
        PdfReader.unethicalreading = true;
        // maintain usage rights on output file
        using (var stamper = new PdfStamper(PDF_READER, ms, '\0', true))
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(filledXml);
            stamper.AcroFields.Xfa.FillXfaForm(doc.DocumentElement);
        }
    }
    File.WriteAllBytes(OUTFILE, ms.ToArray());
}

要回答您的最后一个问题,如何确定表单“类型”,请使用PDFReader实例,如下所示:

PDF_READER.AcroFields.Xfa.XfaPresent

true表示XFA,false表示acroform。

 类似资料:
  • 本文向大家介绍javascript实现自动填写表单实例简析,包括了javascript实现自动填写表单实例简析的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了javascript实现自动填写表单的方法。分享给大家供大家参考,具体如下: 在平时开发过程中,或者在访问某些站点,经常要频繁地填写一大堆表单时,我们可以利用javascript,写一段脚本,预先把要填的信息准备好,然后模拟点击按钮的

  • 问题内容: 我知道如何使用纯PHP来做到这一点,但是我需要在不重新加载页面的情况下做到这一点。无论如何,jQuery是否可以有效地拉回一些数据库结果(基于用户在表单的第一个文本字段中输入的内容),然后使用从db查询中拉回的数据填充其余的字段? 从本质上讲,我希望用户离开文本字段(通过跳出或单击下一个字段)而离开,然后使用该字段中输入的值提交查询,然后使用w /重新加载页面。 我熟悉jQuery的基

  • 我们有一个配置页面,用户在其中配置电子邮件服务器。由于某种原因,chrome开始自动填充随机场。我们尝试使用随机字符串添加名称属性或id属性,但google仍然自动填充这些字段。我们的田地是这样的 它会更改字段,客户会保存数据,而不会意识到字段正在更改。阻止这一切的最好方法是什么?

  • 我有一个问题,当我完成表单上的一个字段并使用Tab键或鼠标移动到另一个字段时,表单会自动提交并转到actionCreate或actionEdit(视情况而定)中指定的页面。如果我重新打开表单,则该单个数据元素已保存,并且我可以再输入一个数据元素,但只要移动到另一个字段,表单就会自动重新提交。 一些背景资料: 这种行为发生在Google Chrome v.56上。x和Firefox v.52。x、

  • 我的表单中有两个字段,Chrome被错误地识别为信用卡号码(一个是电话号码,一个是传真号码)。也有两个字段的名字,Chrome认为是信用卡名称的字段,并希望自动填充。我可以在这些元素上使用一些属性来告诉Chrome它们实际上与信用卡无关吗? 我已尝试在输入上设置autocomplete=“false”。这删除了地址/联系信息的自动填充选项,但信用卡选项仍然存在。

  • 问题内容: 我想知道一种如何使用ajax或curl在外部站点(PHP)的多个页面上自动填充多个表单(使用)。 例如,一个站点有一个表单,可将您带到提交表单的时间,而还有另一种表单也需要填写和提交。我想从我的本地服务器自动填写两个表格。我该如何做到? 问题答案: 最简单的方法是使用油脂类(https://addons.mozilla.org/en- US/firefox/addon/greasemo