使用可流布局预填充Forms prepopulating-forms-with-flowable-layouts1

使用可流布局预填充Forms prepopulating-forms-with-flowable-layouts2

预先填充的表单会在呈现的表单中向用户显示数据。 例如,假设用户使用用户名和密码登录到网站。 如果验证成功,则客户端应用程序将查询数据库以获取用户信息。 数据将合并到表单中,然后表单呈现给用户。 因此,用户能够在表单中查看个性化数据。

预先填充表单具有以下优点:

  • 允许用户在表单中查看自定义数据。
  • 减少用户填写表单时键入内容的次数。
  • 通过控制数据的放置位置来确保数据完整性。

以下两个XML数据源可以预填充表单:

  • XDP数据源,它是符合XFA语法的XML(或预填充使用Acrobat创建的表单的XFDF数据)。
  • 包含与表单字段名称匹配的名称/值对的任意XML数据源(本节中的示例使用任意XML数据源)。

要预填充的每个表单字段都必须存在XML元素。 XML元素名称必须与字段名称匹配。 如果XML元素与表单字段不对应,或者如果XML元素名称与字段名称不匹配,则忽略该元素。 只要指定了所有XML元素,就不必匹配XML元素的显示顺序。

在预填充已包含数据的表单时,必须指定已在XML数据源中显示的数据。 假设包含10个字段的表单在四个字段中有数据。 接下来,假设您希望预填充其余六个字段。 在这种情况下,必须在XML数据源中指定用于预填充表单的10个XML元素。 如果仅指定六个元素,则原始的四个字段为空。

例如,您可以预填充窗体,如示例确认窗体。 (请参阅呈现交互式PDF forms中的“确认表单”。)

要预填充示例确认表单,您必须创建一个XML数据源,该数据源包含与表单中的三个字段匹配的三个XML元素。 此表单包含以下三个字段:FirstNameLastNameAmount。 第一步是创建一个XML数据源,该数据源包含与表单设计中的字段匹配的XML元素。 下一步是将数据值分配给XML元素,如以下XML代码中所示。

     <Untitled>
         <FirstName>Jerry</FirstName>
         <LastName>Johnson</LastName>
         <Amount>250000</Amount>
     </Untitled>

使用此XML数据源预填充确认表单,然后呈现该表单后,将显示分配给XML元素的数据值,如下图所示。

pf_pf_confirmxml3

使用可流动布局预填充表单 prepopulating_forms_with_flowable_layouts-1

带可流动布局的Forms可用于向用户显示未确定的数据量。 由于表单的布局会自动根据合并的数据量进行调整,因此您无需像处理具有固定布局的表单那样预先确定表单的固定布局或页数。

通常,表单会填充在运行时获取的数据。 因此,您可以通过创建内存中XML数据源并将数据直接放入内存中XML数据源来预填充表单。

考虑一个基于Web的应用程序,如在线商店。 在线购物者完成购买项目后,所有购买的项目都会放入内存中的XML数据源,该数据源用于预填充表单。 下图显示了此流程,图后的表中对此进行了说明。

pf_pf_finsrv_webapp_v1

下表描述了此图中的步骤。

步骤
描述
1
用户从基于Web的网上商店购买商品。
2
用户完成采购物料并单击“提交”按钮后,将创建一个内存中的XML数据源。 购买的项目和用户信息都放入内存中的XML数据源中。
3
XML数据源用于预填充采购订单表单(此表后面显示了此表单的示例)。
4
采购订单表单呈现给客户端Web浏览器。

下图显示了采购订单表单的示例。 表中的信息可以根据XML数据中的记录数进行调整。

pf_pf_poform

NOTE
可以使用来自其他源(如企业数据库或外部应用程序)的数据预填充表单。

窗体设计注意事项 form-design-considerations

带可流动布局的Forms基于在Designer中创建的表单设计。 表单设计指定一组布局、呈现和数据捕获规则,包括基于用户输入计算值。 数据输入到表单中时将应用规则。 添加到表单的字段是表单设计内的子表单。 例如,在上图所示的采购订单表单中,每行都是一个子表单。 有关创建包含子表单的表单设计的信息,请参阅创建具有可流动布局的采购订单表单

