我在Java中工作,使用以下Maven依赖项(以及其他依赖项):
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.0.0</version>
</dependency>
</dependencies>下面的课是从另一篇这样的文章中收集到的:
import java.io.FileOutputStream;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
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.CTLvl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
public class CreateSimpleWordBulletList
{
public static void main(String[] args) throws Exception
{
CTAbstractNum cTAbstractNum = CTAbstractNum.Factory.newInstance();
// Next we set the AbstractNumId. This requires care.
// Since we are in a new document we can start numbering from 0.
// But if we have an existing document, we must determine the next free
// number first.
cTAbstractNum.setAbstractNumId(BigInteger.valueOf(0));
// Bullet list
CTLvl cTLvl = cTAbstractNum.addNewLvl();
cTLvl.addNewNumFmt().setVal(STNumberFormat.BULLET);
cTLvl.addNewLvlText().setVal("•");
XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
XWPFDocument document = new XWPFDocument();
XWPFNumbering numbering = document.createNumbering();
BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
BigInteger numID = numbering.addNum(abstractNumID);
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("A list having defined gap between bullet point and text:");
ArrayList<String> documentList = new ArrayList<String>(Arrays.asList(new String[] { "One", "Two", "Three" }));
for (String string : documentList)
{
paragraph = document.createParagraph();
paragraph.setNumID(numID);
// set indents in Twips (twentieth of an inch point, 1440 Twips = 1 inch
paragraph.setIndentFromLeft(1440 / 4); // indent from left 360 Twips = 1/4
// inch
paragraph.setIndentationHanging(1440 / 4); // indentation hanging 360
// Twips = 1/4 inch
// so bullet point hangs 1/4
// inch before the text at
// indentation 0
run = paragraph.createRun();
run.setText(string);
}
paragraph = document.createParagraph();
FileOutputStream out = new FileOutputStream("CreateWordSimplestBulletList.docx");
document.write(out);
out.close();
document.close();
}
}这会像我想要的那样创建一个弹出列表;我希望缩进它,但这是次要的。
我需要对其进行的真正修改是再添加两个级别的列表,以便在Word文档中得到类似于以下内容的结果:
* One
- AAA
o aaa
o bbb
o ccc
- BBB
o xyz
o abc
* Two
- AAA
o mmm
o nnn
- ZZZ
o bbb
o nnn等。
我希望没有必要有人为此为我编写代码,但我不理解也没有找到任何关于CTAbstractNum、CTLvl或XWPF*类的文档。如果有足够的文档,那么有人就可以指出这一点。
我从这里的其他评论中了解到,CTAbstractNum.setAbstractNumId()中的值集标识了整个编号级别的文档,因此它应该应用于最外层的所有项目,而在概念上,另一个这样的ID将应用于每个项目中相同级别的所有项目(例如,上图中的'aaa‘、'bbb’、'ccc‘字符串。我猜会创建不同的I并应用于每个这样的内部列表。但是,当我对API的概念模型一无所知时,我讨厌猜测这一点。试错编程是如此的无聊。
发布于 2022-01-05 11:13:35
我已经为如何创建字号提供了多个答案。也适用于如何创建多级编号。例如:Apache多行子弹点是工作的,但不是多个副翼?和我如何添加列表在poi字,序号或其他符号的列表符号?。
但是当你也在要求文件的时候,我会试图对此做出更多的解释。
现代Word文档(*.docx)正在使用Office Open XML文件格式。该格式最初由Ecma (作为ECMA-376)和ISO和IEC (作为ISO/IEC 29500)在以后的版本标准化。它是一个包含XML和特殊目录结构中的其他文件的ZIP归档文件。因此,您可以轻松地解压缩*.docx文件并查看其内部结构。
基于这些标准,apache在org.openxmlformats.schemas类中开发了XML。直到apache poi版本4,这些类都是在ooxml-模式中提供的。从apache poi版本5上看,它们都在poi-ooxml-满中。还有一个poi-ooxml-lite版本。但是这只包含那些被高级apache poi类使用的bean。因此,当涉及到更特殊的用例时,它缺乏一些bean。
不幸的是,没有公共的org.openxmlformats.schemas类文档。但是,当然我们可以下载这些源代码,并从这些源中执行javadoc,以便至少具有API文档。
XWPF是apache poi对Microsoft使用的Office部分的高级实现。它使用org.openxmlformats.schemas bean来实现更方便的方法。它在https://poi.apache.org/:Apache POI - Javadocs、快速指南中有文档。但是XWPF至今还没有包含Microsoft的所有可能性和特性。因此,对于一些特殊的用例,需要了解XML和org.openxmlformats.schemas bean的使用情况。
因为*.docx只是一个ZIP存档,所以最方便的方法是使用Microsoft创建一个简单的*.docx文件,然后解压缩*.docx以获得创建的*.docx。然后尝试使用XWPF和org.openxmlformats.schemas bean重新创建XML。
当谈到编号时,人们会发现在/word/numbering.xml ZIP归档文件中有一个*.docx,它包含用于编号定义的XML。每个定义都包含一个包含该定义的abstractNum,即使对于多个缩进级别的编号和链接到该abstractNum的num也是如此。num有一个numId,它在/word/document.xml中用于标记枚举中包含的段落。这些段落还可能有一个ilv (缩进级别),它显示了它们在枚举中的深度。
XWPF不完全提供在编号中创建abstractNum的所有功能。它提供XWPFAbstractNum,它有一个接受org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum的构造函数。因此,需要使用低级别bean创建CTAbstractNum。最简单的方法是根据String提供的XML创建它。XML可以通过创建一个简单的*.docx文件,其中包含使用Microsoft本身的编号,然后解压缩*.docx ZIP存档。
如果一个人能够读取XML,那么这个XML将是自我解释。这些元素有很好的名称。我们需要知道的是,缩进和悬挂的测量单位是twips (二十英寸点)。而且,用于符号点的符号一次来自附加的Windows字体符号和/或Wingdings。然后,还需要在XML中设置这些字体。这些值是ASCII值,它使用这些特殊字体的特殊符号。
下面的完整示例说明了这一点。它创建显示的枚举,一次作为项目列表,一次作为编号列表。
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
import java.math.BigInteger;
import java.util.Map;
import java.util.TreeMap;
public class CreateWordMultilevelLists {
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=\"\uF0B7\"/><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=\"\u2013\"/><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=\"\u26Ac\"/><w:lvlJc w:val=\"left\"/><w:pPr><w:ind w:left=\"2160\" 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:abstractNum>";
static String cTAbstractNumDecimalXML =
"<w:abstractNum xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\" w:abstractNumId=\"1\">"
+ "<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>";
static BigInteger createNumbering(XWPFDocument document, String abstractNumXML) throws Exception {
CTNumbering cTNumbering = CTNumbering.Factory.parse(abstractNumXML);
CTAbstractNum cTAbstractNum = cTNumbering.getAbstractNumArray(0);
XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum);
XWPFNumbering numbering = document.createNumbering();
BigInteger abstractNumID = numbering.addAbstractNum(abstractNum);
BigInteger numID = numbering.addNum(abstractNumID);
return numID;
}
static void setIndentLevel(XWPFParagraph paragraph, BigInteger level) {
if (paragraph.getCTP().isSetPPr()) {
if (paragraph.getCTP().getPPr().isSetNumPr()) {
if (paragraph.getCTP().getPPr().getNumPr().isSetIlvl()) {
paragraph.getCTP().getPPr().getNumPr().getIlvl().setVal(level);
} else {
paragraph.getCTP().getPPr().getNumPr().addNewIlvl().setVal(level);
}
}
}
}
static BigInteger getIndentLevelFromNumberingString(String numberingString) {
String[] levels = numberingString.split("\\.");
int level = levels.length -1;
return BigInteger.valueOf(level);
}
static void insertListContent(XWPFDocument document, TreeMap<String, String> listContent, BigInteger numID) {
for (Map.Entry<String, String> entry : listContent.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
XWPFParagraph paragraph = document.createParagraph();
paragraph.setNumID(numID);
setIndentLevel(paragraph, getIndentLevelFromNumberingString(key));
XWPFRun run = paragraph.createRun();
run.setText(value);
if (!entry.equals(listContent.lastEntry())) paragraph.setSpacingAfter(0);
}
}
public static void main(String[] args) throws Exception {
TreeMap<String, String> listContent = new TreeMap<String, String>();
listContent.put("1", "One");
listContent.put("1.1", "AAA");
listContent.put("1.1.1", "aaa");
listContent.put("1.1.2", "bbb");
listContent.put("1.1.3", "ccc");
listContent.put("1.2", "BBB");
listContent.put("1.2.1", "xyz");
listContent.put("1.2.2", "abc");
listContent.put("2", "Two");
listContent.put("2.1", "AAA");
listContent.put("2.1.1", "mmm");
listContent.put("2.1.2", "nnn");
listContent.put("2.2", "ZZZ");
listContent.put("2.2.1", "bbb");
listContent.put("2.2.2", "nnn");
XWPFDocument document = new XWPFDocument();
BigInteger numIDBulletList = createNumbering(document, cTAbstractNumBulletXML);
BigInteger numIDDecimalList = createNumbering(document, cTAbstractNumDecimalXML);
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run=paragraph.createRun();
run.setText("The bullet list:");
insertListContent(document, listContent, numIDBulletList);
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("Paragraph after the list.");
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("The decimal list:");
insertListContent(document, listContent, numIDDecimalList);
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("Paragraph after the list.");
FileOutputStream out = new FileOutputStream("./CreateWordMultilevelLists.docx");
document.write(out);
out.close();
document.close();
}
}https://stackoverflow.com/questions/70582769
复制相似问题