How to set background color (Page Color) for word document (.doc or .docx) in Java?
Asked Answered
S

2

-1

By some libraries like http://poi.apache.org , we could create word document with any text color, but for background or highlight of the text, I didn't find any solution.

Page color for word in manual way!:

https://support.office.com/en-us/article/Change-the-background-or-color-of-a-document-6ce0b23e-b833-4421-b8c3-b3d637e62524

Here is my main code to create word document by poi.apache

        // Blank Document
        @SuppressWarnings("resource")
        XWPFDocument document = new XWPFDocument();
        // Write the Document in file system
        FileOutputStream out = new FileOutputStream(new File(file_address));
        // create Paragraph
        XWPFParagraph paragraph = document.createParagraph();
        paragraph.setAlignment(ParagraphAlignment.RIGHT);

        XWPFRun run = paragraph.createRun();
        run.setFontFamily(font_name);
        run.setFontSize(font_size);
        // This only set text color not background!
        run.setColor(hex_color);

        for (String s : text_array) {
            run.setText(s);
            run.addCarriageReturn();
        }

        document.write(out);
        out.close();
Sandoval answered 24/12, 2015 at 16:24 Comment(2)
Please find stcakoverflow answer #35420119Tiptop
@LearNer Thanks! Usually beginners are more responsive in this site!Sandoval
S
0

We Only need to add these 3 lines to set the background color for Word documents by XWPF. We have to set these lines after declaring XWPFRun and it's text color:

CTShd cTShd = run.getCTR().addNewRPr().addNewShd();
cTShd.setVal(STShd.CLEAR);
cTShd.setFill(hex_background_color);
Sandoval answered 3/12, 2016 at 16:45 Comment(1)
For the record: A much more elaborate version of this XWPF-based approach can be found in this answer.Eats
E
3

Update: XWPF is the newest way to create word document files, but setting background only possible by HWPF which is for old format version (.doc)