了解数据子组 understanding-data-subgroups

XML数据源用于预先填充具有固定布局和可流动布局的表单。 但是,不同之处在于,使用可流动布局预填充表单的XML数据源包含用于预填充表单内重复的子表单的重复XML元素。 这些重复的XML元素称为数据子组。

用于预填充上图所示的采购订单表单的XML数据源包含四个重复的数据子组。 每个数据子组对应于购买的项目。 所购物品包括显示器、台灯、电话和通讯录。

以下XML数据源用于预填充采购订单表单。

     <header>
         <!-- XML elements used to prepopulate non-repeating fields such as address
         <!and city
         <txtPONum>8745236985</txtPONum>
         <dtmDate>2004-02-08</dtmDate>
         <txtOrderedByCompanyName>Any Company Name</txtOrderedByCompanyName>
         <txtOrderedByAddress>555, Any Blvd.</txtOrderedByAddress>
         <txtOrderedByCity>Any City</txtOrderedByCity>
         <txtOrderedByStateProv>ST</txtOrderedByStateProv>
         <txtOrderedByZipCode>12345</txtOrderedByZipCode>
         <txtOrderedByCountry>Any Country</txtOrderedByCountry>
         <txtOrderedByPhone>(123) 456-7890</txtOrderedByPhone>
         <txtOrderedByFax>(123) 456-7899</txtOrderedByFax>
         <txtOrderedByContactName>Contact Name</txtOrderedByContactName>
         <txtDeliverToCompanyName>Any Company Name</txtDeliverToCompanyName>
         <txtDeliverToAddress>7895, Any Street</txtDeliverToAddress>
         <txtDeliverToCity>Any City</txtDeliverToCity>
         <txtDeliverToStateProv>ST</txtDeliverToStateProv>
         <txtDeliverToZipCode>12346</txtDeliverToZipCode>
         <txtDeliverToCountry>Any Country</txtDeliverToCountry>
         <txtDeliverToPhone>(123) 456-7891</txtDeliverToPhone>
         <txtDeliverToFax>(123) 456-7899</txtDeliverToFax>
         <txtDeliverToContactName>Contact Name</txtDeliverToContactName>
     </header>
     <detail>
         <!-- A data subgroup that contains information about the monitor>
         <txtPartNum>00010-100</txtPartNum>
         <txtDescription>Monitor</txtDescription>
         <numQty>1</numQty>
         <numUnitPrice>350.00</numUnitPrice>
     </detail>
     <detail>
         <!-- A data subgroup that contains information about the desk lamp>
         <txtPartNum>00010-200</txtPartNum>
         <txtDescription>Desk lamps</txtDescription>
         <numQty>3</numQty>
         <numUnitPrice>55.00</numUnitPrice>
     </detail>
     <detail>
         <!-- A data subgroup that contains information about the Phone>
             <txtPartNum>00025-275</txtPartNum>
             <txtDescription>Phone</txtDescription>
             <numQty>5</numQty>
             <numUnitPrice>85.00</numUnitPrice>
     </detail>
     <detail>
         <!-- A data subgroup that contains information about the address book>
         <txtPartNum>00300-896</txtPartNum>
         <txtDescription>Address book</txtDescription>
         <numQty>2</numQty>
         <numUnitPrice>15.00</numUnitPrice>
     </detail>

请注意,每个数据子组都包含对应于此信息的四个XML元素:

  • 项目部件号
  • 物料说明
  • 物料数量
  • 单价

数据子组的父XML元素的名称必须与窗体设计中的子窗体的名称匹配。 例如,在上一个图中,请注意数据子组的父XML元素的名称为detail。 这与采购订单表单所基于的表单设计中子表单的名称相对应。 如果数据子组的父XML元素的名称与子表单不匹配,则不会预填充服务器端表单。

