Page 1 of 1

How to set table cell contents

PostPosted: Tue Nov 16, 2010 2:18 pm
by ashario
Hi all

Ive spent the past few hours installing and configuring docx4j and playing around with a few of the sample classes.

I'm now at the point where I have created a table and want to set the contents of a specific cell, but I'm struggling to work out how to do this.

I have created a table with 3 rows and 3 columns.

Code: Select all
// try some styles
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Title", "Hello world");
wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Heading1", "Heading 1");
wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Heading2", "Heading 2");
wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Heading3", "Heading 3");
wordMLPackage.getMainDocumentPart().addParagraphOfText("from docx4j!");

// add an image
File file = new File("e:\\temp\\login_cqms.jpg" );
byte bytes[] = new byte[(int) file.length()];
bytes = FileUtils.readFileToByteArray(file);

String filenameHint = null;
String altText = null;
int id1 = 0;
int id2 = 1;

org.docx4j.wml.P p = newImage( wordMLPackage, bytes, filenameHint, altText, id1, id2 );
wordMLPackage.getMainDocumentPart().addObject(p);

// create a table
int writableWidthTwips = wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();
Tbl tbl = TblFactory.createTable(3, 3, writableWidthTwips/3);
wordMLPackage.getMainDocumentPart().addObject(tbl);

String filePath = "e:\\temp\\docx4j.docx";
wordMLPackage.save(new java.io.File(filePath) );


How, for example
a. would I reference the 3rd column in the 1st row and set its text to 'this is the text'?
b. insert an embedded image into the 2nd cell of the 1st row (Ive already managed to insert an image into a document, just not into a specific cell)?

Any help much appreciated.

Re: How to set table cell contents

PostPosted: Tue Nov 16, 2010 3:56 pm
by jason
Welcome aboard :-)

Table rows:
Code: Select all
      List<Object> rows = tbl.getEGContentRowContent();


Note that that list can contain things other that row (org.docx4j.wml.Tr) objects.

Note also that your tr object might be wrapped in a JAXBElement (you can use XmlUtils.unwrap to get it).

Cells:
Code: Select all
      List<Object> cells = tr.getEGContentCellContent();


Similar comments apply.

To put something in a cell, access its contents list:

Code: Select all
tc.getEGBlockLevelElts()


For example code, see TableModel.java. (This pre-dates XmlUtils.unwrap, which could simplify the code by removing the "instanceof javax.xml.bind.JAXBElement" statements)

Remember, you can run any docx through OpenMainDocumentAndTraverse and/or PartsList to see its structure in docx4j terms.

hth .. Jason

Re: How to set table cell contents

PostPosted: Tue Nov 16, 2010 4:07 pm
by ashario
Thanks, yes that helps :)

Now, once i have a reference to a cell, how do I set its text contents, or add an object to it (ie like an image)?

I'm at the point where I can loop through rows and cells, but I'm sort of stumped as to how to 'add a text node' to a cell, so to speak.

Re: How to set table cell contents

PostPosted: Tue Nov 16, 2010 4:33 pm
by jason
tc.getEGBlockLevelElts().add(yourpara)

The tc has a content list, just like the document body. But to add text to a table cell, you have to add a paragraph yourpara containing the text. Similarly for an image.

Re: How to set table cell contents

PostPosted: Tue Nov 16, 2010 5:02 pm
by ashario
Ah, I get it now.

Pretty much any element can itself have multiple elements in it.

Thanks
Will try that out.

EDIT: Just in case anyone else is searching and wondering how to do this

Code: Select all
      int writableWidthTwips = wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().getWritableWidthTwips();
      Tbl tbl = TblFactory.createTable(3, 3, writableWidthTwips/3);

      ObjectFactory of = new ObjectFactory();

      List rows = tbl.getEGContentRowContent();
      Tr row = (Tr) rows.get(0);
      List cells = row.getEGContentCellContent();
      Tc tc = (Tc) cells.get(0);

      tc.getEGBlockLevelElts().add( wordMLPackage.getMainDocumentPart().createParagraphOfText("some text that goes in the cell") );



