如何使用 Apache POI 为 Word 页面设置完整的页面背景?

How can I set the complete page background for a Word page with Apache POI?

今天已经找了一整天了,还是没有找到。首先我创建了一个新的Word文档并尝试将背景设置为

 //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是我要设置的图片

您的问题似乎是关于 add, change, or delete the background color in Word

这包括两个设置。

首先,必须在文档设置中启用display-background-shape。

其次,文档必须设置有颜色的背景。这可能是白色的,但必须设置。

然后可以设置可选的图片参考。该图片然后被用作背景图块。 Microsoft Word 本身仍然使用 VML 将图片引用设置为背景。这比使用绘图要简单得多。尽管根据 Office Open XML 规范可以使用 CTBackground 中的绘图,但直到现在我还从未在实际使用中看到过这种情况。

apache poi 的高级 class 层不支持这些。但是可以用低级org.openxmlformats.schemas.wordprocessingml.x2006.main.*classes.

解决

另一个挑战是获得XWPFSettings。没有 getter 方法。所以我们需要使用反射从 XWPFDocument 中获取它。然后从 XWPFSettings 得到 CTSettings 同样。

以下完整示例显示了如何设置背景颜色and/or 背景图块图片。该代码已经过测试,可以使用当前的 apache po 5.2.0poi-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();
 }
}

背景颜色和背景图块图片都只在 Microsoft Word GUI 中可见。它不会被打印出来。

如果需要打印的页面背景,那么这将通过页眉中的形状(也称为水印)来解决。但这是另一个问题。