5

I would like to create an unnumbered list with bullets using docx4j in my Word document. I have found the following code that is supposed to do the work. But whatever I try, the generated list is a numbered list! I use Word 2010, German version and docx4j-2.8.1.

    wordMLPackage = WordprocessingMLPackage.createPackage();

    ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
    P p = factory.createP();

    org.docx4j.wml.Text t = factory.createText();
    t.setValue(text);

    org.docx4j.wml.R run = factory.createR();
    run.getContent().add(t);

    p.getContent().add(run);

    org.docx4j.wml.PPr ppr = factory.createPPr();

    p.setPPr(ppr);

    // Create and add <w:numPr>
    NumPr numPr = factory.createPPrBaseNumPr();
    ppr.setNumPr(numPr);

    // The <w:ilvl> element
    Ilvl ilvlElement = factory.createPPrBaseNumPrIlvl();
    numPr.setIlvl(ilvlElement);
    ilvlElement.setVal(BigInteger.valueOf(0));

    // The <w:numId> element
    NumId numIdElement = factory.createPPrBaseNumPrNumId();
    numPr.setNumId(numIdElement);
    numIdElement.setVal(BigInteger.valueOf(1));

    wordMLPackage.getMainDocumentPart().addObject(p);

Can someone help me to generate a real unordered, buletted list?!

javac
  • 2,431
  • 4
  • 17
  • 26
LaDude
  • 1,383
  • 1
  • 11
  • 27

3 Answers3

4

Hope this helps you.

import org.docx4j.XmlUtils;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.wml.*;

import javax.xml.bind.JAXBException;
import java.io.File;
import java.math.BigInteger;


