Search code examples
javadocxdocx4j

Add a caption to an image with docx4j


i would like to link a caption to an image using docx4j.

BinaryPartAbstractImage imagePart;
imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);
Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, false);

ObjectFactory factory = new ObjectFactory();
P imageParagraph = factory.createP();
R run = factory.createR();
imageParagraph.getContent().add(run);
Drawing drawing = factory.createDrawing();
run.getContent().add(drawing);
drawing.getAnchorOrInline().add(inline);   

I have seen something link CTCaption but i don't know how to link it.


Solution

  • Word adds the caption as a sibling w:p following the one containing the image, using w:fldSimple for the numbering:

    <w:p>
      <w:r>
        <w:drawing>
          <wp:inline distT="0" distB="0" distL="0" distR="0" wp14:anchorId="27B5888C" wp14:editId="054E2550">
            <wp:extent cx="6010910" cy="2385060"/>
            <wp:effectExtent l="0" t="0" r="8890" b="0"/>
            <wp:docPr id="1" name="Picture 1" descr="Graphical user interface, text&#xA;&#xA;Description automatically generated"/>
            <wp:cNvGraphicFramePr>
              <a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
            </wp:cNvGraphicFramePr>
            <a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
              <a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
                <pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
                  <pic:nvPicPr>
                    <pic:cNvPr id="1" name="Picture 1" descr="Graphical user interface, text&#xA;&#xA;Description automatically generated"/>
                    <pic:cNvPicPr/>
                  </pic:nvPicPr>
                  <pic:blipFill>
                    <a:blip r:embed="rId4"/>
                    <a:stretch>
                      <a:fillRect/>
                    </a:stretch>
                  </pic:blipFill>
                  <pic:spPr>
                    <a:xfrm>
                      <a:off x="0" y="0"/>
                      <a:ext cx="6010910" cy="2385060"/>
                    </a:xfrm>
                    <a:prstGeom prst="rect">
                      <a:avLst/>
                    </a:prstGeom>
                  </pic:spPr>
                </pic:pic>
              </a:graphicData>
            </a:graphic>
          </wp:inline>
        </w:drawing>
      </w:r>
    </w:p>
    <w:p>
      <w:pPr>
        <w:pStyle w:val="Caption"/>
      </w:pPr>
      <w:r>
        <w:t xml:space="preserve">Figure </w:t>
      </w:r>
      <w:fldSimple w:instr=" SEQ Figure \* ARABIC ">
        <w:r>
          <w:rPr>
            <w:noProof/>
          </w:rPr>
          <w:t>1</w:t>
        </w:r>
      </w:fldSimple>
      <w:r>
        <w:t>YOUR CAPTION HERE</w:t>
      </w:r>
    </w:p>
    

    Indicative Java code for that w:p

        // Create object for p
        P p4 = wmlObjectFactory.createP(); 
        body.getContent().add( p4); 
            // Create object for r
            R r4 = wmlObjectFactory.createR(); 
            p4.getContent().add( r4); 
                // Create object for t (wrapped in JAXBElement) 
                Text text3 = wmlObjectFactory.createText(); 
                JAXBElement<org.docx4j.wml.Text> textWrapped3 = wmlObjectFactory.createRT(text3); 
                r4.getContent().add( textWrapped3); 
                    text3.setValue( "Figure "); 
                    text3.setSpace( "preserve"); 
            // Create object for r
            R r5 = wmlObjectFactory.createR(); 
            p4.getContent().add( r5); 
                // Create object for fldChar (wrapped in JAXBElement) 
                FldChar fldchar = wmlObjectFactory.createFldChar(); 
                JAXBElement<org.docx4j.wml.FldChar> fldcharWrapped = wmlObjectFactory.createRFldChar(fldchar); 
                r5.getContent().add( fldcharWrapped); 
                    fldchar.setFldCharType(org.docx4j.wml.STFldCharType.BEGIN);
            // Create object for r
            R r6 = wmlObjectFactory.createR(); 
            p4.getContent().add( r6); 
                // Create object for instrText (wrapped in JAXBElement) 
                Text text4 = wmlObjectFactory.createText(); 
                JAXBElement<org.docx4j.wml.Text> textWrapped4 = wmlObjectFactory.createRInstrText(text4); 
                r6.getContent().add( textWrapped4); 
                    text4.setValue( " SEQ Figure \\* ARABIC "); 
                    text4.setSpace( "preserve"); 
            // Create object for r
            R r7 = wmlObjectFactory.createR(); 
            p4.getContent().add( r7); 
                // Create object for fldChar (wrapped in JAXBElement) 
                FldChar fldchar2 = wmlObjectFactory.createFldChar(); 
                JAXBElement<org.docx4j.wml.FldChar> fldcharWrapped2 = wmlObjectFactory.createRFldChar(fldchar2); 
                r7.getContent().add( fldcharWrapped2); 
                    fldchar2.setFldCharType(org.docx4j.wml.STFldCharType.SEPARATE);
            // Create object for r
            R r8 = wmlObjectFactory.createR(); 
            p4.getContent().add( r8); 
                // Create object for t (wrapped in JAXBElement) 
                Text text5 = wmlObjectFactory.createText(); 
                JAXBElement<org.docx4j.wml.Text> textWrapped5 = wmlObjectFactory.createRT(text5); 
                r8.getContent().add( textWrapped5); 
                    text5.setValue( "1"); 
                // Create object for rPr
                RPr rpr3 = wmlObjectFactory.createRPr(); 
                r8.setRPr(rpr3); 
                    // Create object for noProof
                    BooleanDefaultTrue booleandefaulttrue3 = wmlObjectFactory.createBooleanDefaultTrue(); 
                    rpr3.setNoProof(booleandefaulttrue3); 
            // Create object for r
            R r9 = wmlObjectFactory.createR(); 
            p4.getContent().add( r9); 
                // Create object for fldChar (wrapped in JAXBElement) 
                FldChar fldchar3 = wmlObjectFactory.createFldChar(); 
                JAXBElement<org.docx4j.wml.FldChar> fldcharWrapped3 = wmlObjectFactory.createRFldChar(fldchar3); 
                r9.getContent().add( fldcharWrapped3); 
                    fldchar3.setFldCharType(org.docx4j.wml.STFldCharType.END);
                // Create object for rPr
                RPr rpr4 = wmlObjectFactory.createRPr(); 
                r9.setRPr(rpr4); 
                    // Create object for noProof
                    BooleanDefaultTrue booleandefaulttrue4 = wmlObjectFactory.createBooleanDefaultTrue(); 
                    rpr4.setNoProof(booleandefaulttrue4); 
            // Create object for r
            R r10 = wmlObjectFactory.createR(); 
            p4.getContent().add( r10); 
                // Create object for t (wrapped in JAXBElement) 
                Text text6 = wmlObjectFactory.createText(); 
                JAXBElement<org.docx4j.wml.Text> textWrapped6 = wmlObjectFactory.createRT(text6); 
                r10.getContent().add( textWrapped6); 
                    text6.setValue( "YOUR CAPTION HERE"); 
            // Create object for pPr
            PPr ppr2 = wmlObjectFactory.createPPr(); 
            p4.setPPr(ppr2); 
                // Create object for pStyle
                PPrBase.PStyle pprbasepstyle = wmlObjectFactory.createPPrBasePStyle(); 
                ppr2.setPStyle(pprbasepstyle); 
                    pprbasepstyle.setVal( "Caption");