如何使用 apache POI XWPFDocument 从 java 创建多级项目符号和编号?
How to create multiLevel bullets and numbering from java using apache POI XWPFDocument?
我已经阅读了很多与我的要求相关的博客和论坛,但直到现在我已经能够在所有帮助下为第一级生成项目符号或编号。谁能指导我如何使用 apache poi 创建多级编号。
想知道 Apache POI XWPFDocument 是否支持这样的功能?
以下是我的要求
- 一级
- 二级
- 二级
- 一级
编辑 1:
这是我的示例代码,适用于单级编号
public class TestNumbering {
String fileName="";
InputStream in = null;
CTAbstractNum abstractNum = null;
public TestNumbering() {
try {
in = CreateWordDocument.class.getClassLoader().getResourceAsStream("numbering.xml");
abstractNum = CTAbstractNum.Factory.parse(in);
} catch (XmlException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String createDocument(String fileName, String content) {
this.fileName=fileName;
XWPFDocument doc = new XWPFDocument();
doc.createNumbering();
XWPFNumbering numbering=null;
numbering=doc.createNumbering();
for(String value: content.split("@")) {
XWPFParagraph para = doc.createParagraph();
para.setVerticalAlignment(TextAlignment.CENTER);
para.setNumID(addListStyle(abstractNum, doc, numbering));
XWPFRun run=para.createRun();
run.setText(value);
}
try {
FileOutputStream out = new FileOutputStream(fileName);
doc.write(out);
out.close();
in.close();
} catch(Exception e) {}
return null;
}
private BigInteger addListStyle(CTAbstractNum abstractNum, XWPFDocument doc, XWPFNumbering numbering) {
try {
XWPFAbstractNum abs = new XWPFAbstractNum(abstractNum, numbering);
BigInteger id = BigInteger.valueOf(0);
boolean found = false;
while (!found) {
Object o = numbering.getAbstractNum(id);
found = (o == null);
if (!found)
id = id.add(BigInteger.ONE);
}
abs.getAbstractNum().setAbstractNumId(id);
id = numbering.addAbstractNum(abs);
return doc.getNumbering().addNum(id);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
String fileName="Test.docx";
new TestNumbering().createDocument(fileName, "First Level@@Second Level@@Second Level@@First Level");
}
}
也可以在下面找到 numbering.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="3A6A237F"/>
<w:multiLevelType w:val="hybridMultilevel"/>
<w:tmpl w:val="5C9890C4"/>
<w:lvl w:ilvl="0" w:tplc="0409000F"><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:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%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:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%3."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="2160" w:hanging="180"/></w:pPr></w:lvl>
<w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl>
<w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="1">
<w:nsid w:val="5E7736F6"/>
<w:multiLevelType w:val="hybridMultilevel"/>
<w:tmpl w:val="F602653C"/>
<w:lvl w:ilvl="0" w:tplc="0409000F"><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:tplc="04090001"><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="Symbol" w:hAnsi="Symbol" w:hint="default"/></w:rPr></w:lvl>
<w:lvl w:ilvl="2" w:tplc="04090003"><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="2340" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:hAnsi="Courier New" w:hint="default"/></w:rPr></w:lvl>
<w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl>
<w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl>
</w:abstractNum>
<w:num w:numId="1"><w:abstractNumId w:val="1"/></w:num>
<w:num w:numId="2"><w:abstractNumId w:val="0"/></w:num>
</w:numbering>
你说得对,Apache POI 的文档类型最差,或者你可以说根本没有文档。所以除了一些博客你找不到什么。
将您的 for 循环替换为:
for (String value : content.split("@")) {
XWPFParagraph para = doc.createParagraph();
para.setVerticalAlignment(TextAlignment.CENTER);
para.setNumID(addListStyle(abstractNum, doc, numbering));
if (value.contains("Second")) {
para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
}
XWPFRun run = para.createRun();
run.setText(value);
}
在 MS-Word .docx
中手动创建一个多层次的 bullited 列表,并通过将其扩展名重命名为 .zip
来检查其 XML 结构,在此 zip 中,您会发现 word/document.xml
,通过检查它你会发现它的 <w:ilvl w:val="0"/>
,"ilvl" 缩进级别负责你的缩进,所以使用上面的代码你可以创建你的多级列表。
设置缩进级别的方法如下:
para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
只需将缩进级别增加 BigInteger.valueOf((int)IndentLevel)
我已经阅读了很多与我的要求相关的博客和论坛,但直到现在我已经能够在所有帮助下为第一级生成项目符号或编号。谁能指导我如何使用 apache poi 创建多级编号。
想知道 Apache POI XWPFDocument 是否支持这样的功能?
以下是我的要求
- 一级
- 二级
- 二级
- 一级
编辑 1:
这是我的示例代码,适用于单级编号
public class TestNumbering {
String fileName="";
InputStream in = null;
CTAbstractNum abstractNum = null;
public TestNumbering() {
try {
in = CreateWordDocument.class.getClassLoader().getResourceAsStream("numbering.xml");
abstractNum = CTAbstractNum.Factory.parse(in);
} catch (XmlException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public String createDocument(String fileName, String content) {
this.fileName=fileName;
XWPFDocument doc = new XWPFDocument();
doc.createNumbering();
XWPFNumbering numbering=null;
numbering=doc.createNumbering();
for(String value: content.split("@")) {
XWPFParagraph para = doc.createParagraph();
para.setVerticalAlignment(TextAlignment.CENTER);
para.setNumID(addListStyle(abstractNum, doc, numbering));
XWPFRun run=para.createRun();
run.setText(value);
}
try {
FileOutputStream out = new FileOutputStream(fileName);
doc.write(out);
out.close();
in.close();
} catch(Exception e) {}
return null;
}
private BigInteger addListStyle(CTAbstractNum abstractNum, XWPFDocument doc, XWPFNumbering numbering) {
try {
XWPFAbstractNum abs = new XWPFAbstractNum(abstractNum, numbering);
BigInteger id = BigInteger.valueOf(0);
boolean found = false;
while (!found) {
Object o = numbering.getAbstractNum(id);
found = (o == null);
if (!found)
id = id.add(BigInteger.ONE);
}
abs.getAbstractNum().setAbstractNumId(id);
id = numbering.addAbstractNum(abs);
return doc.getNumbering().addNum(id);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) throws Exception {
String fileName="Test.docx";
new TestNumbering().createDocument(fileName, "First Level@@Second Level@@Second Level@@First Level");
}
}
也可以在下面找到 numbering.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mo="http://schemas.microsoft.com/office/mac/office/2008/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="urn:schemas-microsoft-com:mac:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 wp14">
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="3A6A237F"/>
<w:multiLevelType w:val="hybridMultilevel"/>
<w:tmpl w:val="5C9890C4"/>
<w:lvl w:ilvl="0" w:tplc="0409000F"><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:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%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:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%3."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="2160" w:hanging="180"/></w:pPr></w:lvl>
<w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl>
<w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="1">
<w:nsid w:val="5E7736F6"/>
<w:multiLevelType w:val="hybridMultilevel"/>
<w:tmpl w:val="F602653C"/>
<w:lvl w:ilvl="0" w:tplc="0409000F"><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:tplc="04090001"><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="Symbol" w:hAnsi="Symbol" w:hint="default"/></w:rPr></w:lvl>
<w:lvl w:ilvl="2" w:tplc="04090003"><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="2340" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:hAnsi="Courier New" w:hint="default"/></w:rPr></w:lvl>
<w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl>
<w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="decimal"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerLetter"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl>
<w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="1"><w:start w:val="1"/><w:numFmt w:val="lowerRoman"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl>
</w:abstractNum>
<w:num w:numId="1"><w:abstractNumId w:val="1"/></w:num>
<w:num w:numId="2"><w:abstractNumId w:val="0"/></w:num>
</w:numbering>
你说得对,Apache POI 的文档类型最差,或者你可以说根本没有文档。所以除了一些博客你找不到什么。
将您的 for 循环替换为:
for (String value : content.split("@")) {
XWPFParagraph para = doc.createParagraph();
para.setVerticalAlignment(TextAlignment.CENTER);
para.setNumID(addListStyle(abstractNum, doc, numbering));
if (value.contains("Second")) {
para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
}
XWPFRun run = para.createRun();
run.setText(value);
}
在 MS-Word .docx
中手动创建一个多层次的 bullited 列表,并通过将其扩展名重命名为 .zip
来检查其 XML 结构,在此 zip 中,您会发现 word/document.xml
,通过检查它你会发现它的 <w:ilvl w:val="0"/>
,"ilvl" 缩进级别负责你的缩进,所以使用上面的代码你可以创建你的多级列表。
设置缩进级别的方法如下:
para.getCTP().getPPr().getNumPr().addNewIlvl().setVal(BigInteger.valueOf(1));
只需将缩进级别增加 BigInteger.valueOf((int)IndentLevel)