使用JAVA在POI docx中使用多级列表

问题描述 投票:0回答:1

我如何制定多级列表(使用TOC)以创建具有这样的编号的DOCX:

  1. 主题011.1。项目011.2。项目02

  2. 主题022.1。项目032.2。项目04

list apache-poi docx
1个回答
0
投票

这可以在不直接访问XML的情况下完成。这是所述示例的代码:

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.openxmlformats.schemas.wordprocessingml.x2006.main.*;

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


public class MultiLevelListExample {
    public static void main(String[] args){

        XWPFDocument doc = new XWPFDocument();

        BigInteger numId = getNumId(doc);           //set up the numbering scheme

        createNumberedParagraph(doc, numId, "Subject 01", BigInteger.ZERO);     //first indent level
        createNumberedParagraph(doc, numId, "Item 01", BigInteger.ONE);         //second indent level
        createNumberedParagraph(doc, numId, "Item 02", BigInteger.ONE);
        createNumberedParagraph(doc, numId, "Subject 02", BigInteger.ZERO);
        createNumberedParagraph(doc, numId, "Item 03", BigInteger.ONE);
        createNumberedParagraph(doc, numId, "Item 04", BigInteger.ONE);

        /*produce the document*/
        try {
            File outputReport = new File("report.docx");

            FileOutputStream output = new FileOutputStream(outputReport);
            doc.write(output);

            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * This method creates a numbering scheme and associates it with the working document
     * @param document the document in which the numbering scheme will be used
     * @return The ID for the created numbering scheme
     */
    public static BigInteger getNumId(XWPFDocument document){

        CTAbstractNum cTAbstractNum = CTAbstractNum.Factory.newInstance();      //create a numbering scheme
        cTAbstractNum.setAbstractNumId(BigInteger.valueOf(0));                  //give the scheme an ID

        /*first level*/
        CTLvl cTLvl0 = cTAbstractNum.addNewLvl();               //create the first numbering level
        cTLvl0.setIlvl(BigInteger.ZERO);                        //mark it as the top outline level
        cTLvl0.addNewNumFmt().setVal(STNumberFormat.DECIMAL);   //set the number format
        cTLvl0.addNewLvlText().setVal("%1.");                   //set the adornment; %1 is the first-level number or letter as set by number format
        cTLvl0.addNewStart().setVal(BigInteger.ONE);            //set the starting number (here, index from 1)
        cTLvl0.addNewSuff().setVal(STLevelSuffix.SPACE);        //set space between number and text

        /*second level*/
        CTLvl cTLvl1 = cTAbstractNum.addNewLvl();               //create another numbering level
        cTLvl1.setIlvl(BigInteger.ONE);                         //specify that it's the first indent
        CTInd ctInd = cTLvl1.addNewPPr().addNewInd();           //add an indent
        ctInd.setLeft(inchesToTwips(.5));                       //set a half-inch indent
        cTLvl1.addNewNumFmt().setVal(STNumberFormat.DECIMAL);   //the rest is fairly similar
        cTLvl1.addNewLvlText().setVal("%1.%2.");                //setup to get 1.1, 1.2, ect.
        cTLvl1.addNewStart().setVal(BigInteger.ONE);
        cTLvl1.addNewSuff().setVal(STLevelSuffix.SPACE);

        /*associate the numbering scheme with the document's numbering*/
        XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
        XWPFNumbering numbering = document.createNumbering();
        BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
        /*return an ID for the numbering*/
        return numbering.addNum(abstractNumID);
    }

    /**
     * @param inches
     * @return twentieths of a point (twips)
     */
    private static BigInteger inchesToTwips(double inches) {
        return BigInteger.valueOf((long) (1440L * inches));
    }


    /**
     * creates a numbered list item at the specified depth
     * @param doc the document
     * @param numId the numbering setup for the document
     * @param paragraphText the paragraph being created
     * @param numLevel the indent level in the list
     */
    private static void createNumberedParagraph(XWPFDocument doc, BigInteger numId, String paragraphText, BigInteger numLevel) {
        XWPFParagraph paragraph = doc.createParagraph();        //create the paragraph
        paragraph.createRun().setText(paragraphText);           //fill text
        paragraph.setNumID(numId);                              //make it numbered
        CTDecimalNumber ctDecimalNumber = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
        ctDecimalNumber.setVal(numLevel);                       //set the indent level
    }
}

您可能想以不同的方式布置代码以提高灵活性,但这演示了创建多级列表的步骤。

重要的步骤(创建简单列表所需的步骤之外是创建多个编号级别并指定每个段落位于哪个级别上。

此示例已通过POI 3.14和ooxml-schemas 1.3进行了测试

© www.soinside.com 2019 - 2024. All rights reserved.