Page 1 of 1

insert data into a table in existing doc file

PostPosted: Wed May 18, 2011 9:23 pm
by cairokl
I am trying to insert a text into a table's cell, but I end up java.util.ConcurrentModificationException. I got a question here, is this error caused by part ? if yes, how do i deal with it ?

the code below comment "// is this the correct way of insert the data ?" is that the correct way of inserting the data into the table ?

please let me know if i can give better understanding to reader.


here is what i am trying to do
===========================
table1
row1
cell1:statement period:
cell2:[input here]
===========================

Code: Select all
Exception in thread "main" java.util.ConcurrentModificationException
   at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
   at java.util.AbstractList$Itr.next(Unknown Source)
   at TestTable.walkJAXBElements(TestTable.java:121)
   at TestTable.walkJAXBElements(TestTable.java:126)
   at TestTable.walkJAXBElements(TestTable.java:126)
   at TestTable.walkJAXBElements(TestTable.java:126)
   at TestTable.main(TestTable.java:44)



Code: Select all
import java.util.List;
import javax.xml.bind.JAXBException;
import org.docx4j.TraversalUtil;
import org.docx4j.TraversalUtil.Callback;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.samples.AbstractSample;
import org.docx4j.wml.Body;
import org.docx4j.wml.Document;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Tc;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;


public class TestTable extends AbstractSample implements Callback {
   int tables=0;
   int cells =0;
   int rows=0;
   boolean write;
   Tc tc=null;
   int trackCell=0;
   static WordprocessingMLPackage wmp=null;
   public static void main(String args[]) {
      inputfilepath="C:\\KOB.docx";
      try {
         wmp = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
         MainDocumentPart docPart = wmp.getMainDocumentPart();
         Document wmlDocumentEl = (Document)docPart.getJaxbElement();
         Body body=wmlDocumentEl.getBody();
         
         
         new TestTable().walkJAXBElements(body);
         wmp.save(new java.io.File(inputfilepath));
      } catch (Docx4JException e) {
         System.out.println("File error");
         e.printStackTrace();
      }
   }

   @Override
   public List<Object> apply(Object o) {
      String text="";
      ObjectFactory factory = Context.getWmlObjectFactory();
      
      if (o instanceof Tbl) {
         Tbl tbl = new Tbl();
         tbl=(Tbl)o;
         System.out.println("table ==> " + (tables+=1));   
         cells=0;
         rows=0;
      }
      
      if(o instanceof Tr) {
         System.out.println();
         System.out.println("row ==> " + (rows+=1));
         write=false;
      }
      
      if(o instanceof Tc) {         
         tc=(Tc)o;         
         System.out.println("cell ==> " + (cells+=1));
      }
      
      if( o instanceof Text){
         text=((Text)o).getValue();
         if(text.equalsIgnoreCase("STATEMENT PERIOD:")) {
            write=true;
            trackCell=cells+1;
         }
      }
      if(!text.equals("")) {         System.out.println("detected String ..... == " + text);

      }

      
                /**
       *
       *   is this the correct way of insert the data ?
       */
      if(o instanceof P && write && tc != null && cells==trackCell) {
//         tc.getEGBlockLevelElts();
//         tc.getEGBlockLevelElts().add( wmp.getMainDocumentPart().createParagraphOfText("--value--") );
         
         P p=(P)o;
         R run = factory.createR();
         Text t = factory.createText();
         t.setValue(" --value--");
         run.getRunContent().add(t);
         
         p.getParagraphContent().add(run);
         tc.getEGBlockLevelElts().add(p);
      
      }
         
      return null;
   }

   @Override
   public List<Object> getChildren(Object arg0) {
      return TraversalUtil.getChildrenImpl(arg0);
   }

   @Override
   public boolean shouldTraverse(Object arg0) {
      return true;
   }

   @Override
   public void walkJAXBElements(Object parent) {
      List children = getChildren(parent);
      if(children != null) {
         for(Object o : children) {
            o=XmlUtils.unwrap(o);
            this.apply(o);
            
            if (this.shouldTraverse(o)) {
               walkJAXBElements(o);
            }
         }
      }      
   }
   
}

Re: insert data into a table in existing doc file

PostPosted: Thu May 19, 2011 1:10 am
by jason
I guess the problem is that with

Code: Select all
            tc.getEGBlockLevelElts().add(p);


you are adding content to one of the ancestor lists (ie tc content) you are iterating over in walkJAXBElements.

You need to avoid doing that.

If your implementation of org.docx4j.TraversalUtil.Callback is simply trying to find the right tc to add content to, then store a reference to that tc when you find it, and defer the add content step until after you've finished the traverse. (You can have shouldTraverse return false to get out quickly).

Re: insert data into a table in existing doc file

PostPosted: Thu May 19, 2011 6:28 pm
by cairokl
thanks, its works now.
one more question its there any method to find the font size of a word ?