Search code examples
javams-worddocxdocx4j

Insert field codes into document using docx4java


Using Docx4J, how would I insert a fieldcode such as "INCLUDEPICTURE" into a document?

I need to use the \d switch for INCLUDEPICTURE.

UPDATE: This code isn't working when I insert an image from the internet. :-(

    boolean save = true; 

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(file);
    MainDocumentPart mdp = wordMLPackage.getMainDocumentPart();

    // Example 1: add text in Title style
    mdp.addStyledParagraphOfText("Title", "Select all, then hit F9 in Word to see your pictures, or programmatically add them first");

    mdp.createParagraphOfText("simple field:");

    P p = new P(); 
    p.getContent().add( 
            createSimpleField( " INCLUDEPICTURE  \"http://placehold.it/312x322\"  \\* MERGEFORMAT ")
            );
    mdp.getContent().add(p);

    mdp.createParagraphOfText("complex field:");

    p = new P(); 
    addComplexField(p, " INCLUDEPICTURE  \"http://placehold.it/312x322\"  \\* MERGEFORMAT ");
    mdp.getContent().add(p);

    wordMLPackage.save(file);


private static CTSimpleField createSimpleField(String val) {

    CTSimpleField field = new CTSimpleField();
    field.setInstr(val);
    return field;
}

private static void addComplexField(P p, String instrText) {

    org.docx4j.wml.ObjectFactory wmlObjectFactory = Context.getWmlObjectFactory();

    // Create object for r
    R r = wmlObjectFactory.createR(); 
    p.getContent().add( r); 
        // Create object for fldChar (wrapped in JAXBElement) 
        FldChar fldchar = wmlObjectFactory.createFldChar(); 
        JAXBElement<org.docx4j.wml.FldChar> fldcharWrapped = wmlObjectFactory.createRFldChar(fldchar); 
        r.getContent().add( fldcharWrapped); 
            fldchar.setFldCharType(org.docx4j.wml.STFldCharType.BEGIN);
        // Create object for instrText (wrapped in JAXBElement) 
        Text text = wmlObjectFactory.createText(); 
        JAXBElement<org.docx4j.wml.Text> textWrapped = wmlObjectFactory.createRInstrText(text); 
        r.getContent().add( textWrapped); 
            text.setValue( instrText); 
            text.setSpace( "preserve");     

        // Create object for fldChar (wrapped in JAXBElement) 
        fldchar = wmlObjectFactory.createFldChar(); 
        fldcharWrapped = wmlObjectFactory.createRFldChar(fldchar); 
        r.getContent().add( fldcharWrapped); 
            fldchar.setFldCharType(org.docx4j.wml.STFldCharType.END);

}

When I unqip the .docx and open up the document.xml, here is what I find:

<w:p>
  <w:pPr>
    <w:pStyle w:val="Title"/>
  </w:pPr>
  <w:r>
    <w:t>Select all, then hit F9 in Word to see your pictures, or programmatically add them first</w:t>
  </w:r>
</w:p>
<w:p>
  <w:fldSimple w:instr=" INCLUDEPICTURE  &quot;http://placehold.it/312x322&quot;  \* MERGEFORMAT "/>
</w:p>
<w:p>
  <w:r>
    <w:fldChar w:fldCharType="begin"/>
    <w:instrText xml:space="preserve">INCLUDEPICTURE  &quot;http://placehold.it/312x322&quot;  \* MERGEFORMAT </w:instrText>
    <w:fldChar w:fldCharType="end"/>
  </w:r>
</w:p>

However, this doesn't appear as an image on the document if I use an internet URL.

I tried inserting a field code using MS Word, and this is the code I got. This properly shows up as an image.

<w:p w14:paraId="43d51bd" w14:textId="43d51bd" w:rsidR="006549FC" w:rsidRDefault="00581431">
  <w:pPr>
    <w15:collapsed w:val="false"/>
  </w:pPr>
  <w:r>
    <w:fldChar w:fldCharType="begin"/>
  </w:r>
  <w:r>
    <w:instrText xml:space="preserve">INCLUDEPICTURE &quot;http://placehold.it/100x100&quot; \* MERGEFORMAT </w:instrText>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="separate"/>
  </w:r>
  <w:r>
    <w:pict>
      <v:shapetype coordsize="21600,21600" filled="f" id="_x0000_t75" o:preferrelative="t" o:spt="75.0" path="m@4@5l@4@11@9@11@9@5xe" stroked="f">
        <v:stroke joinstyle="miter"/>
        <v:formulas>
          <v:f eqn="if lineDrawn pixelLineWidth 0"/>
          <v:f eqn="sum @0 1 0"/>
          <v:f eqn="sum 0 0 @1"/>
          <v:f eqn="prod @2 1 2"/>
          <v:f eqn="prod @3 21600 pixelWidth"/>
          <v:f eqn="prod @3 21600 pixelHeight"/>
          <v:f eqn="sum @0 0 1"/>
          <v:f eqn="prod @6 1 2"/>
          <v:f eqn="prod @7 21600 pixelWidth"/>
          <v:f eqn="sum @8 21600 0"/>
          <v:f eqn="prod @7 21600 pixelHeight"/>
          <v:f eqn="sum @10 21600 0"/>
        </v:formulas>
        <v:path gradientshapeok="t" o:connecttype="rect" o:extrusionok="f"/>
        <o:lock aspectratio="t" v:ext="edit"/>
      </v:shapetype>
      <v:shape id="_x0000_i1025" style="width:100pt;height:100pt" type="#_x0000_t75">
        <v:imagedata r:href="rId6" r:id="rId5"/>
      </v:shape>
    </w:pict>
  </w:r>
  <w:r>
    <w:fldChar w:fldCharType="end"/>
  </w:r>
  <w:bookmarkEnd w:id="0"/>
</w:p>

Solution

  • See the new sample FieldINCLUDEPICTURE.java, which shows you how to add it as either a simple or complex field.

    I've left the \d switch as a presumably trivial exercise for the reader.

    Note that unless you actually add the field result, the picture won't show up in Word until you refresh the fields. Adding the picture programmatically to the field result is much the same as the addImage example.