For *.doc (i.e. POI's HWPF component):

  1. Highlighting of text: Look into setHighlighted()

  2. Background color:

    I suppose you mean the background of a paragraph (AFAIK, Word also allows to color the entire page which is a different matter)

    There is setShading() which allows you to provide a foreground and background color (through setCvFore() and setCvBack() of SHDAbstractType) for a Paragraph. IIRC, it is the foreground that you would want to set in order to color your Paragraph. The background is only relevant for shadings which are composed of two (alternating) colors.

    The underlying data structure is named Shd80 ([MS-DOC], 2.9.248). There is also SHDOperand ([MS-DOC], 2.9.249) that reflects the functionality of Word prior to Word97. [MS-DOC] is the Binary Word File format specification which is freely available on MSDN.

Edit:

Here is some code to illustrate the above:

    try {
        HWPFDocument document = [...]; // comes from somewhere
        Range range = document.getRange();

        // Background shading of a paragraph
        ParagraphProperties pprops = new ParagraphProperties();
        ShadingDescriptor shd = new ShadingDescriptor();
        shd.setCvFore(Colorref.valueOfIco(0x07)); // yellow; ICO
        shd.setIpat(0x0001); // solid background; IPAT
        pprops.setShading(shd);
        Paragraph p1 = range.insertBefore(pprops, StyleSheet.NIL_STYLE);
        p1.insertBefore("shaded paragraph");

        // Highlighting of individual characters
        Paragraph p2 = range.insertBefore(new ParagraphProperties(), StyleSheet.NIL_STYLE);     
        CharacterRun cr = p2.insertBefore("highlighted text\r");
        cr.setHighlighted((byte) 0x06); // red; ICO

        document.write([...]); // document goes to somewhere
    } catch (IOException e) {   
        e.printStackTrace();
    }
  • ICO is a color structure
  • IPAT is a list of predefined shading styles
Eats answered 31/12, 2015 at 9:29 Comment(18)
Unfortunately, they only introduce methods by JavaDoc not real example! Could you answer me by code? support.office.com/en-us/article/…Sandoval
So you actually want to change the background of your document and not that of individual paragraphs?Eats
yes! But that's paragraph is also good enough if that page color isn't possible. :)Sandoval
Ok, I've added an example of the old Word format since this is what I started off with. Hope this helps. Coloring of the entire page is currently not possible using HWPF (would have to be handled on the Section-level).Eats
But I cannot figure out "getRange" function! Could you give me a clear instruction about importing libraries? I tried to import some other libraries but it didn't worked. for example: import org.apache.poi.hwpf.usermodel.Range;Sandoval
@Sandoval For HWPF you need to have both the core POI library and poi-scatchpad on your classpath. See here.Eats
I have this jar library: poi-3.13 which also has "poi-scatchpad-3.13-20150929.jar" But I cannot run your code, especially this line: Range range = document.getRange(); It's better to tell me which version of poi library you using and what you imported! My import was these but still it doesn't work! import org.apache.*; import org.apache.poi.*; import org.apache.poi.hwpf.*; import org.apache.poi.hwpf.usermodel.Range; and some other but it was useless!Sandoval
@Sandoval HWPFDocument.getRange() is a fundamental function of HWPF. I can see it in trunk, so it shouldn't really matter which version of POI you are using for this to work. Are you sure both the poi and the poi-scratchpad jar are on your classpath?Eats
@mondo I'm sure! I also downloaded poi-scratchpad-3.2-FINAL.jar independently and imported that too, which also has the same libraries which exist in main poi-3.13 Look at this picture I take from my libraries: oi66.tinypic.com/2ug2jjo.jpgSandoval
@Sandoval Don't use two scratchpads concurrently! - Besides that: What is the exact error you are getting? Do you have import org.apache.poi.hwpf.HWPFDocument; and import org.apache.poi.hwpf.usermodel.Range; in the respective source file? Eclipse (which you are obviously using) should either add those lines automatically or offer a quick fix to do so.Eats
@mondo I imported many of them and also those you suggested but still it doesn't recognize! I think it's better to show me a complete source code with the latest version of poi.apache.org. Here is the picture from my code which shows getRange() still is an error: oi65.tinypic.com/szx01j.jpgSandoval
@Sandoval Once again: What is the exact error your are getting? So what does Eclipse say when you hover that document.getRange() line? Your HWPFDocument.java should look exactly like this (you can confirm this by doing a CTRL+Click on HWPFDocument in Eclipse) and thus has the necessary getRange() method. Did you import the correct Range and not accidentally a class with the same name from some other unrelated package?Eats
@mondo When I hover on it, it says: "The method getRange() is undefined for the type XWPFDocument". I also imported all that libraries you linked but still it doesn't recognize getRange(). I'm using Java 8 and poi-3.13. I think it's better to show me a simple working source code for this problem! with respect! :)Sandoval
All of my imports for poi.apache: org.apache.poi.hwpf.model.Colorref; org.apache.poi.hwpf.model.StyleSheet; org.apache.poi.hwpf.usermodel.CharacterRun; import org.apache.poi.hwpf.usermodel.Paragraph; import org.apache.poi.hwpf.usermodel.ParagraphProperties; org.apache.poi.hwpf.usermodel.Range; org.apache.poi.hwpf.usermodel.ShadingDescriptor; org.apache.poi.xwpf.usermodel.ParagraphAlignment; org.apache.poi.xwpf.usermodel.XWPFDocument; org.apache.poi.xwpf.usermodel.XWPFParagraph; org.apache.poi.xwpf.usermodel.XWPFRun; org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;Sandoval
@Sandoval My code is for HWPF not XWPF (see the very first line of my initial answer)! Hence, we are dealing with an HWPFDocument and not an XWPFDocument. AFAIK the particular functionality you asked for (background + highlighting) is not available with XWPF. Or to but it bluntly: You can only do this for a *.doc file and not for *.docx.Eats
@mondo Thanks! So I have to ignore background color until they provide it! :)Sandoval
@bdshabab Your question was initially open regarding the file format (see your question title). If you had pointed out in the beginning that you need this explicitly for *.docx, you would have saved me from quite a bit of (apparently useless) work. So please be more specific next time! Other than that, I believe it wouldn't be too difficult to add your required functionality to XWPF - so consider crafting a patch. POI is open-source, after all.Eats
@mondo sorry about that! But your answer wasn't useless. Honestly, I'm beginner to work by these libraries (poi.apache) and I didn't know there is another way like HWPF. I saw a clear example in their site which illustrated by XWPF. (next time I hope, I could explain better, my friend! :) )Sandoval
S
0

We Only need to add these 3 lines to set the background color for Word documents by XWPF. We have to set these lines after declaring XWPFRun and it's text color:

CTShd cTShd = run.getCTR().addNewRPr().addNewShd();
cTShd.setVal(STShd.CLEAR);
cTShd.setFill(hex_background_color);
Sandoval answered 3/12, 2016 at 16:45 Comment(1)
For the record: A much more elaborate version of this XWPF-based approach can be found in this answer.Eats

© 2022 - 2024 — McMap. All rights reserved.