Page 1 of 1

Replace text into docx within a table

PostPosted: Thu Aug 07, 2008 11:12 am
by thinkpad
Hello,

first of all thanks to the developers. Docx4j is getting a great and easy tool to work with OpenXML.

I am trying to replace some text fields and am using your demo:

Code: Select all
   public static void main(String[] args) {
      File f = new File("test.docx");
      
      WordprocessingMLPackage wd;
      try {
         
         // 1. Load the Package
         wd = WordprocessingMLPackage.load(f);
         
         // 2. Fetch the document part
         MainDocumentPart docPart = wd.getMainDocumentPart();
         
         org.docx4j.wml.Document wmlDocumentEl = (org.docx4j.wml.Document)docPart.getJaxbElement();
         Body body =  wmlDocumentEl.getBody();
         
         List <Object> bodyChildren = body.getEGBlockLevelElts();
         
         walkJAXBElements(bodyChildren);
         
         wd.save(new File("test_out.docx"));
         
      } catch (Docx4JException e) {
         e.printStackTrace();
      }
      
   }
   
   /**
    * Iterates through all body objects of the word document.
    * @param bodyChildren
    */
   static void walkJAXBElements(List <Object> bodyChildren){
      
      for (Object o : bodyChildren ) {
         if (o instanceof org.docx4j.wml.P) {
            walkList( ((org.docx4j.wml.P)o).getParagraphContent());
         }
      }
   }
   
   
   /**
    * Iterates through all child elements to find text fields.
    * @param children
    */
   @SuppressWarnings("unchecked")
   static void walkList(List children){
      for (Object o : children ) {               
         if ( o instanceof javax.xml.bind.JAXBElement) {   
            if ( ((JAXBElement)o).getDeclaredType().getName().equals("org.docx4j.wml.Text") ) {
               org.docx4j.wml.Text t = (org.docx4j.wml.Text)((JAXBElement)o).getValue();
               if(t.getValue().equals("[Name]")) {
                  t.setValue("Arnold");
               }
            }                           
         } else if ( o instanceof org.docx4j.wml.R) {
            org.docx4j.wml.R  run = (org.docx4j.wml.R)o;
            walkList(run.getRunContent());         
         }
      }
   }


In the example above, every Textfield which has [Name] as Value will be replaced. This example works only on documents without tables.

Does anybody know who I can get into tables to find Text-Object within them?

Re: Replace text into docx within a table

PostPosted: Sat Aug 09, 2008 11:47 pm
by jason
Click here for a change which shows you how to do it.

A table is a block level element (sibling of p), so first you need to handle it in walkJAXBElements:

Code: Select all
if ( ((JAXBElement)o).getDeclaredType().getName().equals("org.docx4j.wml.Tbl") ) {
               org.docx4j.wml.Tbl tbl = (org.docx4j.wml.Tbl)((JAXBElement)o).getValue();
               describeTable(tbl);
            }


And then here is what you can do with the Tbl:

Code: Select all
   static void describeTable( org.docx4j.wml.Tbl tbl ) {
      
      // What does a table look like?
      boolean suppressDeclaration = false;
      boolean prettyprint = true;
      System.out.println( org.docx4j.XmlUtils.marshaltoString(tbl, suppressDeclaration, prettyprint) );
      
      // Could get the TblPr if we wanted them
       org.docx4j.wml.TblPr tblPr = tbl.getTblPr();
      
       // Could get the TblGrid if we wanted it
       org.docx4j.wml.TblGrid tblGrid = tbl.getTblGrid();
      
       // But here, let's look at the table contents
       for (Object o : tbl.getEGContentRowContent() ) {
         
          if (o instanceof org.docx4j.wml.Tr) {
            
             org.docx4j.wml.Tr tr = (org.docx4j.wml.Tr)o;
            
             for (Object o2 : tr.getEGContentCellContent() ) {
               
                  System.out.println("  " + o2.getClass().getName() );
                  if ( o2 instanceof javax.xml.bind.JAXBElement) {
                     
                     if ( ((JAXBElement)o2).getDeclaredType().getName().equals("org.docx4j.wml.Tc") ) {
                        org.docx4j.wml.Tc tc = (org.docx4j.wml.Tc)((JAXBElement)o2).getValue();
                        
                        // Look at the paragraphs in the tc
                        walkJAXBElements( tc.getEGBlockLevelElts() );
                        
                     } else {
                        // What is it, if it isn't a Tc?
                        System.out.println("      " +  ((JAXBElement)o).getName() );
                        System.out.println("      " +  ((JAXBElement)o).getDeclaredType().getName());
                     }
                  } else {
                     System.out.println("  " + o.getClass().getName() );                     
                  }
             }
          } else {
            System.out.println("  " + o.getClass().getName() );
          }
         
       }
   }


Hope this helps.

cheers .. Jason