pdfbox-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tolen Miller <tolenmil...@gmail.com>
Subject Re: Hybrid XFA (Livecycle) PDF - setting values of text fields in XFA
Date Sat, 24 Oct 2015 16:21:05 GMT
I've tried setting the XFA a few ways. First, I tried simply setting the
XFA with the original, but I assume that this does not work because I'm
working on the Document (xml) that is a copy and no longer associated with
the xfa:
...
* PDXFA xfa = acroForm.getXFA();*
* Document xmlDoc = xfa.getDocument();*
* Node xfaData = xmlDoc.getElementsByTagName("xfa:data").item(0);*
*        setDataElements(xfaData, notesFields);  // edit xml doc*
*        acroForm.setXFA(xfa);*
...
Second, I tried creating a new xfa object by grabbing the original xfa
COSObject, though that seems the same as the first attempt.
...
*        PDXFA newXfa = new PDXFA(xfa.getCOSObject());*
*        acroForm.setXFA(newXfa);*
...
Now I'm wondering if I am supposed to work my way back up the object model,
after I set the XFA? something like:
*docCatalog.setAcroForm(acroForm);*

Or am I supposed to create a new XFA, then put my XML in a stream and get
it into the new XFA object somehow? (as described here for an older version
<http://stackoverflow.com/questions/24149361>) Or stop using the Document
class and go straight to the COS model with something like is suggested here
<http://stackoverflow.com/questions/10536334>?


On Thu, Oct 22, 2015 at 10:29 PM Maruan Sahyoun <sahyoun@fileaffairs.de>
wrote:

> 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
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message