Search code examples
javaxmlimageapache-poicenter

Image in front of text - CENTER


I have the following XML

    CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
    long width = drawing.getInlineArray(0).getExtent().getCx();
    long height = drawing.getInlineArray(0).getExtent().getCy();
        String anchorXML = "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
            +"simplePos=\"0\" relativeHeight=\"0\" behindDoc=\""+((behind)?1:0)+"\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
            +"<wp:simplePos x=\"0\" y=\"0\"/>"
            +"<wp:positionH relativeFrom=\"column\"><wp:posOffset>0</wp:posOffset></wp:positionH>"
            +"<wp:positionV relativeFrom=\"paragraph\"><wp:posOffset>0</wp:posOffset></wp:positionV>"
            +"<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>"
            +"<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>";

    drawing = CTDrawing.Factory.parse(anchorXML);
    CTAnchor anchor = drawing.getAnchorArray(0);
    anchor.setGraphic(graphicalobject);
    return anchor;  

found here at Wrap Text in Apache POI(docx)?

But for some reason I can't position the image correctly, how do I CENTER it?


Solution

  • How to get usable XML for this?

    All Office Open XML files (so also *.docx) simply are ZIP archives. So one can unzip a *.docx file and have a look into. In that ZIP archive you will find a /word/document.xml containing the XML for the document.

    So create what you want using Microsoft Word, save the *.docx file, unzip the *.docx file and have a look at what /word/document.xml contains.

    In addition, you can use available specifications to read what that XML is supposed to mean. For example learn.microsoft.com and/or ECMA-376 Office Open XML file formats.

    For a horizontally centered picture for example, you will find something like :

    <wp:anchor … >  
      <wp:positionH relativeFrom="page">  
        <wp:align>center</wp:align>  
      </wp:positionH>  
      …  
    </wp:anchor>  
    

    Then try recreating this using code.

    Example:

    import java.io.*;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.apache.poi.util.Units;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
    import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObject;
    import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
    
    public class CreateWordImageAtCenterOfPage {
    
     private static CTAnchor getAnchorWithGraphic(CTDrawing drawing /*inline drawing*/ , 
      String drawingDescr, boolean behind, String relFromH, String alignH, String relFromV, String alignV) throws Exception {
    
      CTGraphicalObject graphicalobject = drawing.getInlineArray(0).getGraphic();
      long width = drawing.getInlineArray(0).getExtent().getCx();
      long height = drawing.getInlineArray(0).getExtent().getCy();
    
      String anchorXML = 
       "<wp:anchor xmlns:wp=\"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing\" "
      +"simplePos=\"0\" relativeHeight=\"0\" behindDoc=\""+((behind)?1:0)+"\" locked=\"0\" layoutInCell=\"1\" allowOverlap=\"1\">"
      +"<wp:simplePos x=\"0\" y=\"0\"/>"
      +"<wp:positionH relativeFrom=\""+relFromH+"\"><wp:align>"+alignH+"</wp:align></wp:positionH>"
      +"<wp:positionV relativeFrom=\""+relFromV+"\"><wp:align>"+alignV+"</wp:align></wp:positionV>"
      +"<wp:extent cx=\""+width+"\" cy=\""+height+"\"/>"
      +"<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>";
    
      drawing = CTDrawing.Factory.parse(anchorXML);
      CTAnchor anchor = drawing.getAnchorArray(0);
      anchor.setGraphic(graphicalobject);
      return anchor;  
     }
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument doc = new XWPFDocument();
      XWPFParagraph paragraph;
      XWPFRun run; 
      InputStream in;
      CTDrawing drawing;
      CTAnchor anchor;
    
      paragraph = doc.createParagraph();
      run = paragraph.createRun();
      run.setText("Picture at position center of page:");
    
      run = paragraph.createRun();
      in = new FileInputStream("samplePict.jpeg");
      int width = Units.toEMU(200);
      int height = Units.toEMU(200);
      run.addPicture(in, Document.PICTURE_TYPE_JPEG, "samplePict.jpeg", width, height);
      in.close();  
      drawing = run.getCTR().getDrawingArray(0);
    
      anchor = getAnchorWithGraphic(drawing, "samplePict.jpeg", false /*behind text*/, "page", "center", "page", "center");
    
      drawing.setAnchorArray(new CTAnchor[]{anchor});
      drawing.removeInline(0);
    
      paragraph = doc.createParagraph();
    
      FileOutputStream out = new FileOutputStream("./CreateWordImageAtCenterOfPage.docx");
      doc.write(out);
      out.close();
      doc.close();
    
     }
    }