'How can I set the complete page background for a Word page with Apache POI?
I have already searched all day today, but without success. First I created a new Word document and tried to set the background with
//Blank Document
XWPFDocument doc = new XWPFDocument();
//Write the Document in file system
FileOutputStream out = new FileOutputStream(new File("test.docx"));
File backgroundImage = new File("img.png");
doc.getDocument().addNewBackground().addNewDrawing().save(backgroundImage);
backgroundImage
is the picture I want to set.
Solution 1:[1]
Your question seems to be about add, change, or delete the background color in Word.
This consists of two settings.
First, display-background-shape must be enabled in document settings .
Second, the document must have set background having a color. This might be white but must be set.
Then optional a picture reference can be set. That picture then gets used as background tile. Microsoft Word itself still uses VML to set the picture reference to background. This is much simpler than using a drawing. Although using a drawing in CTBackground
is possible according Office Open XML specifications, I've never seen this in practical usage until now.
Nothing of that is supported by the high level class layer of apache poi
. But it can be solved using the low level org.openxmlformats.schemas.wordprocessingml.x2006.main.*
classes.
One more challenge is to get the XWPFSettings
. There is not a getter method. So we need using reflection to get it from XWPFDocument
. Same for to get CTSettings
from XWPFSettings
then.
Following complete example shows how to set background color and/or background tile picture. The code is tested and works using current apache po 5.2.0
and poi-ooxml-full-5.2.0.jar
.
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
public class CreateWordPageBackground {
static XWPFSettings getSettings(XWPFDocument document) throws Exception {
java.lang.reflect.Field settings = XWPFDocument.class.getDeclaredField("settings");
settings.setAccessible(true);
return (XWPFSettings)settings.get(document);
}
static void setDisplayBackgroundShape(XWPFSettings settings, boolean booleanOnOff) throws Exception {
java.lang.reflect.Field _ctSettings = XWPFSettings.class.getDeclaredField("ctSettings");
_ctSettings.setAccessible(true);
CTSettings ctSettings = (CTSettings )_ctSettings.get(settings);
CTOnOff onOff = CTOnOff.Factory.newInstance();
onOff.setVal(booleanOnOff);
ctSettings.setDisplayBackgroundShape(onOff);
}
static void setBackgroundPictureId(CTBackground background, String rId) throws Exception {
String vmlBackgroundXML = ""
+ "<v:background xmlns:v=\"urn:schemas-microsoft-com:vml\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" "
+ "xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" "
+ "id=\"_x0000_s1025\" o:bwmode=\"white\" o:targetscreensize=\"1024,768\">"
+ "<v:fill r:id=\"" + rId + "\" recolor=\"t\" type=\"frame\"/>"
+ "</v:background>"
;
org.apache.xmlbeans.XmlObject vmlBackgroundXmlObject = org.apache.xmlbeans.XmlObject.Factory.parse(vmlBackgroundXML);
background.set(vmlBackgroundXmlObject);
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument();
// we need document settings to set display-background-shape
XWPFSettings settings = getSettings(document);
setDisplayBackgroundShape(settings, true);
// set a background color
CTBackground background = document.getDocument().addNewBackground();
background.setColor("FF0000");
// crate a picture reference in document
InputStream is = new FileInputStream("./logo.png");
String rId = document.addPictureData(is, Document.PICTURE_TYPE_PNG);
// set a background picture
setBackgroundPictureId(background, rId);
background.setColor("FFFFFF");
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("Text in Body ...");
paragraph = document.createParagraph();
FileOutputStream out = new FileOutputStream("./CreateWordPageBackground.docx");
document.write(out);
out.close();
document.close();
}
}
Both, background color as well as background tile picture, only gets visible in Microsoft Word GUI. It not gets printed.
If the need is a printed page background, then this will be resolved by a shape in the page header, also known as watermark. But this is another question then.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |