Apache POI, создание маркированного списка и нумерованного списка в одном документе

Я пытаюсь создать с помощью apache poi документ, содержащий как выделенную точку, так и нумерованный список. Я хотел бы иметь такой результат.

Список:

  • Список1 пункт 0
  • Список1 пункт 1
  • Список1 элемент 2

Абзац после списка.

Список2:

  1. Список2 пункт 0
  2. Список2 пункт 1
  3. Список2 пункт 2

Абзац после списка2.

Если я попытаюсь создать два списка в двух разных документах, все будет работать.

Но если они находятся в одном документе, я получаю только стиль первого созданного.

Например, в приведенном ниже коде я создаю сначала список маркеров, а затем нумерованный. Но сгенерированный документ содержит два списка маркеров.

Я предполагаю, что проблема в том, что документ считает, что первый список все еще открыт, и применяет тот же стиль к следующему.

Как я могу сообщить документу, что список закрыт? Любое предложение?

Большое спасибо!

import java.io.FileOutputStream;
import java.math.BigInteger;

import org.apache.poi.xwpf.usermodel.XWPFAbstractNum;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFNumbering;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;

public class QuickTest {

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=\"Symbol\" w:hAnsi=\"Symbol\" 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=\"o\"/><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=\"Wingdings\" w:hAnsi=\"Wingdings\" 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);

        CTAbstractNum cTAbstractNum = cTNumbering.getAbstractNumArray(0);

        XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);

        XWPFNumbering numbering = document.createNumbering();

        BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);

        BigInteger numID = numbering.addNum(abstractNumID);
        System.out.println("numID: " + numID);
        for (int i = 0; i < 3; i++) {
            paragraph = document.createParagraph();
            paragraph.setNumID(numID);
            run = paragraph.createRun();
            run.setText("List1 item " + i); 
            if (i < 2) paragraph.setSpacingAfter(0);
        }

        paragraph = document.createParagraph();
        run=paragraph.createRun();  
        run.setText("Paragraph after the list.");
    }

    {
        XWPFParagraph paragraph = document.createParagraph();
        XWPFRun run=paragraph.createRun();  
        run.setText("The List2:");
        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);
        System.out.println("numID: " + numID);
        for (int i = 0; i < 3; i++) {
            paragraph = document.createParagraph();
            paragraph.setNumID(numID);
            run = paragraph.createRun();
            run.setText("List2 item " + i); 
            if (i < 2) paragraph.setSpacingAfter(0);
        }
        paragraph = document.createParagraph();
        run=paragraph.createRun();  
        run.setText("Paragraph after the list2.");
    }

    FileOutputStream out = new FileOutputStream("CreateWordBulletAndDecimalList.docx");    
    document.write(out);

    System.out.println("CreateWordBulletOrDecimalList written successully");
}
}

person Marco Mac    schedule 07.12.2017    source источник
comment
См. stackoverflow.com/questions/43155172/ - последний пример кода там.   -  person Axel Richter    schedule 07.12.2017
comment
Спасибо!!! Я забыл одну вещь: w:abstractNumId=0 не должен быть одновременно равен 0 в XML.   -  person Marco Mac    schedule 08.12.2017