Search code examples
apache-poiapache-poi-4

Set image position and tilt into a word .docx document using POI XWPF


I have added following picture in word document using XWPF addPicture ,

XWPFParagraph p3 = document.createParagraph();
XWPFRun r3 = p3.createRun();
imgFile = "C:\\poi-3.9\\pictures\\Picture4.jpeg";
try {
r3.addPicture(new FileInputStream(imgFile), format, imgFile, Units.toEMU(500), Units.toEMU(80)); // 200x200 pixels
}catch (Exception e){
  System.out.println (e.getMessage());
}

firstImage

Now I want to set it to a particular position and tilt it as well, so that it will look like this ...

enter image description here

Is there any way we can do it using XWPF run, or any other method. Thanks.


Solution

  • I solved it myself. Basically word document is a kind of zip file. If we rename the word file extension as .zip and open the document.xml file, we could see how the image is actually positioned using xml format. Here are the steps I took.

    1. Create a word document with the required image and set image position manually ()
    2. Rename the file extension as .zip from .docx , extract the zip file.
    3. Navigate and open document.xml which is present in the word folder of the extracted zip.
    4. Search of the image name (here my image name is picture4)
    5. Get the Horizontal and Vertical offset , extent cx and cy, relative height and other parameters position from the xml, I have marked them in bold in the xml snippet below.
    <w:body>
            <w:p>
                <w:bookmarkStart w:id="0" w:name="_GoBack"/>
                <w:bookmarkEnd w:id="0"/>
                <w:r>
                    <w:drawing>
                        <wp:anchor distT="0" distB="0" distL="**114300**" distR="**114300**" simplePos="0" relativeHeight="**251658240**" behindDoc="1" locked="0" layoutInCell="1" allowOverlap="1">
                            <wp:simplePos x="0" y="0"/>
                            <wp:positionH relativeFrom="column">
                                <wp:posOffset>**-2256790**</wp:posOffset>
                            </wp:positionH>
                            <wp:positionV relativeFrom="paragraph">
                                <wp:posOffset>**-1823085**</wp:posOffset>
                            </wp:positionV>
                            <wp:extent cx=**"3448050"** cy=**"3619500"**/>
                            <wp:effectExtent l="0" t="0" r="0" b="0"/>
                            <wp:wrapNone/>
                            <wp:docPr id="4" name="Drawing 0" descr="**Picture4**"/>
                            <wp:cNvGraphicFramePr>
    
    1. Set the same in anchor xml

      String anchorXML = "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" " +"distT=\"0\" distB=\"0\" distL=\"114300\" distR=\"114300\" simplePos=\"0\" relativeHeight=\"251658240\" behindDoc=\"1\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"

         +"<wp:simplePos x=\"0\" y=\"0\"/>"
      
         +"<wp:positionH relativeFrom=\"column\"><wp:posOffset>-1800000</wp:posOffset></wp:positionH>"
         +"<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>-1800000</wp:posOffset></wp:positionV>"
      
         + "<wp:extent cx=\"3448050\" cy=\"3619500\"/>"
         +"<wp:effectExtent l=\"0\" t=\"0\" r=\"6350\" b=\"6350\"/>"
         +"  <wp:simplePos x=\"0\" y=\"0\"/><wp:positionH relativeFrom=\"column\"><wp:posOffset>-1800000</wp:posOffset></wp:positionH><wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>-1800000</wp:posOffset></wp:positionV><wp:extent cx=\"3448050\" cy=\"3619500\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/><wp:wrapNone/> "
         +"<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>"
         +"</wp:anchor>"; 
      
    2. Here is sample code to add image and position, we can parameterize the method to set offset and other xml parameters.

       import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
       import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
       import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
       public class addImage extends XWPFDocument {
       public static void main(String[] args) throws IOException {`
      // Create a document file
                       CustomXWPFDocument document = new CustomXWPFDocument();
                       XWPFParagraph paragraphFourteenx = document.createParagraph();
                       XWPFRun paragraphFourteenRunx = paragraphFourteenx.createRun();
      
      
               // add picture four         
               //String imgFile = "C:\\pictures\\Picture4.jpeg";
               XWPFParagraph p3 = document.createParagraph();
               XWPFRun r3 = p3.createRun();
               imgFile = "C:\\Picture4.jpeg";
               try {
               r3.addPicture(new FileInputStream(imgFile), format, imgFile, Units.toEMU(250), Units.toEMU(250)); // 200x200 pixels
               }catch (Exception e){
                 System.out.println (e.getMessage());
               }
      
               try{
                CTDrawing drawing = r3.getCTR().getDrawingArray(0);
                 CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
                 CTAnchor anchor = getAnchorWithGraphic(graphicalobject, "Picture4", 
                                                        Units.toEMU(250), Units.toEMU(250), 
                                                        Units.toEMU(0), Units.toEMU(0),true);
                 drawing.setAnchorArray(new CTAnchor[]{anchor});
                 drawing.removeInline(0);
      
                 }catch (Exception e){
                 System.out.println (e.getMessage());
               }
      
                String anchorXML =          
                     "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
                    +"distT=\"0\" distB=\"0\" distL=\"114300\" distR=\"114300\" simplePos=\"0\" relativeHeight=\"251658240\" behindDoc=\"1\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
      
                     +"<wp:simplePos x=\"0\" y=\"0\"/>"
      
                     +"<wp:positionH relativeFrom=\"column\"><wp:posOffset>-1800000</wp:posOffset></wp:positionH>"
                     +"<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>-1800000</wp:posOffset></wp:positionV>"
      
                     + "<wp:extent cx=\"3448050\" cy=\"3619500\"/>"
                     +"<wp:effectExtent l=\"0\" t=\"0\" r=\"6350\" b=\"6350\"/>"
                     +"  <wp:simplePos x=\"0\" y=\"0\"/><wp:positionH relativeFrom=\"column\"><wp:posOffset>-1800000</wp:posOffset></wp:positionH><wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>-1800000</wp:posOffset></wp:positionV><wp:extent cx=\"3448050\" cy=\"3619500\"/><wp:effectExtent l=\"0\" t=\"0\" r=\"0\" b=\"0\"/><wp:wrapNone/> "
                     +"<wp:docPr id=\"1\" name=\"Drawing 0\" descr=\""+drawingDescr+"\"/><wp:cNvGraphicFramePr/>"
                     +"</wp:anchor>"; 
      
      
                CTDrawing drawing = CTDrawing.Factory.parse(anchorXML);
                 CTAnchor anchor = drawing.getAnchorArray(0);
                 anchor.setGraphic(graphicalobject);
      
           // stream output to file            
                       FileOutputStream outStream = null;
                       try {
                           double x = Math.random();
      
                           String fileName = "C:\\poi-3.9\\generateprequal\\output\\" + args[0] + ".docx";
                           outStream = new FileOutputStream(fileName);
                       } catch (FileNotFoundException e) {
                           System.out.println("First Catch");
                           e.printStackTrace();
                       }
                       try {
                           document.write(outStream);
                           outStream.close();
                       } catch (FileNotFoundException e) {
                           System.out.println("Second Catch");
                           e.printStackTrace();
                       } catch (IOException e) {
                           System.out.println("Third Catch");
                           e.printStackTrace();
                       }
                       }}