public class GenerateBulletedList {

private static final String BULLET_TEMPLATE ="<w:numbering xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">" +
        "<w:abstractNum w:abstractNumId=\"0\">" +
        "<w:nsid w:val=\"12D402B7\"/>" +
        "<w:multiLevelType w:val=\"hybridMultilevel\"/>" +
        "<w:tmpl w:val=\"AECAFC2E\"/>" +
        "<w:lvl w:ilvl=\"0\" w:tplc=\"04090001\">" +
        "<w:start w:val=\"1\"/>" +
        "<w:numFmt w:val=\"bullet\"/>" +
        "<w:lvlText w:val=\"\uF0B7\"/>" +
        "<w:lvlJc w:val=\"left\"/>" +
        "<w:pPr>" +
        "<w:ind w:left=\"360\" w:hanging=\"360\"/>" +
        "</w:pPr>" +
        "<w:rPr>" +
        "<w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:hint=\"default\"/>" +
        "</w:rPr>" +
        "</w:lvl>" +
        "</w:abstractNum>"+
        "<w:num w:numId=\"1\">" +
        "<w:abstractNumId w:val=\"0\"/>" +
        "</w:num>" +
        "</w:numbering>";

public static void main(String[] args) throws Exception{

    WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
    createBulletedList(wordMLPackage);
    wordMLPackage.save(new File("Output.docx"));
}

private static void createBulletedList(WordprocessingMLPackage wordMLPackage)throws Exception{
    NumberingDefinitionsPart ndp = new NumberingDefinitionsPart();
    wordMLPackage.getMainDocumentPart().addTargetPart(ndp);
    ndp.setJaxbElement((Numbering) XmlUtils.unmarshalString(BULLET_TEMPLATE));
    wordMLPackage.getMainDocumentPart().addObject(createParagraph("India"));
    wordMLPackage.getMainDocumentPart().addObject(createParagraph("United Kingdom"));
    wordMLPackage.getMainDocumentPart().addObject(createParagraph("France"));

}
private static P createParagraph(String country) throws JAXBException {

    ObjectFactory factory = new org.docx4j.wml.ObjectFactory();
    P p = factory.createP();
    String text =
            "<w:r xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">" +
                    " <w:rPr>" +
                    "<w:b/>" +
                    " <w:rFonts w:ascii=\"Arial\" w:cs=\"Arial\"/><w:sz w:val=\"16\"/>" +
                    " </w:rPr>" +
                    "<w:t>" + country + "</w:t>" +
                    "</w:r>";

    R r = (R) XmlUtils.unmarshalString(text);
    org.docx4j.wml.R run = factory.createR();
    run.getContent().add(r);

    p.getContent().add(run);
    org.docx4j.wml.PPr ppr = factory.createPPr();

    p.setPPr(ppr);
    // Create and add <w:numPr>
    PPrBase.NumPr numPr = factory.createPPrBaseNumPr();
    ppr.setNumPr(numPr);


    // The <w:numId> element
    PPrBase.NumPr.NumId numIdElement = factory.createPPrBaseNumPrNumId();
    numPr.setNumId(numIdElement);
    numIdElement.setVal(BigInteger.valueOf(1));
    return p;
}


}
NSNoob
  • 5,548
  • 6
  • 41
  • 54
  • [Not my downvote](http://imgur.com/a/j4oEl). Must be from someone who works in Java and thinks your answer is poor . – NSNoob Jul 28 '16 at 09:41
  • This is the only solution that I've had actually work, thank you! I did have to tweak the bullet template a bit to fit my setup though, namely by changing the numId near the bottom from 1 to 6. – Brian_Entei Mar 17 '23 at 18:20
1
private static P getBulletedParagraph(Text text, int i) {
    ObjectFactory objCreator = Context.getWmlObjectFactory(); // Object used to 
    create other Docx4j Objects
    P paragraph = objCreator.createP(); // create Paragraph object
    PPr ppr = objCreator.createPPr(); // create ppr
    NumPr numpr = objCreator.createPPrBaseNumPr();
    PStyle style = objCreator.createPPrBasePStyle();// create Pstyle
    NumId numId = objCreator.createPPrBaseNumPrNumId();
    numId.setVal(BigInteger.valueOf(6));
    numpr.setNumId(numId);
    R run = objCreator.createR();
    Br br = objCreator.createBr();
    run.getContent().add(text);

    Ilvl iLevel = objCreator.createPPrBaseNumPrIlvl(); // create Ilvl Object
    numpr.setIlvl(iLevel);
    iLevel.setVal(BigInteger.valueOf(i)); // Set ilvl value
    ppr.setNumPr(numpr);
    style.setVal("ListParagraph"); // set value to ListParagraph
    ppr.setPStyle(style);
    paragraph.setPPr(ppr);
    paragraph.getContent().add(run);
 // paragraph.getContent().add(br); Adds line breaks
    return paragraph;
}

I believe this is what you're looking for. This method will return you a paragraph object that has bullets. If you uncomment out the last line before returning paragraph, your paragraph object will also contain line breaks. If you didn't know, "Ilvl", or "eye-level" means indentation. Its the same as clicking the tab button when typing to a document the conventional way. Setting the ilvl element to 1 is the same as clicking tab 1 time. Setting it to 2 is the same as clicking the tab button 2 times, and so on. So it doesn't matter what number you give it. Although it will change the type of bullet you get. What really matters is the numid. Setting the numid to 6 will give you bullets instead of numbers. You will also need to set the PPr style to "ListParagraph". I hope this helps.

0

The code you have posted says "use list number 1, level 0".

Evidently that list is a numbered list.

Have a look in your numbering definitions part for a bulleted list, and use that one.

If you don't have a bulleted list there, you'll need to add it. You can upload a sample docx to the docx4j online demo, to have it generate appropriate content for you. Or see ListHelper for an example of how it can be done.

Tim Büthe
  • 62,884
  • 17
  • 92
  • 129
JasonPlutext
  • 15,352
  • 4
  • 44
  • 84
  • This stuff is now in a separate project: https://github.com/plutext/docx4j-ImportXHTML/blob/master/src/main/java/org/docx4j/convert/in/xhtml/ListHelper.java – JasonPlutext Feb 05 '15 at 09:51
  • 3
    Could you explain how you go from "use list number 1, level 0" to knowing it's a numbered list? – Daniel Oct 03 '17 at 19:21