每个数据子组都必须包含与子表单中的字段名称匹配的XML元素。 窗体设计中的detail子窗体包含以下字段:

  • txtPartNum
  • txtDescription
  • numQty
  • numUnitPrice
NOTE
如果您尝试使用包含重复XML元素的数据源预填充表单,并将RenderAtClient选项设置为No,则只有第一个数据记录会合并到表单中。 为确保所有数据记录都合并到表单中,请将RenderAtClient设置为Yes。 有关RenderAtClient选项的信息,请参阅在客户端渲染Forms
NOTE
有关Forms服务的详细信息,请参阅AEM Forms的服务参考

步骤摘要 summary-of-steps

要使用可流式布局预填充表单,请执行以下任务:

  1. 包括项目文件。
  2. 创建内存中XML数据源。
  3. 转换XML数据源。
  4. 呈现预填充的表单。

包含项目文件

在开发项目中包含必要的文件。 如果要使用Java创建客户端应用程序,请包含必要的JAR文件。 如果使用Web服务,请确保包含代理文件。

包含项目文件

在开发项目中包含必要的文件。 如果要使用Java创建客户端应用程序,请包含必要的JAR文件。 如果使用Web服务,请确保包含代理文件。

创建内存中的XML数据源

可以使用org.w3c.dom类创建内存中的XML数据源,以预填充具有可流动布局的表单。 将数据放置到符合表单的XML数据源中。 有关具有可流动布局的表单与XML数据源之间的关系的信息,请参阅了解数据子组

转换XML数据源

使用org.w3c.dom类创建的内存中XML数据源可以转换为com.adobe.idp.Document对象,然后才可用于预填充表单。 内存中的XML数据源可以使用Java XML转换类进行转换。

NOTE
如果您使用Forms服务的WSDL预填充表单,则必须将org.w3c.dom.Document对象转换为BLOB对象。

呈现预填充的表单

您可以像呈现其他表单一样呈现预填充的表单。 唯一的区别是,您使用包含XML数据源的com.adobe.idp.Document对象来预填充表单。

另请参阅

包括AEM Forms Java库文件

设置连接属性

Forms服务API快速启动

呈现交互式PDF forms

创建可渲染Forms的Web应用程序

使用Java API预填充表单 prepopulating-forms-using-the-java-api

