pdfbox-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tolen Miller <tolenmil...@msn.com>
Subject Re: Hybrid XFA (Livecycle) PDF - setting values of text fields in XFA
Date Fri, 23 Oct 2015 04:16:12 GMT
Thank you for the response. Indeed I was unaware that xfa:data was just a
marker showing the start of the nodes that may contain data...

After implementing the recursion Maruan suggeted, I am no longer seeing my
PDFs filled despite my sysout showing the code locating and updating the
values.

In my implementation, I pass in a hashmap with field names and values from
my database. Then, if I find a node with a matching name, I set the value
of the xfa node:

*    public static void setDataElements(Node node, HashMap<String, String>
dbData) {*
*        NodeList nodeList = node.getChildNodes();*
*        for (int i = 0; i < nodeList.getLength(); i++) {*
*            Node currentNode = nodeList.item(i);*
*            if (currentNode.getNodeType() == Node.ELEMENT_NODE &&
currentNode.hasChildNodes()) {*
*                //calls this method for all the children which is Element*
*                setDataElements(currentNode, dbData);*
*            } else {*
*            currentNode.setNodeValue( dbData.get(
currentNode.getNodeName() ) );*
*            System.out.println("Matching XML Field found: " + *
*            currentNode.getNodeName() + *
*            " Setting Value to: " + *
*            dbData.get( currentNode.getNodeName() ));*
*//                dbData.put(currentNode.getNodeName(),
currentNode.getNodeValue());*
*            }*
*        }*
*    }*

Do I then need to set the PDXFA with setXfa()? or should I just be able to
save the pdf after modifying the Document ( retrieved via
PDXFA.getDocument() ) and have the values show up?

Link to test version of PDF <http://1drv.ms/1hREdXQ>

On Sun, Oct 11, 2015 at 11:54 PM Maruan Sahyoun <sahyoun@fileaffairs.de>
wrote:

> Hi,
>
> > Am 12.10.2015 um 00:46 schrieb Tolen Miller <tolenmiller@msn.com>:
> >
> > I'm using version 1.8.10 and had some great help in a previous thread
> > (subject: Cannot load pre existing PDF to access fields). I have been
> able
> > to successfully load a pre existing fill-able PDF (created in LiveCycle);
> > get a map of text fields from the getFieldNameList() method; then use a
> > comparison of the field name on the pdf and name of the database field to
> > map values onto the pdf.
> >
> > In the end of that thread, I mentioned my own trouble with also filling
> the
> > XFA portion of the form. In the end, I opted to rip out the XFA
> (acroForm.
> > setXFA(null);) in order to get the filled static PDF to display in
> Adobe's
> > products. I have been working on another project in the past few weeks,
> but
> > am again looking at filling the XFA. After looking at the PDXFA, I am
> > having trouble getting a similar map or list of text field names from the
> > XFA. This was my first attempt, but I'm not getting what I was expecting:
>
>
> would it be possible to upload a sample form to a public location to take
> a closer look?
>
> >
> > System.out.println("Setting up XFA");
> > PDXFA xfa = acroForm.getXFA();
> > Document xmlDoc = xfa.getDocument();
> > NodeList dataElements = xmlDoc.getElementsByTagName("xfa:data");
> > HashMap<String, Integer> xmlFields = new HashMap<String, Integer>();
> > if (dataElements != null) {
> > for (int i = 0; i < dataElements.getLength(); i++) {
> > xmlFields.put(dataElements.item(0).getNodeName(), i);
> > }
> > }
> >
>
> your need to recurse down into the nodes below xfa:data. Something like
>
>
>
>     public static void main(String[] args) throws IOException,
> ParserConfigurationException, SAXException
>     {
>         PDDocument document = PDDocument.loadNonSeq(...);
>         PDXFA xfa = document.getDocumentCatalog().getAcroForm().getXFA();
>         Document xmlDoc = xfa.getDocument();
>         Node xfaData = xmlDoc.getElementsByTagName("xfa:data").item(0);
>         HashMap<String, String> xmlFields = new HashMap<String, String>();
>
>         getDataElements(xfaData, xmlFields);
>
>         System.out.println(xmlFields);
>
>     }
>
>     public static void getDataElements(Node node, HashMap<String, String>
> xmlFields) {
>         NodeList nodeList = node.getChildNodes();
>         for (int i = 0; i < nodeList.getLength(); i++) {
>             Node currentNode = nodeList.item(i);
>             if (currentNode.getNodeType() == Node.ELEMENT_NODE &&
> currentNode.hasChildNodes()) {
>                 //calls this method for all the children which is Element
>                 getDataElements(currentNode, xmlFields);
>             } else {
>                 xmlFields.put(currentNode.getNodeName(),
> currentNode.getNodeValue());
>             }
>         }
>     }
>
>
> It could also be that xfa:data is empty or doesn't have all fields e.g.
> for dynamic forms. To get the fields as designed you need to look into the
> template node and look for subform and field nodes. Things can get a little
> more complicated as there is a <traversal> and there might be a <bind>
> elements which tell you a little more about the structure of the form and
> the data binding of an element. <bind> is there if the data binding for the
> field is not done by matching the field name. A small snippet below
>
>
>             <field h="6.35mm" name="txtOrderedByCompanyName" w="82.55mm"
> y="52.07mm">
>                <ui>
>                   <textEdit>
>                      <border>
>                         <edge presence="hidden"/>
>                         <edge presence="hidden"/>
>                         <edge/>
>                         <edge presence="hidden"/>
>                      </border>
>                      <margin/>
>                   </textEdit>
>                </ui>
>                <font size="9pt" typeface="Myriad Pro"/>
>                <margin bottomInset="0mm" leftInset="0mm" rightInset="0mm"
> topInset="0mm"/>
>                <para marginLeft="0pt" vAlign="middle"/>
>                <caption reserve="15.24mm">
>                   <para vAlign="middle"/>
>                   <value>
>                      <text>Company</text>
>                   </value>
>                </caption>
>                <traversal>
>                   <traverse ref="header[0].txtOrderedByAddress[0]"/>
>                </traversal>
>                <bind match="dataRef" ref="$.CompanyName"/>
>             </field>
>
>
> BR
> Maruan
>
>
>
>
> > My hope, after that code snippet, was to match on the String of the
> > xmlFields map with a field name from my db, then use the int as the
> > position of the dataElements list to set the text value (which would show
> > as the filled value in the pdf).  Where have I gone wrong?
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message