【问题标题】:Using MultiLevel List in POI docx using JAVA使用 JAVA 在 POI docx 中使用多级列表
【发布时间】:2018-05-28 21:35:50
【问题描述】:

如何详细说明多级列表(使用 TOC)以创建具有如下编号的 DOCX:

  1. 主题 01
    1.1。项目 01
    1.2.项目02

  2. 主题 02
    2.1。项目 03
    2.2.项目 04

【问题讨论】:

  • 我忘了说,我想要:。 “标题1”样式的“主题01”和“主题02”。 “heading2”样式中的“Item nn”
  • 对于多级编号,请参阅stackoverflow.com/questions/43155172/…。那么样式是另一个问题。

标签: list apache-poi docx


【解决方案1】:

这可以在不直接访问 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 进行了测试

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多