How can I add List in poi word, ordered number or other symbol for list symbol?

前端 未结 1 1854
谎友^
谎友^ 2021-01-17 01:17

everyone! first, I want to add list in my poi word(XWPF), second, I want to using black cube as the list symbol like picture as below. third, what I should to do if ordere

相关标签:
1条回答
  • 2021-01-17 02:12

    Since for new adding a new AbstractNum in XWPFNumbering, XWPFAbstractNum is needed and this is not able to create without using underlaying low level objects until now, at least org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum is needed.

    There are methods in CTAbstractNum for creating the single sub objects therein. But the resulting code would be very small part code and so much many code lines would be necessary. So the best way in my opinion is parsing XML for creating the AbstractNum. To get this XML one can create a simple Worddocument having numbering and then unzip the *.docx file and have a look at /word/numbering.xml. There you will find something like:

    <w:numbering>
     <w:abstractNum w:abstractNumId="0">
      <w:multiLevelType w:val="hybridMultilevel"/>
      <w:lvl w:ilvl="0">
       <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:hanging="360" w:left="720"/>
       </w:pPr>
      </w:lvl>
      <w:lvl w:ilvl="1" w:tentative="1">
       <w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1.%2"/><w:lvlJc w:val="left"/>
       <w:pPr>
        <w:ind w:hanging="360" w:left="1440"/>
       </w:pPr>
      </w:lvl>
      <w:lvl w:ilvl="2" w:tentative="1">
       <w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%1.%2.%3"/><w:lvlJc w:val="left"/>
       <w:pPr>
        <w:ind w:hanging="360" w:left="2160"/>
       </w:pPr>
      </w:lvl>
     </w:abstractNum>
    ...
    </w:numbering>
    

    for a 3 level decimal numbering for example.

    This XML is self explained in my opinion. There is a lvl definition for each numbering level having definitions for it's appearance and indention.

    For a bullet numbering the XMLwill be similar but the glyphs for the bullet characters used will be additional defined using Font definition. The "black cube" for example is a glyph from font Wingdings.

    ...
    <w:lvl w:ilvl="0">
     <w:start w:val="1"/><w:numFmt w:val="bullet"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/>
     <w:pPr>
      <w:ind w:hanging="360" w:left="720"/>
     </w:pPr>
     <w:rPr>
      <w:rFonts w:ascii="Wingdings" w:hAnsi="Wingdings" w:hint="default"/>
     </w:rPr>
    </w:lvl>
    ...
    

    Knowing this we can code:

    import java.io.File;
    import java.io.FileOutputStream;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
    
    import java.math.BigInteger;
    
    public class CreateWordBulletOrDecimalList {
    
     static String cTAbstractNumBulletXML = 
      "<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"0\">"
    + "<w:multiLevelType w:val=\"hybridMultilevel\"/>"
    + "<w:lvl w:ilvl=\"0\"><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=\"720\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:hint=\"default\"/></w:rPr></w:lvl>"
    + "<w:lvl w:ilvl=\"1\" w:tentative=\"1\"><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=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\" w:hint=\"default\"/></w:rPr></w:lvl>"
    + "<w:lvl w:ilvl=\"2\" w:tentative=\"1\"><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=\"2160\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:hint=\"default\"/></w:rPr></w:lvl>"
    + "</w:abstractNum>";
    
     static String cTAbstractNumDecimalXML = 
      "<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"0\">"
    + "<w:multiLevelType w:val=\"hybridMultilevel\"/>"
    + "<w:lvl w:ilvl=\"0\"><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:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%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:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2.%3\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr></w:lvl>"
    + "</w:abstractNum>";
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument document = new XWPFDocument();
    
      XWPFParagraph paragraph = document.createParagraph();
      XWPFRun run=paragraph.createRun();  
      run.setText("The List:");
    
      CTNumbering cTNumbering = CTNumbering.Factory.parse(cTAbstractNumBulletXML);
      //CTNumbering cTNumbering = CTNumbering.Factory.parse(cTAbstractNumDecimalXML);
    
      CTAbstractNum cTAbstractNum = cTNumbering.getAbstractNumArray(0);
    
      XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
    
      XWPFNumbering numbering = document.createNumbering();
    
      BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
    
      BigInteger numID = numbering.addNum(abstractNumID);
    
      for (int i = 0; i < 5; i++) {
       paragraph = document.createParagraph();
       paragraph.setNumID(numID);
       run = paragraph.createRun();
       run.setText("List item " + (i+1)); 
       if (i < 4) paragraph.setSpacingAfter(0);
       if (i == 0) {
        for (int j = 0; j < 2; j++) {
         paragraph = document.createParagraph();
         paragraph.setNumID(numID);
         paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
         run = paragraph.createRun();
         run.setText("Sub list item " + (i+1) + " " + (char)(97+j));
         paragraph.setSpacingAfter(0);
        }
       }
       if (i == 1 || i == 3) {
        paragraph = document.createParagraph();
        paragraph.setNumID(numID);
        paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
        run = paragraph.createRun();
        run.setText("Sub list item " + (i+1) + " a");
        paragraph.setSpacingAfter(0); 
       }
      }
    
      paragraph = document.createParagraph();
      run=paragraph.createRun();  
      run.setText("Paragraph after the list.");
    
      FileOutputStream out = new FileOutputStream("CreateWordBulletOrDecimalList.docx");    
      document.write(out);
    
      System.out.println("CreateWordBulletOrDecimalList written successully");
     }
    }
    

    Code for using both kind of lists in one document:

    import java.io.File;
    import java.io.FileOutputStream;
    
    import org.apache.poi.xwpf.usermodel.*;
    
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
    
    import java.math.BigInteger;
    
    public class CreateWordBulletAndDecimalList {
    
     static String cTAbstractNumBulletXML = 
      "<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"0\">"
    + "<w:multiLevelType w:val=\"hybridMultilevel\"/>"
    + "<w:lvl w:ilvl=\"0\"><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=\"720\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Wingdings\" w:hAnsi=\"Wingdings\" w:hint=\"default\"/></w:rPr></w:lvl>"
    + "<w:lvl w:ilvl=\"1\" w:tentative=\"1\"><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=\"Courier New\" w:hAnsi=\"Courier New\" w:cs=\"Courier New\" w:hint=\"default\"/></w:rPr></w:lvl>"
    + "<w:lvl w:ilvl=\"2\" w:tentative=\"1\"><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=\"2160\" w:hanging=\"360\"/></w:pPr><w:rPr><w:rFonts w:ascii=\"Symbol\" w:hAnsi=\"Symbol\" w:hint=\"default\"/></w:rPr></w:lvl>"
    + "</w:abstractNum>";
    
     static String cTAbstractNumDecimalXML = 
      "<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"1\">"
    + "<w:multiLevelType w:val=\"hybridMultilevel\"/>"
    + "<w:lvl w:ilvl=\"0\"><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:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%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:tentative=\"1\"><w:start w:val=\"1\"/><w:numFmt w:val=\"decimal\"/><w:lvlText w:val=\"%1.%2.%3\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" w:hanging=\"360\"/></w:pPr></w:lvl>"
    + "</w:abstractNum>";
    
     public static void main(String[] args) throws Exception {
    
      XWPFDocument document = new XWPFDocument();
    
      CTNumbering cTNumbering = CTNumbering.Factory.parse(cTAbstractNumBulletXML);
      CTAbstractNum cTAbstractNum = cTNumbering.getAbstractNumArray(0);
      XWPFAbstractNum abstractNum1 = new XWPFAbstractNum(cTAbstractNum);
    
    
      cTNumbering = CTNumbering.Factory.parse(cTAbstractNumDecimalXML);
      cTAbstractNum = cTNumbering.getAbstractNumArray(0);
      XWPFAbstractNum abstractNum2 = new XWPFAbstractNum(cTAbstractNum);
    
      XWPFNumbering numbering = document.createNumbering();
    
      BigInteger abstractNumID1 = numbering.addAbstractNum(abstractNum1);
      BigInteger numID1 = numbering.addNum(abstractNumID1);
    
      BigInteger abstractNumID2 = numbering.addAbstractNum(abstractNum2);
      BigInteger numID2 = numbering.addNum(abstractNumID2);
    
      XWPFParagraph paragraph = document.createParagraph();
      XWPFRun run=paragraph.createRun();  
      run.setText("The lists:");
      paragraph = document.createParagraph();
    
      paragraph = document.createParagraph();
      run=paragraph.createRun();  
      run.setText("The bullet list:");
    
      for (int i = 0; i < 5; i++) {
       paragraph = document.createParagraph();
       paragraph.setNumID(numID1);
       run = paragraph.createRun();
       run.setText("List item " + (i+1)); 
       if (i < 4) paragraph.setSpacingAfter(0);
       if (i == 0) {
        for (int j = 0; j < 2; j++) {
         paragraph = document.createParagraph();
         paragraph.setNumID(numID1);
         paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
         run = paragraph.createRun();
         run.setText("Sub list item " + (i+1) + " " + (char)(97+j));
         paragraph.setSpacingAfter(0);
        }
       }
       if (i == 1 || i == 3) {
        paragraph = document.createParagraph();
        paragraph.setNumID(numID1);
        paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
        run = paragraph.createRun();
        run.setText("Sub list item " + (i+1) + " a");
        paragraph.setSpacingAfter(0); 
       }
      }
    
      paragraph = document.createParagraph();
      paragraph = document.createParagraph();
      run=paragraph.createRun();  
      run.setText("The decimal list:");
    
      for (int i = 0; i < 5; i++) {
       paragraph = document.createParagraph();
       paragraph.setNumID(numID2);
       run = paragraph.createRun();
       run.setText("List item " + (i+1)); 
       if (i < 4) paragraph.setSpacingAfter(0);
       if (i == 0) {
        for (int j = 0; j < 2; j++) {
         paragraph = document.createParagraph();
         paragraph.setNumID(numID2);
         paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
         run = paragraph.createRun();
         run.setText("Sub list item " + (i+1) + " " + (char)(97+j));
         paragraph.setSpacingAfter(0);
        }
       }
       if (i == 1 || i == 3) {
        paragraph = document.createParagraph();
        paragraph.setNumID(numID2);
        paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
        run = paragraph.createRun();
        run.setText("Sub list item " + (i+1) + " a");
        paragraph.setSpacingAfter(0); 
       }
      }
    
      paragraph = document.createParagraph();
      paragraph = document.createParagraph();
      run=paragraph.createRun();  
      run.setText("Paragraph after the lists.");
    
      FileOutputStream out = new FileOutputStream("CreateWordBulletAndDecimalList.docx");    
      document.write(out);
    
      System.out.println("CreateWordBulletAndDecimalList written successully");
     }
    }
    
    0 讨论(0)
提交回复
热议问题