Mind you, I'm guessing most tables are created with 0 rows, and the developer creates them on the fly and adds them to the table. THat's my next challenge I guess :?

Re: How to set table cell contents

PostPosted: Wed Nov 17, 2010 6:24 pm
by ashario
ashario wrote:Mind you, I'm guessing most tables are created with 0 rows, and the developer creates them on the fly and adds them to the table. THat's my next challenge I guess :?

And that's where I seem to be falling over now.

I'm trying to work out how to programatically create an empty table, and then loop through a collection of data and create one table row per item. The code compiles and runs, but I have messed up something in the internal docx XML, because I get the error below when I attempt to open the docx created.

The file xxx cannot be opened because there are problems with its contents
Location : Part : /word/document.xml, Line: 1, Column 4040


The code causing the problem is my table generation code below. I'm trying to first create an empty table with 5 columns, then I create the 'header' row containing column headings. Lastly I'm trying to add rows, each row having 5 columns.

Code: Select all
      wordMLPackage.getMainDocumentPart().addStyledParagraphOfText("Heading2", "Credentialing Progress");
      Tbl tblCredProg = TblFactory.createTable(0, 5, writableWidthTwips/5);

      Tr thead = factory.createTr();
      addTc(thead, "Centre");
      addTc(thead, "Facility Questionnaire");
      addTc(thead, "Benchmarking");
      addTc(thead, "Site Visit");
      addTc(thead, "Overall Result");
      tblCredProg.getEGContentRowContent().add(thead);

      for (Iterator<TrialForm> it = credForms.iterator(); it.hasNext(); ) {
         TrialForm tf = it.next();
         Tr tr = factory.createTr();
         addTc(tr , tf.getAccrual().getSite().getSiteName());
         addTc(tr , tf.getSingleByReportingTag(ReportingTag.CRED_FAC_QUESTIONNAIRE));
         addTc(tr , tf.getSingleByReportingTag(ReportingTag.CRED_BENCHMARKING));
         addTc(tr , tf.getSingleByReportingTag(ReportingTag.CRED_SITE_VISIT));
         addTc(tr , tf.getSingleByReportingTag(ReportingTag.CRED_OVERALL_RESULT));

         tblCredProg.getEGContentRowContent().add(tr);
      }

      wordMLPackage.getMainDocumentPart().addObject(tblCredProg);


The getSingleByReportingTag() returns a String. The addTc() method is below

Code: Select all
protected void addTc(Tr tr, String text) {
   Tc tc = factory.createTc();
   tc.getEGBlockLevelElts().add( wordMLPackage.getMainDocumentPart().createParagraphOfText(text) );
   tr.getEGContentCellContent().add( tc );
}


If someone out there has an example of how to programatically create rows, then cells within each row, then add the rows to a table, that would be greatly appreciated.

Thanks

Re: How to set table cell contents

PostPosted: Wed Nov 17, 2010 6:34 pm
by ashario
Replacing the line

Code: Select all
Tbl tblCredProg = TblFactory.createTable(0, 5, writableWidthTwips/5);


with

Code: Select all
Tbl tblCredProg = factory.createTbl();


seemed to do the trick.

Re: How to set table cell contents

PostPosted: Fri May 04, 2012 10:12 pm
by IgorShevchenko
Hi,

I've add an image to the table cell like:
org.docx4j.wml.P p = newImage(wordMLPackage, bytes, filenameHint,altText, id1, id2);
tc.getEGBlockLevelElts().add(p);

Image was added successfully but "Enter" is added before the image. Seems that "\n" was added before the image.
It looks in a cell like:

-----------------
| |
| my_image |
-----------------

How can I delete the "\n" before the image?

Thanks,
Igor

Re: How to set table cell contents

PostPosted: Fri May 04, 2012 10:31 pm
by IgorShevchenko
The problem was solved,
Not relevant anymore.

Thanks,
Igor