pdfbox-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Maruan Sahyoun <sahy...@fileaffairs.de>
Subject Re: Hybrid XFA (Livecycle) PDF - setting values of text fields in XFA
Date Fri, 23 Oct 2015 05:29:09 GMT
Hi,

> Am 23.10.2015 um 06:16 schrieb Tolen Miller <tolenmiller@msn.com>:
> 
> 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?

you need to setXfa() as the changes you've done are to the XML Document but not yet back in
the PDF

BR
Maruan

> 
> 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?
>> 
>> 


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@pdfbox.apache.org
For additional commands, e-mail: users-help@pdfbox.apache.org


Mime
View raw message