Page 1 of 1

Add caption to image

PostPosted: Thu Apr 24, 2014 12:52 am
by jarod
Hi,
I'd like to programmatically add a caption to an image that is also inserted using docx4j.
So far I am using an example based on the code given in http://vixmemon.blogspot.com/2013/04/do ... -with.html.
It works fine to add the image in the document.

Now I want to customize the image, first I am setting the size of the image by adding the following lines in the private "P addInlineImageToParagraph(Inline inline, P paragraph)" method (the size values are just for testing..):
Code: Select all
CTPositiveSize2D ctPositiveSize2D = new CTPositiveSize2D();
           ctPositiveSize2D.setCx(4300*1000);
           ctPositiveSize2D.setCy(inline.getExtent().getCy());
          inline.setExtent(ctPositiveSize2D);


So now I would like to add a caption to this image. I was expecting a similar solution, but could not find any documentation or example to do so.

I found that there is an CTCaption object which I created using:
Code: Select all
CTCaption caption = factory.createCTCaption();
      caption.setName("Test");

But I could not find the way to link/insert this caption (in)to the image.

Does someone have any clues that could guide me?

From testing around I saw that the XML data of a caption of a figure looks like this:
Code: Select all
<w:p w:rsidR="005E10CD" w:rsidRPr="005E10CD" w:rsidRDefault="008C679D" w:rsidP="002F3885"><w:pPr><w:pStyle w:val="Caption"/><w:jc w:val="center"/></w:pPr><w:r><w:t xml:space="preserve">Figure </w:t></w:r><w:fldSimple w:instr=" SEQ Figure \* ARABIC "><w:r w:rsidR="005E10CD"><w:rPr><w:noProof/></w:rPr><w:t>1</w:t></w:r></w:fldSimple><w:r><w:t xml:space="preserve"> </w:t></w:r><w:r w:rsidR="005E10CD"><w:t>–</w:t></w:r><w:r><w:t xml:space="preserve"> My Caption</w:t></w:r>
<w:bookmarkStart w:id="0" w:name="_GoBack"/><w:bookmarkEnd w:id="0"/></w:p>

Re: Add caption to image

PostPosted: Fri Apr 25, 2014 8:19 pm
by jarod
Hi again,
I actually found the solution myself using your VERY nice tool to generate code from docx (that's insanely useful!!) http://www.docx4java.org/blog/2013/05/d ... eneration/

So now, about figure or table captions in word, if my understanding is correct, the caption is not closely linked to the picture, but simply the fact that the caption is just above or below the picture suffices to make the whole references work. So basically, a caption is nothing more than a reference to a given place in the document. Knowing this and using the code generation tool on a document that had a single figure with a caption, I obtained the function that generates a caption.

Code: Select all
public P createIt() {

      org.docx4j.wml.ObjectFactory wmlObjectFactory = new org.docx4j.wml.ObjectFactory();

      P p = wmlObjectFactory.createP();
      // Create object for r
      R r = wmlObjectFactory.createR();
      p.getContent().add(r);
      // Create object for t (wrapped in JAXBElement)
      Text text = wmlObjectFactory.createText();
      JAXBElement<org.docx4j.wml.Text> textWrapped = wmlObjectFactory
            .createRT(text);
      r.getContent().add(textWrapped);
      text.setValue("Figure ");
      text.setSpace("preserve");
      // Create object for fldSimple (wrapped in JAXBElement)
      CTSimpleField simplefield = wmlObjectFactory.createCTSimpleField();
      JAXBElement<org.docx4j.wml.CTSimpleField> simplefieldWrapped = wmlObjectFactory
            .createPFldSimple(simplefield);
      p.getContent().add(simplefieldWrapped);
      // Create object for r
      R r2 = wmlObjectFactory.createR();
      simplefield.getContent().add(r2);
      // Create object for t (wrapped in JAXBElement)
      Text text2 = wmlObjectFactory.createText();
      JAXBElement<org.docx4j.wml.Text> textWrapped2 = wmlObjectFactory
            .createRT(text2);
      r2.getContent().add(textWrapped2);
      text2.setValue("1");
      // Create object for rPr
      RPr rpr = wmlObjectFactory.createRPr();
      r2.setRPr(rpr);
      // Create object for noProof
      BooleanDefaultTrue booleandefaulttrue = wmlObjectFactory
            .createBooleanDefaultTrue();
      rpr.setNoProof(booleandefaulttrue);
      simplefield.setInstr(" SEQ Figure \\* ARABIC ");
      // Create object for r
      R r3 = wmlObjectFactory.createR();
      p.getContent().add(r3);
      // Create object for t (wrapped in JAXBElement)
      Text text3 = wmlObjectFactory.createText();
      JAXBElement<org.docx4j.wml.Text> textWrapped3 = wmlObjectFactory
            .createRT(text3);
      r3.getContent().add(textWrapped3);
      text3.setValue(" ");
      text3.setSpace("preserve");
      // Create object for r
      R r4 = wmlObjectFactory.createR();
      p.getContent().add(r4);
      // Create object for t (wrapped in JAXBElement)
      Text text4 = wmlObjectFactory.createText();
      JAXBElement<org.docx4j.wml.Text> textWrapped4 = wmlObjectFactory
            .createRT(text4);
      r4.getContent().add(textWrapped4);
      text4.setValue("–");
      // Create object for r
      R r5 = wmlObjectFactory.createR();
      p.getContent().add(r5);
      // Create object for t (wrapped in JAXBElement)
      Text text5 = wmlObjectFactory.createText();
      JAXBElement<org.docx4j.wml.Text> textWrapped5 = wmlObjectFactory
            .createRT(text5);
      r5.getContent().add(textWrapped5);
      text5.setValue("This is the caption of the figure");
      text5.setSpace("preserve");
      // Create object for bookmarkStart (wrapped in JAXBElement)
      CTBookmark bookmark = wmlObjectFactory.createCTBookmark();
      JAXBElement<org.docx4j.wml.CTBookmark> bookmarkWrapped = wmlObjectFactory
            .createPBookmarkStart(bookmark);
      p.getContent().add(bookmarkWrapped);
      bookmark.setName("_GoBack");
      bookmark.setId(BigInteger.valueOf(0));
      // Create object for bookmarkEnd (wrapped in JAXBElement)
      CTMarkupRange markuprange = wmlObjectFactory.createCTMarkupRange();
      JAXBElement<org.docx4j.wml.CTMarkupRange> markuprangeWrapped = wmlObjectFactory
            .createPBookmarkEnd(markuprange);
      p.getContent().add(markuprangeWrapped);
      markuprange.setId(BigInteger.valueOf(0));
      // Create object for pPr
      PPr ppr = wmlObjectFactory.createPPr();
      p.setPPr(ppr);
      // Create object for pStyle
      PPrBase.PStyle pprbasepstyle = wmlObjectFactory.createPPrBasePStyle();
      ppr.setPStyle(pprbasepstyle);
      pprbasepstyle.setVal("Caption");
      // Create object for jc
      Jc jc = wmlObjectFactory.createJc();
      ppr.setJc(jc);
      jc.setVal(org.docx4j.wml.JcEnumeration.CENTER);

      return p;
   }


From there the only thing to do is to put the create P (paragraph) just before or after the paragraph created for the figure.

So problem solved!!
Thanks for this blog and the tool!
Cheers