0

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>
Monarch Wadia
  • 4,400
  • 4
  • 36
  • 37
  • Did you select all then hit F9 to update fields? – JasonPlutext Sep 06 '14 at 03:10
  • That worked! Is there any way to skip the Select All & F9 Step? The documents are ultimately going to auto-generated and used by end-users, and we'd like to reduce complexity as much as possible. – Monarch Wadia Sep 06 '14 at 15:07
  • As per the other comment in the sample FieldINCLUDEPICTURE.java, you can avoid that by adding the w:pict (or a w:drawing) after the field separator (like the XML you have above); look at the docx4j ImageAdd sample for how to do that. – JasonPlutext Sep 06 '14 at 21:36

2 Answers2

1

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.

JasonPlutext
  • 15,352
  • 4
  • 44
  • 84
  • thank you so much for the quick update...!!!! I am checking this out right now!! I really appreciate you updating your source for this use case in I think less than 1 hour? :-) – Monarch Wadia Sep 06 '14 at 01:11
  • Hello Jason, This doesn't seem to be working with files located on the internet. What might I be doing wrong? Pasting my code below. – Monarch Wadia Sep 06 '14 at 01:27
0

I am also trying to insert image programatically for remote link and I am failed to achieve desired results without manually updating links on word 2010.

public class FieldINCLUDEPICTURE {

  public static void main(String[] args) throws Exception {
    boolean save = true; 

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
    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:");

    String url = "http://www.springsoftware.co.uk/spring/images/sampledata/itcg.png";

        P p = new P();
//      p.getContent().add(
//              createSimpleField( " INCLUDEPICTURE  \"file:///C:/Users/jharrop/git/plutext/docx4j/src/test/resources/images/greentick.png\"  \\* MERGEFORMAT ")
    //          );
//      mdp.getContent().add(p);
    mdp.createParagraphOfText("complex field:");

    //addComplexField(p, "INCLUDEPICTURE  \"" + url + "\"" + " \\* MERGEFORMAT \\d");
    addComplexField(p, " INCLUDEPICTURE  \"" + url + "\"  \\* MERGEFORMAT \\d");

    mdp.getContent().add(p);

    //addComplexField(p, " INCLUDEPICTURE  \"" + attachmentRequestURL + "\"" + " \\* MERGEFORMAT \\d");

    // Pretty print the main document part
    System.out.println(
            XmlUtils.marshaltoString(mdp.getJaxbElement(), true, true));

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

    // Image 1: no width specified
    P p1 = newImage(wordMLPackage, url, filenameHint, altText, id1, id2);

    addComplexField(p1,url);

    // Optionally save it
    if (save) {
        String filename = System.getProperty("user.dir") + "/OUT_FieldINCLUDEPICTURE.docx";
        wordMLPackage.save(new java.io.File(filename) );
        System.out.println("Saved " + filename);
    }

}

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);

}


/**
 * Create image, without specifying width
 */
public static P newImage(WordprocessingMLPackage wordMLPackage, String url, String filenameHint, String altText, int id1, int id2) throws Exception {

    BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createLinkedImagePart(wordMLPackage, new URL(url));

    Inline inline = imagePart.createImageInline(filenameHint, altText, id1, id2, true);

    // Now add the inline in w:p/w:r/w:drawing
    org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
    P p = factory.createP();
    R run = factory.createR();
    p.getContent().add(run);
    org.docx4j.wml.Drawing drawing = factory.createDrawing();
    run.getContent().add(drawing);
    drawing.getAnchorOrInline().add(inline);

    return p;

}

}
Micho
  • 3,929
  • 13
  • 37
  • 40