要使用Forms API (Java)预填充具有可流动布局的表单,请执行以下步骤:

  1. 包含项目文件

    在Java项目的类路径中包含客户端JAR文件,例如adobe-forms-client.jar。 有关这些文件的位置的信息,请参阅包括AEM Forms Java库文件

  2. 创建内存中XML数据源

    • 通过调用DocumentBuilderFactorynewInstance方法创建Java DocumentBuilderFactory对象。

    • 通过调用DocumentBuilderFactory对象的newDocumentBuilder方法创建Java DocumentBuilder对象。

    • 调用DocumentBuilder对象的newDocument方法以实例化org.w3c.dom.Document对象。

    • 通过调用org.w3c.dom.Document对象的createElement方法创建XML数据源的根元素。 这将创建一个表示根元素的Element对象。 将表示元素名称的字符串值传递给createElement方法。 将返回值强制转换为Element。 接下来,通过调用Document对象的appendChild方法将根元素附加到文档,并将根元素对象作为参数传递。 以下代码行显示了此应用程序逻辑:

       Element root = (Element)document.createElement("transaction");  document.appendChild(root);

    • 通过调用Document对象的createElement方法创建XML数据源的标头元素。 将表示元素名称的字符串值传递给createElement方法。 将返回值强制转换为Element。 接下来,通过调用root对象的appendChild方法,将标头元素附加到根元素,并将标头元素对象作为参数传递。 附加到标题元素的XML元素对应于表单的静态部分。 以下代码行显示此应用程序逻辑:

       Element header = (Element)document.createElement("header");  root.appendChild(header);

    • 通过调用Document对象的createElement方法,创建属于标头元素的子元素,并传递表示该元素名称的字符串值。 将返回值强制转换为Element。 接下来,通过调用子元素的appendChild方法为其设置值,并将Document对象的createTextNode方法作为参数传递。 指定作为子元素的值显示的字符串值。 最后,通过调用标头元素的appendChild方法将子元素附加到标头元素,并将子元素对象作为参数传递。 以下代码行显示此应用程序逻辑:

       Element poNum= (Element)document.createElement("txtPONum");  poNum.appendChild(document.createTextNode("8745236985"));  header.appendChild(LastName);

    • 通过重复表单静态部分中出现的每个字段的上一个子步骤,将所有剩余的元素添加到标题元素中(在XML数据源图表中,这些字段显示在A部分中。(请参阅了解数据子组

    • 通过调用Document对象的createElement方法创建XML数据源的详细信息元素。 将表示元素名称的字符串值传递给createElement方法。 将返回值强制转换为Element。 接下来,通过调用root对象的appendChild方法,将detail元素附加到根元素,并将该detail元素对象作为参数传递。 附加到详细信息元素的XML元素对应于表单的动态部分。 以下代码行显示此应用程序逻辑:

       Element detail = (Element)document.createElement("detail");  root.appendChild(detail);

    • 通过调用Document对象的createElement方法,创建属于该详细信息元素的子元素,并传递表示该元素名称的字符串值。 将返回值强制转换为Element。 接下来,通过调用子元素的appendChild方法为其设置值,并将Document对象的createTextNode方法作为参数传递。 指定作为子元素的值显示的字符串值。 最后,通过调用detail元素的appendChild方法,将子元素附加到detail元素,并将子元素对象作为参数传递。 以下代码行显示此应用程序逻辑:

       Element txtPartNum = (Element)document.createElement("txtPartNum");  txtPartNum.appendChild(document.createTextNode("00010-100"));  detail.appendChild(txtPartNum);

    • 对所有XML元素重复最后一个子步骤以附加到详细信息元素。 要正确创建用于填充采购订单表单的XML数据源,必须将以下XML元素附加到详细信息元素: txtDescriptionnumQtynumUnitPrice

    • 对用于预填充表单的所有数据项重复前两个子步骤。

  3. 转换XML数据源

    • 通过调用javax.xml.transform.Transformer对象的静态newInstance方法创建javax.xml.transform.Transformer对象。
    • 通过调用TransformerFactory对象的newTransformer方法创建Transformer对象。
    • 使用构造函数创建ByteArrayOutputStream对象。
    • 使用对象的构造函数创建javax.xml.transform.dom.DOMSource对象,并传递在步骤1中创建的org.w3c.dom.Document对象。
    • 使用对象的构造函数创建javax.xml.transform.dom.DOMSource对象并传递ByteArrayOutputStream对象。
    • 通过调用javax.xml.transform.Transformer对象的transform方法并传递javax.xml.transform.dom.DOMSourcejavax.xml.transform.stream.StreamResult对象来填充Java ByteArrayOutputStream对象。
    • 创建字节数组并将ByteArrayOutputStream对象的大小分配给字节数组。
    • 通过调用ByteArrayOutputStream对象的toByteArray方法填充字节数组。
    • 使用对象的构造函数并传递字节数组来创建一个com.adobe.idp.Document对象。
  4. 呈现预填充的表单

    调用FormsServiceClient对象的renderPDFForm方法并传递以下值:

    • 一个字符串值,它指定窗体设计名称,包括文件扩展名。
    • 包含要与表单合并的数据的com.adobe.idp.Document对象。 确保使用在步骤1和步骤2中创建的com.adobe.idp.Document对象。
    • 存储运行时选项的PDFFormRenderSpec对象。
    • 包含Forms服务所需URI值的URLSpec对象。
    • 存储文件附件的java.util.HashMap对象。 这是一个可选参数,如果您不想将文件附加到表单,则可以指定null

    renderPDFForm方法返回的FormsResult对象包含必须写入客户端Web浏览器的表单数据流。

    • 创建用于将表单数据流发送到客户端Web浏览器的javax.servlet.ServletOutputStream对象。
    • 通过调用FormsResult对象的getOutputContent方法创建com.adobe.idp.Document对象。
    • 通过调用com.adobe.idp.Document对象的getInputStream方法创建java.io.InputStream对象。
    • 通过调用InputStream对象的read方法并将该字节数组作为参数传递,创建字节数组以表单数据流填充该字节数组。
    • 调用javax.servlet.ServletOutputStream对象的write方法将表单数据流发送到客户端Web浏览器。 将字节数组传递给write方法。

另请参阅

快速入门(SOAP模式):使用Java API在可流式布局中预填充Forms

包括AEM Forms Java库文件

设置连接属性

使用Web服务API预填充表单 prepopulating-forms-using-the-web-service-api

要使用Forms API(Web服务)预填充具有可流动布局的表单,请执行以下步骤:

  1. 包含项目文件

  2. 创建内存中XML数据源

    • 通过调用DocumentBuilderFactorynewInstance方法创建Java DocumentBuilderFactory对象。

    • 通过调用DocumentBuilderFactory对象的newDocumentBuilder方法创建Java DocumentBuilder对象。

    • 调用DocumentBuilder对象的newDocument方法以实例化org.w3c.dom.Document对象。

    • 通过调用org.w3c.dom.Document对象的createElement方法创建XML数据源的根元素。 这将创建一个表示根元素的Element对象。 将表示元素名称的字符串值传递给createElement方法。 将返回值强制转换为Element。 接下来,通过调用Document对象的appendChild方法将根元素附加到文档,并将根元素对象作为参数传递。 以下代码行显示此应用程序逻辑:

       Element root = (Element)document.createElement("transaction");  document.appendChild(root);

    • 通过调用Document对象的createElement方法创建XML数据源的标头元素。 将表示元素名称的字符串值传递给createElement方法。 将返回值强制转换为Element。 接下来,通过调用root对象的appendChild方法,将标头元素附加到根元素,并将标头元素对象作为参数传递。 附加到标题元素的XML元素对应于表单的静态部分。 以下代码行显示此应用程序逻辑:

       Element header = (Element)document.createElement("header");  root.appendChild(header);

    • 通过调用Document对象的createElement方法,创建属于标头元素的子元素,并传递表示该元素名称的字符串值。 将返回值强制转换为Element。 接下来,通过调用子元素的appendChild方法为其设置值,并将Document对象的createTextNode方法作为参数传递。 指定作为子元素的值显示的字符串值。 最后,通过调用标头元素的appendChild方法将子元素附加到标头元素,并将子元素对象作为参数传递。 以下代码行显示了此应用程序逻辑:

       Element poNum= (Element)document.createElement("txtPONum");  poNum.appendChild(document.createTextNode("8745236985"));  header.appendChild(LastName);

    • 通过重复表单静态部分中出现的每个字段的上一个子步骤,将所有剩余的元素添加到标题元素中(在XML数据源图表中,这些字段显示在A部分中。(请参阅了解数据子组

    • 通过调用Document对象的createElement方法创建XML数据源的详细信息元素。 将表示元素名称的字符串值传递给createElement方法。 将返回值强制转换为Element。 接下来,通过调用root对象的appendChild方法,将detail元素附加到根元素,并将该detail元素对象作为参数传递。 附加到详细信息元素的XML元素对应于表单的动态部分。 以下代码行显示了此应用程序逻辑:

       Element detail = (Element)document.createElement("detail");  root.appendChild(detail);

    • 通过调用Document对象的createElement方法,创建属于该详细信息元素的子元素,并传递表示该元素名称的字符串值。 将返回值强制转换为Element。 接下来,通过调用子元素的appendChild方法为其设置值,并将Document对象的createTextNode方法作为参数传递。 指定作为子元素的值显示的字符串值。 最后,通过调用detail元素的appendChild方法,将子元素附加到detail元素,并将子元素对象作为参数传递。 以下代码行显示了此应用程序逻辑:

       Element txtPartNum = (Element)document.createElement("txtPartNum");  txtPartNum.appendChild(document.createTextNode("00010-100"));  detail.appendChild(txtPartNum);

    • 对所有XML元素重复最后一个子步骤以附加到详细信息元素。 要正确创建用于填充采购订单表单的XML数据源,必须将以下XML元素附加到详细信息元素: txtDescriptionnumQtynumUnitPrice

    • 对用于预填充表单的所有数据项重复前两个子步骤。

  3. 转换XML数据源

    • 通过调用javax.xml.transform.Transformer对象的静态newInstance方法创建javax.xml.transform.Transformer对象。
    • 通过调用TransformerFactory对象的newTransformer方法创建Transformer对象。
    • 使用构造函数创建ByteArrayOutputStream对象。
    • 使用对象的构造函数创建javax.xml.transform.dom.DOMSource对象,并传递在步骤1中创建的org.w3c.dom.Document对象。
    • 使用对象的构造函数创建javax.xml.transform.dom.DOMSource对象并传递ByteArrayOutputStream对象。
    • 通过调用javax.xml.transform.Transformer对象的transform方法并传递javax.xml.transform.dom.DOMSourcejavax.xml.transform.stream.StreamResult对象来填充Java ByteArrayOutputStream对象。
    • 创建字节数组并将ByteArrayOutputStream对象的大小分配给字节数组。
    • 通过调用ByteArrayOutputStream对象的toByteArray方法填充字节数组。
    • 使用构造函数创建BLOB对象并调用其setBinaryData方法并传递字节数组。
  4. 呈现预填充的表单

    调用FormsService对象的renderPDFForm方法并传递以下值:

    • 一个字符串值,它指定窗体设计名称,包括文件扩展名。
    • 包含要与表单合并的数据的BLOB对象。 确保您使用在步骤1和步骤2中创建的BLOB对象。
    • 存储运行时选项的PDFFormRenderSpecc对象。 有关详细信息,请参阅AEM Forms API引用
    • 包含Forms服务所需URI值的URLSpec对象。
    • 存储文件附件的java.util.HashMap对象。 这是一个可选参数,如果您不想将文件附加到表单,则可以指定null
    • 方法填充的空com.adobe.idp.services.holders.BLOBHolder对象。 用于存储渲染的PDF表单。
    • 方法填充的空javax.xml.rpc.holders.LongHolder对象。 (此参数将存储表单中的页数)。
    • 方法填充的空javax.xml.rpc.holders.StringHolder对象。 (此参数将存储区域设置值)。
    • 将包含此操作结果的空com.adobe.idp.services.holders.FormsResultHolder对象。

    renderPDFForm方法使用必须写入客户端Web浏览器的表单数据流填充作为最后一个参数值传递的com.adobe.idp.services.holders.FormsResultHolder对象。

    • 通过获取com.adobe.idp.services.holders.FormsResultHolder对象的value数据成员的值创建FormResult对象。
    • 通过调用FormsResult对象的getOutputContent方法,创建包含表单数据的BLOB对象。
    • 通过调用其getContentType方法获取BLOB对象的内容类型。
    • 通过调用其setContentType方法并传递BLOB对象的内容类型来设置javax.servlet.http.HttpServletResponse对象的内容类型。
    • 通过调用javax.servlet.http.HttpServletResponse对象的getOutputStream方法,创建用于将表单数据流写入客户端Web浏览器的javax.servlet.ServletOutputStream对象。
    • 创建字节数组,并通过调用BLOB对象的getBinaryData方法填充该数组。 此任务将FormsResult对象的内容分配给字节数组。
    • 调用javax.servlet.http.HttpServletResponse对象的write方法将表单数据流发送到客户端Web浏览器。 将字节数组传递给write方法。
    note note
    NOTE
    renderPDFForm方法使用必须写入客户端Web浏览器的表单数据流填充作为最后一个参数值传递的com.adobe.idp.services.holders.FormsResultHolder对象。

另请参阅

使用Base64编码调用AEM Forms

recommendation-more-help
19ffd973-7af2-44d0-84b5-d547b0dffee2