Search code examples
javaapache-poidocx

How to add background image to docx document through apache poi?


How i can add background image to docx document through Apache POI or other java framework. I would like have some xml block, where defined background, in result document like that

<w:document xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 wp14">
<w:background w:color="FFFFFF">
    <v:background id="_x0000_s1025" o:bwmode="white" o:targetscreensize="1024,768">
        <v:fill r:id="rId2" o:title="Alien 1" recolor="t" type="frame"/>
    </v:background>
</w:background>
<w:body>
      .....
</w:body></w:document>

Solution

  • Assuming you want to add a background element to the root of the document, you'll need to do something like:

    XWPFDocument doc = new XWPFDocument(OPCPackage.open("test.docx"));
    if (doc.getDocument().getBackground() == null) {
       doc.getDocument.addNewBackground();
    };
    
    CTBackground bkgnd = doc.getDocument().getBackground();
    bkgnd.setColor("FFFFFF");
    

    Now, to add your new background into the backgrounds list, which is in a different namespace, it's a bit trickier. We'd do something like:

    String xml = 
      "<v:background id=\"_x0000_s1025\" o:bwmode=\"white\" o:targetscreensize=\"1024,768\">" +
      "<v:fill r:id=\"rId2\" o:title=\"Alien 1\" recolor=\"t\" type=\"frame\"/>" +
      "</v:background>";
    bkgnd.set(XmlToken.Factory.parse(xml));
    

    If you look in something like XWPFRun you'll see an example of adding in xml from a different namespace. Were it all in the .docx namespace you could do it all with the CT Objects, but sadly yours is a complicated case...

    If the manual XML stuff is a bit fiddly for you, try using POI to process a file with that added in by Word, and play around with the CTBackground object. That might let you work out the xmlbeans object for the inner v:background xml, which would offer up a simpler way of doing it. If you get it working, send in patch to POI!