如下图的word目录大纲该怎么获取呢?

试过用jacob方式确实可以直接读取到大纲的编号,但是jacob不支持在linux上的调用(不确定反正网络上都说不支持,自己目前没有找到可以解决linux如何调用的问题),没办法只好使用poi硬编码实现了一把,目前只支持读取4个层级以内的大纲(大纲的编号,就是1.、1.1.、…这些编号必须是word自动生成的不是手动写上去的,这是规范),基本原理是读取大纲的标题级别根据大纲标题级别来构造层级关系。
话不多说上才艺:

maven依赖

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.2</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>4.1.2</version></dependency>

ReadWordTest.java

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;import java.io.File;
import java.io.FileInputStream;
import java.util.*;public class ReadWordTest {/*** Word中的大纲级别,可以通过getPPr().getOutlineLvl()直接提取,但需要注意,Word中段落级别,通过如下三种方式定义:* 1、直接对段落进行定义;* 2、对段落的样式进行定义;* 3、对段落样式的基础样式进行定义。* 因此,在通过“getPPr().getOutlineLvl()”提取时,需要依次在如上三处读取。** @param doc* @param para* @return*/private static String getTitleLvl(XWPFDocument doc, XWPFParagraph para) {String titleLvl = "";try {//判断该段落是否设置了大纲级别if (para.getCTP().getPPr().getOutlineLvl() != null) {return String.valueOf(para.getCTP().getPPr().getOutlineLvl().getVal());}} catch (Exception e) {}try {//判断该段落的样式是否设置了大纲级别if (doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl() != null) {return String.valueOf(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getPPr().getOutlineLvl().getVal());}} catch (Exception e) {}try {//判断该段落的样式的基础样式是否设置了大纲级别if (doc.getStyles().getStyle(doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal()).getCTStyle().getPPr().getOutlineLvl() != null) {String styleName = doc.getStyles().getStyle(para.getStyle()).getCTStyle().getBasedOn().getVal();return String.valueOf(doc.getStyles().getStyle(styleName).getCTStyle().getPPr().getOutlineLvl().getVal());}} catch (Exception e) {}try {if (para.getStyleID() != null) {return para.getStyleID();}} catch (Exception e) {}return titleLvl;}public static void main(String[] args) throws Exception {File file = new File("C:\\Users\\lenovo\\Desktop\\test5.docx");FileInputStream fis = new FileInputStream(file);XWPFDocument xdoc = new XWPFDocument(fis);List<XWPFParagraph> paragraphs = xdoc.getParagraphs();List<ReadDto> readDtos = new ArrayList<>();for (XWPFParagraph paragraph : paragraphs) {String text = paragraph.getText();String titleLvl = getTitleLvl(xdoc, paragraph);if (StringUtils.isNotEmpty(titleLvl)) {int level = Integer.valueOf(titleLvl);
//                System.out.println("text: " + text + ", titleLvl: " + titleLvl);ReadDto readDto = new ReadDto();readDto.setText(text);readDto.setTitleLevel(level);readDtos.add(readDto);}}int zeroCount = 0;//0出现的次数int oneCount = 0;//1出现的次数int twoCount = 0;//2出现的次数int threeCount = 0;//3出现的次数int curPoint = 0;//当前指针值for (int i = 0; i < readDtos.size(); i++) {int curLevel = readDtos.get(i).getTitleLevel();if (curLevel > 4) {throw new RuntimeException("暂不支持目录层级超过4层!!!");}if (curPoint == 0) {zeroCount++;curPoint = 1;readDtos.get(i).setPrefix(zeroCount + ".");} else if (curPoint == 1) {if (curLevel == 0) {zeroCount++;oneCount = 0;twoCount = 0;threeCount = 0;curPoint = 1;readDtos.get(i).setPrefix(zeroCount + ".");}if (curLevel == 1) {curPoint++;oneCount++;readDtos.get(i).setPrefix(zeroCount + "." + "1.");}} else if (curPoint == 2) {if (curLevel == 0) {zeroCount++;oneCount = 0;twoCount = 0;threeCount = 0;curPoint = 1;readDtos.get(i).setPrefix(zeroCount + ".");} else if (curLevel == 1) {oneCount++;twoCount = 0;curPoint = 2;readDtos.get(i).setPrefix(zeroCount + "." + oneCount + ".");} else if (curLevel == 2) {curPoint = 3;twoCount++;threeCount = 0;readDtos.get(i).setPrefix(zeroCount + "." + oneCount + "." + twoCount + ".");}} else if (curPoint == 3) {if (curLevel == 0) {zeroCount++;oneCount = 0;twoCount = 0;threeCount = 0;curPoint = 1;readDtos.get(i).setPrefix(zeroCount + ".");} else if (curLevel == 1) {oneCount++;curPoint = 2;twoCount = 0;readDtos.get(i).setPrefix(zeroCount + "." + oneCount + ".");} else if (curLevel == 2) {curPoint = 3;twoCount++;threeCount = 0;readDtos.get(i).setPrefix(zeroCount + "." + oneCount + "." + twoCount + ".");} else if (curLevel == 3) {threeCount++;if (i < readDtos.size() - 1) {int nextLevel = readDtos.get(i + 1).getTitleLevel();if (nextLevel > 3) {throw new RuntimeException("暂不支持目录层级超过4层!!!");}if (nextLevel == 3) {curPoint = 3;} else if (nextLevel < 3) {curPoint = nextLevel + 1;}}readDtos.get(i).setPrefix(zeroCount + "." + oneCount + "." + twoCount + "." + threeCount + ".");}}}for (ReadDto dto : readDtos) {System.out.println("text:" + dto.getPrefix() + dto.getText() + ",level:" + dto.getTitleLevel());}}
}

ReadDto.java

public class ReadDto {private String prefix;private String text;private int titleLevel;public String getPrefix() {return prefix;}public void setPrefix(String prefix) {this.prefix = prefix;}public String getText() {return text;}public void setText(String text) {this.text = text;}public int getTitleLevel() {return titleLevel;}public void setTitleLevel(int titleLevel) {this.titleLevel = titleLevel;}
}

输出如下:

text:1.第一章,level:0
text:1.1.模块一,level:1
text:1.1.1.顶顶顶顶,level:2
text:1.2.模块二,level:1
text:1.2.1.功能一,level:2
text:1.2.2.功能二,level:2
text:1.3.模块三,level:1
text:1.3.1.功能一,level:2
text:2.第二章,level:0
text:2.1.模块一一,level:1
text:2.2.模块二二,level:1

目前的实现写的比较丑陋,后续有空看能不能实现一个优雅点且不限制层级的吧>_<

poi方式读取word目录大纲相关推荐

  1. java读取word文档的复杂表格_poi读取word表格 java POI 如何读取word的表格中的表格...

    poi 操作word 2007 (如何删除word中的某一个表格)小编忘了哪年哪月的哪日小编在哪面墙上刻下张脸张微笑着忧伤着凝望小编的脸. public static void changeTable ...

  2. Java:POI方式实现Word转html/htm

    2019独角兽企业重金招聘Python工程师标准>>> 这里就不对POI做过多的说明了,贴个官网 https://poi.apache.org/,随意看看. 首先搞清楚下要将doc/ ...

  3. java poi方式读取Excel的图片

    POM ​​​​ <!-- poi --> <dependency><groupId>cn.afterturn</groupId><artifac ...

  4. POI XWPFDocument 导出word目录详解

    完整代码,代码为main方法直接运行,该代码实现了对目录样式,布局,标题,位置的修改,但是无法自动获取页码,只可以手动添加目录中对应的页码,或者设置为空.下方资源运行环境: Windows10 JDK ...

  5. POI方式替换Word中的文字

    开发当中,很多时候我们会需要将我们的数据写入到Word当中,或者说导出.这时候我们会使用一些特定的标识来达到我们替换内容的目的.在Word中定义好我们需要替换的内容,也就是模板.然后再写入数据.源码如 ...

  6. 使用POI读取word文档

    使用POI 读取word 文档(word 2003和2007) 最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2 ...

  7. POI 读取word (word 2003 和 word 2007

    最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 9 ...

  8. POI 读取word (word 2003 和 word 2007)

    最近在给客户做系统的时候,用户提出需求,要能够导入 word 文件,现在 microsoft word 有好几个版本 97.2003.2007的,这三个版本存储数据的格式上都有相当大的差别,而现在 9 ...

  9. java poi word换行符_poi读取word的换行符问题

    用Java的Poi插件读取word内容,类如下: package com.tw.word; import org.apache.poi.hwpf.HWPFDocument; import org.ap ...

最新文章

  1. java-分支重载以及构造方法
  2. 怎样学好python-零基础如何学好Python?
  3. windows 批处理bat,设置定时关机
  4. P4288 [SHOI2014]信号增幅仪 最小圆覆盖
  5. 64位进程调用32位dll的解决方法
  6. Servlet实现文件上传
  7. python 相关性检验怎么计算p值_生信工具 | 相关性热图还能玩出什么花样?
  8. 门槛,才是做生意持久盈利的基础
  9. AcWing 840. 模拟散列表(散列hash)
  10. 根据IP获取对应国家
  11. 验证集与测试集的区别
  12. 数学建模中各种评价类模型的优点和缺点总结
  13. [Xcelsius]BI展现工具之Xcelsius
  14. 教你一招,免费拆分pdf
  15. 【QT-QSS】QSS介绍
  16. python弹球游戏移动球拍_pygame库实现移动底座弹球小游戏
  17. Domain or host
  18. 英语四六级及考研语法(学习方法)
  19. CentOS7开启自定义热点HotSpot
  20. 为何优秀的程序员不断离开?,中高级Java面试中你不得不会的知识点

热门文章

  1. webrtc 使用了aec_使用适用于AEC的PiXYZ插件更快地设计,构建和运行
  2. 机器学习三剑客之Matplotlab
  3. 2020年中国IT咨询行业市场现状及发展趋势
  4. postgresql: pg_ctl -D data start 出现 postgres aaaaaaaaaaaaaaaaaaaaaaaaa C:/Users/huang zhen yang/dat
  5. MATLAB机器学习进阶
  6. kotlin中mainactivity无法直接调用xml中的控件_个推TechDay广州站:使用Kotlin演进安卓开发生态...
  7. 三国杀开源系列之三106@365
  8. mono android单选按钮,CLEngine
  9. b-tree和b+tree以及mysql为什么使用了b+树
  10. jsp开源网址导航-IT库网址导航源码下载-仿2345部分导航