<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">列表也是docx文件中常见的元素之一。</span>
列表实际上也是段落,只是指定了列表格式。
列表格式需要首先在NumberingPart中定义,然后在段落的PPr中进行引用。
列表格式的详细说明见http://officeopenxml.com/WPnumberingAbstractNum.php。
下面是一个简单列表的实例,将所有支持的列表格式都一一列举。
package me.test.docx4j;
import java.io.File;
import java.math.BigInteger;
import javax.xml.bind.JAXBException;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.wml.Body;
import org.docx4j.wml.Document;
import org.docx4j.wml.Lvl;
import org.docx4j.wml.Lvl.LvlText;
import org.docx4j.wml.Lvl.Start;
import org.docx4j.wml.NumFmt;
import org.docx4j.wml.NumberFormat;
import org.docx4j.wml.Numbering;
import org.docx4j.wml.Numbering.AbstractNum;
import org.docx4j.wml.Numbering.AbstractNum.MultiLevelType;
import org.docx4j.wml.Numbering.AbstractNum.Name;
import org.docx4j.wml.Numbering.Num;
import org.docx4j.wml.Numbering.Num.AbstractNumId;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.PPr;
import org.docx4j.wml.PPrBase.NumPr;
import org.docx4j.wml.PPrBase.NumPr.Ilvl;
import org.docx4j.wml.PPrBase.NumPr.NumId;
import org.docx4j.wml.R;
import org.docx4j.wml.Text;
import org.junit.Test;
/**
* @see <a href="http://officeopenxml.com/WPnumbering.php">http://officeopenxml.com/WPnumbering.php</a>
*
*/
public class SimpleNumbering {
protected ObjectFactory factory = Context.getWmlObjectFactory();
public static final class MultiLevelTypeEnum {
public static final MultiLevelType SINGLE_LEVEL;
public static final MultiLevelType MULTI_LEVEL;
public static final MultiLevelType HYBRID_MULTI_LEVEL;
static {
SINGLE_LEVEL = create("singleLevel");
MULTI_LEVEL = create("multiLevel");
HYBRID_MULTI_LEVEL = create("hybridMultiLevel");
}
protected static MultiLevelType create(String type) {
MultiLevelType mlt = new MultiLevelType();
mlt.setVal(type);
return mlt;
}
}
/**
* 在Numbering中增加AbstractNum和Num项目
* @param numbering
* @param i 用于abstractNumId和numId
* @param nf 指定编号格式
*/
protected void appendNum(Numbering numbering, int i, NumberFormat nf) {
//首先定义AbstractNum部分
AbstractNum an = new AbstractNum();
an.setAbstractNumId(BigInteger.valueOf(i));
an.setMultiLevelType(MultiLevelTypeEnum.SINGLE_LEVEL);
Name name = new Name();
name.setVal(nf.value());
an.setName(name);
//定义0级,即最高一级的编号
//只定义这一个级别
Lvl lvl = new Lvl();
lvl.setIlvl(BigInteger.ZERO);
//设置开始序号,如果不设置为1的话默认为0,可能出现某些格式的序号没有0值显示
Start start = new Start();
start.setVal(BigInteger.valueOf(1));
lvl.setStart(start);
//设置显示文本内容,如果不设置的话将不显示编号
LvlText lvltext = new LvlText();
//表示显示第一级编号,后面跟一个“.”
lvltext.setVal("%1.");
lvl.setLvlText(lvltext);
//设置编号格式
NumFmt numfmt = new NumFmt();
numfmt.setVal(nf);
lvl.setNumFmt(numfmt);
//将Lvl增加到AbstractNum中
an.getLvl().add(lvl);
//将AbstractNum增加到Numbering中
numbering.getAbstractNum().add(an);
//设置一个Num的实例,通过AbstractNumId引用刚定义的AbstractNum
AbstractNumId anid = new AbstractNumId();
anid.setVal(BigInteger.valueOf(i));
Num num = new Num();
num.setAbstractNumId(anid);
num.setNumId(BigInteger.valueOf(i)); //此处NumId不能为0,必须为正整数
//将Num增加到Numbering中
numbering.getNum().add(num);
}
@Test
public void doTest() throws Docx4JException, JAXBException {
WordprocessingMLPackage pkg = WordprocessingMLPackage.createPackage();
MainDocumentPart main = pkg.getMainDocumentPart();
Document doc = main.getContents();
Body body = doc.getBody();
//增加编号列表设置部分,注意,一定要增加到MainDocumentPart中,否则会出现引用不成功的情况
NumberingDefinitionsPart numberingPart = new NumberingDefinitionsPart();
Numbering numbering = new Numbering();
numberingPart.setContents(numbering);
main.addTargetPart(numberingPart);
//遍历所有支持的列表格式
//注意:numId不能为0,否则不显示列表
int i = 1;
for(NumberFormat nf : java.util.EnumSet.allOf(NumberFormat.class)) {
this.appendNum(numbering, i, nf);
i++;
}
//为每个列表格式创建一个列表,并注明列表格式名称
int j = 1;
for(NumberFormat nf : java.util.EnumSet.allOf(NumberFormat.class)) {
P para = this.createPara(nf.value());
body.getContent().add(para);
P pa = this.createPara("A");
P pb = this.createPara("B");
P pc = this.createPara("C");
NumPr numpr = new NumPr();
NumId numid = new NumId();
numid.setVal(BigInteger.valueOf(j));
numpr.setNumId(numid);
Ilvl ilvl = new Ilvl();
ilvl.setVal(BigInteger.ZERO);
numpr.setIlvl(ilvl);
pa.getPPr().setNumPr(numpr);
pb.getPPr().setNumPr(numpr);
pc.getPPr().setNumPr(numpr);
body.getContent().add(pa);
body.getContent().add(pb);
body.getContent().add(pc);
j++;
}
pkg.save(new File(System.getProperty("user.dir"), "Simple Numbering.docx"));
}
protected void appendNumberingPara(Body body, int numId, String str) {
P para = this.createPara(str);
body.getContent().add(para);
P pa = this.createPara("A");
P pb = this.createPara("B");
P pc = this.createPara("C");
NumPr numpr = factory.createPPrBaseNumPr();
NumId numid = factory.createPPrBaseNumPrNumId();
numid.setVal(BigInteger.valueOf(numId));
numpr.setNumId(numid);
Ilvl ilvl = new Ilvl();
ilvl.setVal(BigInteger.ZERO);
numpr.setIlvl(ilvl);
pa.getPPr().setNumPr(numpr);
pb.getPPr().setNumPr(numpr);
pc.getPPr().setNumPr(numpr);
body.getContent().add(pa);
body.getContent().add(pb);
body.getContent().add(pc);
}
protected P createPara(String str) {
P para = factory.createP();
R run = factory.createR();
Text text = factory.createText();
text.setValue(str);
run.getContent().add(text);
para.getContent().add(run);
PPr ppr = factory.createPPr();
para.setPPr(ppr);
return para;
}
}