此文参考了前人文章,链接如下
https://blog.csdn.net/lk1233691/article/details/75268200
但前辈由于持续探索与更新,没有给出一份完整代码,
且其最新一次更新(2018-06-03)中给出的代码中,
判断段落是否设置了大纲级别的代码para.getCTP().getPPr().getOutlineLvl()是有可能报空指针异常的.如果报异常,后续段落的样式以及段落的样式的基础样式是否设置了大纲级别的判断则不会被执行.
故对其进行略微改动,完整代码如下:
package run;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFStyles;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
/**
* 获取.docx文档大纲
*
* @author MrBlack
*/
public class POITest {
public static void main(String[] args) {
InputStream is = null;
try {
is = new FileInputStream("D:\\test.docx");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
XWPFDocument document = null;
try {
document = new XWPFDocument(is);
} catch (IOException e) {
e.printStackTrace();
}
List<XWPFParagraph> paragraphs = document.getParagraphs();
XWPFStyles styles = document.getStyles();
for (XWPFParagraph paragraph : paragraphs) {
// List<XWPFRun> runs = paragraph.getRuns();
// for (XWPFRun run : runs) {
// CTR ctr = run.getCTR();
// System.out.println(ctr);
// }
boolean control = false;
try {
// 判断该段落是否设置了大纲级别
control = textPrint(paragraph, paragraph.getCTP().getPPr().getOutlineLvl());
} catch (Exception e) {
e.printStackTrace();
}
if (!control) {
try {
// 判断该段落的样式是否设置了大纲级别
CTDecimalNumber number = styles.getStyle(paragraph.getStyle()).getCTStyle().getPPr()
.getOutlineLvl();
control = textPrint(paragraph, number);
} catch (Exception e) {
e.printStackTrace();
}
}
if (!control) {
try {
// 判断该段落的样式的基础样式是否设置了大纲级别
CTDecimalNumber number = styles
.getStyle(styles.getStyle(paragraph.getStyle()).getCTStyle().getBasedOn().getVal())
.getCTStyle().getPPr().getOutlineLvl();
textPrint(paragraph, number);
} catch (Exception e) {
e.printStackTrace();
}
}
}
try {
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static int num = 0;
/**
* 输出大纲,返回的布尔值用于判断内一级是否需要判断大纲
*
* @param paragraph
* @param number
* @throws IOException
*/
private static boolean textPrint(XWPFParagraph paragraph, CTDecimalNumber number) throws IOException {
String text = unescapeJava(paragraph.getParagraphText());
if (number != null && text != null && !"".equals(text)) {
StringBuffer space = new StringBuffer();
space.append(num++);
for (BigInteger i = BigInteger.ZERO; i.compareTo(number.getVal()) < 0; i = i.add(BigInteger.ONE)) {
space.append(" ");
}
space.append(text);
System.out.println(space.toString());
return true;
} else {
return false;
}
}
/**
* 去除文档中可能存在的转义符
*
* @param str
*/
public static String unescapeJava(String str) {
String dest = "";
if (str != null) {
Pattern p = Pattern.compile("\\s*|\t|\r|\n");
Matcher m = p.matcher(str);
dest = m.replaceAll("");
}
return dest;
}
}