How to create multiLevel bullets and numbering fro

2019-02-23 01:08发布

问题:

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>

回答1:

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)