Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create multiLevel bullets and numbering from java using apache POI XWPFDocument?

I've read many blogs and forums related to my requirement, but till now I was able to generate bullet or numbering for first level with all the help I got. Can anyone guide me how to create a multilevel numbering using apache poi.

Wondering whether Apache POI XWPFDocument support such feature?

Below is what my requirement

  1. First Level
    • Second Level
    • Second Level
  2. First Level

Edit 1 :

Here is my sample code which works for single level numbering

    public class TestNumbering {
        String fileName=""; 
        InputStream in = null;
        CTAbstractNum abstractNum = null;
        public TestNumbering() {
            try {
                in = CreateWordDocument.class.getClassLoader().getResourceAsStream("numbering.xml");
                abstractNum = CTAbstractNum.Factory.parse(in);
            } catch (XmlException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public String createDocument(String fileName, String content) {
            this.fileName=fileName;
            XWPFDocument doc = new XWPFDocument();

            doc.createNumbering();
            XWPFNumbering numbering=null;
            numbering=doc.createNumbering();
            for(String value: content.split("@")) {
                XWPFParagraph para = doc.createParagraph();
                para.setVerticalAlignment(TextAlignment.CENTER);
                para.setNumID(addListStyle(abstractNum, doc, numbering));
                XWPFRun run=para.createRun();
                run.setText(value);
            }
            try {
                FileOutputStream out = new FileOutputStream(fileName);
                doc.write(out);
                out.close();
                in.close();
            } catch(Exception e) {}
            return null;
        }
        private BigInteger addListStyle(CTAbstractNum abstractNum, XWPFDocument doc, XWPFNumbering numbering) {
            try {

                XWPFAbstractNum abs = new XWPFAbstractNum(abstractNum, numbering);
                BigInteger id = BigInteger.valueOf(0);
                boolean found = false;
                while (!found) {
                    Object o = numbering.getAbstractNum(id);
                    found = (o == null);
                    if (!found)
                        id = id.add(BigInteger.ONE);
                }
                abs.getAbstractNum().setAbstractNumId(id);
                id = numbering.addAbstractNum(abs);
                return doc.getNumbering().addNum(id);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        public static void main(String[] args) throws Exception {
            String fileName="Test.docx";
            new TestNumbering().createDocument(fileName, "First Level@@Second Level@@Second Level@@First Level");
        }
    }

Also find below the numbering.xml

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">

    <w:abstractNum w:abstractNumId="0">
    <w:nsid w:val="3A6A237F"/>
    <w:multiLevelType w:val="hybridMultilevel"/>
    <w:tmpl w:val="5C9890C4"/>
    <w:lvl w:ilvl="0" w:tplc="0409000F"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="720" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="1" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%2."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1440" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="2" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%3."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="2160" w:hanging="180"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl>
    </w:abstractNum>

    <w:abstractNum w:abstractNumId="1">
    <w:nsid w:val="5E7736F6"/>
    <w:multiLevelType w:val="hybridMultilevel"/>
    <w:tmpl w:val="F602653C"/>
    <w:lvl w:ilvl="0" w:tplc="0409000F"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="720" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="1" w:tplc="04090001"><w:start w:val="1"/><w:numFmt w:val="bullet"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:hAnsi="Symbol" w:hint="default"/></w:rPr></w:lvl>
    <w:lvl w:ilvl="2" w:tplc="04090003"><w:start w:val="1"/><w:numFmt w:val="bullet"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2340" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:hAnsi="Courier New" w:hint="default"/></w:rPr></w:lvl>
    <w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl>
    <w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl>
    </w:abstractNum>

    <w:num w:numId="1"><w:abstractNumId w:val="1"/></w:num>
    <w:num w:numId="2"><w:abstractNumId w:val="0"/></w:num>

    </w:numbering>
like image 568
Athiappan Avatar asked Sep 28 '22 09:09

Athiappan


1 Answers

You are right Apache POI has the worst kind of documentation or you can say no documentation at all. So there is nothing much you can find except a few blogs.

Replace your for loop with:

for (String value : content.split("@")) {
            XWPFParagraph para = doc.createParagraph();
            para.setVerticalAlignment(TextAlignment.CENTER);
            para.setNumID(addListStyle(abstractNum, doc, numbering));
            if (value.contains("Second")) {
                para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
            }
            XWPFRun run = para.createRun();
            run.setText(value);
        }

Create a multi hierarchy bullited list in MS-Word .docx manually and inspect its XML structure by renaming its extension to .zip, inside this zip you'll find word/document.xml, by inspecting it you'll find that its <w:ilvl w:val="0"/>, "ilvl" Indent Level that is responsible for you indentation so using above code you can create you multi level lists.

Here is how you set indent level:

para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));

Just increase indent level by BigInteger.valueOf((int)IndentLevel)

like image 160
KKK Avatar answered Dec 31 '22 21:12

KKK