feiyu02
2024-11-19 752e00503f672ddfe2066afb6c235721a3a912b5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package cn.flightfeather.supervision.docx4j.simpleDemo;
 
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.vml.CTFill;
import org.docx4j.wml.CTBackground;
import org.docx4j.wml.ObjectFactory;
 
import javax.xml.bind.JAXBElement;
import java.io.File;
import java.io.IOException;
 
/*
 * 
 * Add w:document/w:background;  note that this is only visible in Windows Explorer file preview, or
 * Word's "Web layout" and "Full screen reading" document views (ie not Print Layout, Outline,
 * or Draft).  Checking Word options > Display > Printing options > Print background colors and images
 * makes no difference to what you see in Print Layout, but it does change what you see in Print Preview.
 * 
 * This is different to a watermark, which is set via the headers (see WatermarkPicture sample for that),
 * which is probably what you want.
 * 
 * From [MS-OI29500]:
 * 
 * a. The standard states that any element from the VML namespace or the drawingML namespace 
 *    is allowed as a child of the background element.
 *    
 *    Word renders any drawingML specified as a background at the beginning of the document and not as a background.
 */
public class BackgroundImage {
 
 
    static String DOCX_OUT; 
    
    public static void main(String[] args) throws Exception
    {
        
        // The image to add
        imageFile = new File(System.getProperty("user.dir") + "/src/test/resources/images/greentick.png" );  
        
        // Save it to
        DOCX_OUT = System.getProperty("user.dir") + "/OUT_BackgroundImage.docx";
 
        BackgroundImage sample = new BackgroundImage();
        sample.addBackground();
    }
 
    static ObjectFactory factory = Context.getWmlObjectFactory();
    static File imageFile; 
    
    private byte[] image;    
    private WordprocessingMLPackage wordMLPackage;
    
    public void addBackground() throws Exception
    {
        
        image = this.getImage();
 
        wordMLPackage = WordprocessingMLPackage.createPackage();
        
        BinaryPartAbstractImage imagePartBG = BinaryPartAbstractImage.createImagePart(wordMLPackage, image);
 
        wordMLPackage.getMainDocumentPart().getJaxbElement().setBackground(
                createBackground(
                        imagePartBG.getRelLast().getId())); 
 
        wordMLPackage.getMainDocumentPart().addParagraphOfText("To see your background, go to 'Web layout' or 'Full screen reading' document view!");
        
        File f = new File(DOCX_OUT);
        wordMLPackage.save(f);
 
    }
    
    private static CTBackground createBackground(String rId) {
 
        ObjectFactory wmlObjectFactory = new ObjectFactory();
 
        CTBackground background = wmlObjectFactory.createCTBackground();
        background.setColor("FFFFFF");
        org.docx4j.vml.ObjectFactory vmlObjectFactory = new org.docx4j.vml.ObjectFactory();
        // Create object for background (wrapped in JAXBElement)
        org.docx4j.vml.CTBackground background2 = vmlObjectFactory
                .createCTBackground();
        JAXBElement<org.docx4j.vml.CTBackground> backgroundWrapped = vmlObjectFactory
                .createBackground(background2);
        background.getAnyAndAny().add(backgroundWrapped);
        background2.setTargetscreensize("1024,768");
        background2.setVmlId("_x0000_s1025");
        background2.setBwmode(org.docx4j.vml.officedrawing.STBWMode.WHITE);
        // Create object for fill
        CTFill fill = vmlObjectFactory.createCTFill();
        background2.setFill(fill);
        fill.setTitle("Alien 1");
        fill.setId(rId);
        fill.setType(org.docx4j.vml.STFillType.FRAME);
        fill.setRecolor(org.docx4j.vml.STTrueFalse.T);
 
        return background;
    }
 
    private byte[] getImage() throws IOException {
    
        // Our utility method wants that as a byte array
        java.io.InputStream is = new java.io.FileInputStream(imageFile );
        long length = imageFile.length();    
        // You cannot create an array using a long type.
        // It needs to be an int type.
        if (length > Integer.MAX_VALUE) {
            System.out.println("File too large!!");
        }
        byte[] bytes = new byte[(int)length];
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length
               && (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0) {
            offset += numRead;
        }
        // Ensure all the bytes have been read in
        if (offset < bytes.length) {
            System.out.println("Could not completely read file "+imageFile.getName());
        }
        is.close();
        
        return bytes;
    }
 
 
}