java poi生成word多级目录完整代码
时间: 2024-02-01 19:09:38 浏览: 317
Java POI 生成Word文档
以下是Java POI生成Word多级目录的完整代码示例:
```java
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFStyle;
import org.apache.poi.xwpf.usermodel.XWPFStyles;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNumId;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering.AbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering.Num;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
public class GenerateWordWithMultiLevelTOC {
public static void main(String[] args) throws IOException, XmlException {
// 创建一个空白的Word文档对象
XWPFDocument document = new XWPFDocument();
// 添加自定义样式
addCustomHeadingStyle(document, "标题 1", 1);
addCustomHeadingStyle(document, "标题 2", 2);
addCustomHeadingStyle(document, "标题 3", 3);
// 添加多级目录
addMultiLevelTOC(document, "目录", 1, 3);
// 添加正文内容
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText("这是一级标题");
run.addBreak(BreakType.TEXT_WRAPPING);
run.setText("这是一级标题下的内容");
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("这是二级标题");
run.addBreak(BreakType.TEXT_WRAPPING);
run.setText("这是二级标题下的内容");
paragraph = document.createParagraph();
run = paragraph.createRun();
run.setText("这是三级标题");
run.addBreak(BreakType.TEXT_WRAPPING);
run.setText("这是三级标题下的内容");
// 输出到文件
FileOutputStream out = new FileOutputStream(new File("output.docx"));
document.write(out);
out.close();
document.close();
}
/**
* 添加自定义标题样式
*
* @param document Word文档对象
* @param strStyleName 样式名称
* @param headingLevel 标题级别
*/
private static void addCustomHeadingStyle(XWPFDocument document, String strStyleName, int headingLevel) {
// 获取样式表对象
XWPFStyles styles = document.createStyles();
// 创建一个新样式
XWPFStyle style = document.createStyle();
// 设置样式名称
style.setStyleId(strStyleName);
// 设置样式类型为标题
style.setType(STStyleType.PARAGRAPH);
// 设置样式基础样式为正文
style.setBasedOn("Normal");
// 设置样式字体
style.getCTStyle().addNewRPr().addNewRFonts().setAscii("宋体");
style.getCTStyle().getRPr().getRFonts().setHAnsi("宋体");
style.getCTStyle().getRPr().getRFonts().setCs("宋体");
// 设置样式段落属性
style.getCTStyle().addNewPPr().addNewSpacing().setBeforeLines(BigInteger.valueOf(0));
style.getCTStyle().getPPr().getSpacing().setBeforeAutospacing(true);
style.getCTStyle().getPPr().getSpacing().setBefore(BigInteger.valueOf(0));
style.getCTStyle().getPPr().getSpacing().setAfter(BigInteger.valueOf(0));
style.getCTStyle().getPPr().getSpacing().setLineRule(STLineSpacingRule.AUTO);
style.getCTStyle().getPPr().getSpacing().setLine(BigInteger.valueOf(240));
// 设置样式级别
CTAbstractNum abstractNum = CTAbstractNum.Factory.newInstance();
abstractNum.setAbstractNumId(BigInteger.valueOf(10 + headingLevel));
CTLvl lvl = abstractNum.addNewLvl();
lvl.setIlvl(BigInteger.valueOf(headingLevel - 1));
lvl.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
lvl.addNewLvlText().setVal("%" + headingLevel);
lvl.addNewStart().setVal(BigInteger.valueOf(1));
CTNumbering numbering = document.getDocument().getBody().addNewNumTbl();
CTNum num = numbering.addNewNum();
num.setNumId(BigInteger.valueOf(10 + headingLevel));
num.addNewAbstractNumId().setVal(BigInteger.valueOf(10 + headingLevel));
XWPFAbstractNum abs = new XWPFAbstractNum(abstractNum);
XWPFNumbering numbering1 = new XWPFNumbering(numbering);
BigInteger abstractNumID = numbering1.addAbstractNum(abs);
BigInteger numID = numbering1.addNum(abstractNumID);
style.getCTStyle().getPPr().addNewNumPr().addNewIlvl().setVal(BigInteger.valueOf(headingLevel - 1));
style.getCTStyle().getPPr().getNumPr().addNewNumId().setVal(numID);
// 将样式添加到样式表
styles.addStyle(style);
}
/**
* 添加多级目录
*
* @param document Word文档对象
* @param strTitle 目录标题
* @param nMinHeadingLevel 最小标题级别
* @param nMaxHeadingLevel 最大标题级别
*/
private static void addMultiLevelTOC(XWPFDocument document, String strTitle, int nMinHeadingLevel,
int nMaxHeadingLevel) {
// 创建一个新段落
XWPFParagraph paragraph = document.createParagraph();
// 设置段落对齐方式为居中
paragraph.setAlignment(ParagraphAlignment.CENTER);
// 创建一个新运行
XWPFRun run = paragraph.createRun();
// 设置运行文本
run.setText(strTitle);
// 设置运行字体
run.setFontSize(16);
run.setBold(true);
// 添加一个分页符
paragraph = document.createParagraph();
run = paragraph.createRun();
run.addBreak(BreakType.PAGE);
// 获取所有标题段落
List<XWPFParagraph> headingParagraphs = new ArrayList<XWPFParagraph>();
for (XWPFParagraph p : document.getParagraphs()) {
String text = p.getText();
if (text != null && text.length() > 0) {
int headingLevel = getHeadingLevel(p);
if (headingLevel >= nMinHeadingLevel && headingLevel <= nMaxHeadingLevel) {
headingParagraphs.add(p);
}
}
}
// 创建一个新表格
XWPFTable table = document.createTable();
// 创建表格行
XWPFTableRow row = table.getRow(0);
// 创建表格单元格
XWPFTableCell cell = row.getCell(0);
// 设置单元格文本
cell.setText(strTitle);
// 设置单元格样式
cell.setVerticalAlignment(XWPFVertAlign.CENTER);
cell.setColor("C0C0C0");
cell.setBold(true);
// 创建一个新编号
CTNumbering numbering = CTNumbering.Factory.newInstance();
// 获取所有标题段落的编号
for (XWPFParagraph p : headingParagraphs) {
int headingLevel = getHeadingLevel(p);
// 创建一个新编号项
CTAbstractNum abstractNum = numbering.addNewAbstractNum();
abstractNum.setAbstractNumId(BigInteger.valueOf(headingLevel));
// 创建一个新编号级别
CTLvl lvl = abstractNum.addNewLvl();
lvl.setIlvl(BigInteger.valueOf(headingLevel - nMinHeadingLevel));
lvl.addNewNumFmt().setVal(STNumberFormat.DECIMAL);
lvl.addNewLvlText().setVal("%" + headingLevel);
lvl.addNewStart().setVal(BigInteger.valueOf(1));
// 获取段落编号
CTNum num = numbering.addNewNum();
num.setNumId(BigInteger.valueOf(headingLevel));
num.addNewAbstractNumId().setVal(BigInteger.valueOf(headingLevel));
// 将段落编号添加到编号项
XWPFAbstractNum abs = new XWPFAbstractNum(abstractNum);
XWPFNumbering numbering1 = new XWPFNumbering(numbering);
BigInteger abstractNumID = numbering1.addAbstractNum(abs);
BigInteger numID = numbering1.addNum(abstractNumID);
// 设置段落编号
p.setNumID(numID);
}
// 遍历所有标题段落,添加目录项
for (XWPFParagraph p : headingParagraphs) {
int headingLevel = getHeadingLevel(p);
// 创建一个新段落
paragraph = document.createParagraph();
// 创建一个新运行
run = paragraph.createRun();
// 设置运行文本
run.setText(getHeadingText(p));
// 设置运行字体
run.setFontSize(12);
// 设置段落缩进
paragraph.setIndentationLeft(headingLevel * 720);
// 添加目录项
addTOCItem(paragraph, p);
}
}
/**
* 获取段落标题级别
*
* @param paragraph 段落对象
* @return 标题级别
*/
private static int getHeadingLevel(XWPFParagraph paragraph) {
String style = paragraph.getStyle();
if (style != null && style.startsWith("标题 ")) {
return Integer.parseInt(style.substring(3));
}
return -1;
}
/**
* 获取段落标题文本
*
* @param paragraph 段落对象
* @return 标题文本
*/
private static String getHeadingText(XWPFParagraph paragraph) {
String text = paragraph.getText();
if (text != null && text.length() > 0) {
int pos = text.indexOf(' ');
if (pos > 0) {
return text.substring(pos + 1);
}
}
return text;
}
/**
* 添加目录项
*
* @param paragraph 目录段落
* @param headingParagraph 标题段落
*/
private static void addTOCItem(XWPFParagraph paragraph, XWPFParagraph headingParagraph) {
// 获取段落编号
BigInteger numID = headingParagraph.getNumID();
// 获取段落编号对象
XWPFNum num = headingParagraph.getDocument().getNumbering().getNum(numID);
// 获取段落编号级别
int ilvl = num.getCTNum().getLvlOverrideArray(0).getIlvl().intValue();
// 获取段落编号文本
String numText = num.getCTNum().getLvlOverrideArray(0).getLvl().getLvlText().getVal();
// 获取段落文本
String text = getHeadingText(headingParagraph);
// 创建一个新运行
XWPFRun run = paragraph.createRun();
// 设置运行文本
run.setText(numText + " " + text);
// 设置运行字体
run.setFontSize(12);
// 设置运行样式
run.getCTR().addNewRPr().addNewNoProof();
// 创建一个新运行
run = paragraph.createRun();
// 设置运行文本
run.setText(" ");
}
}
```
阅读全文