java 使用 POI 为 word 文档自动生成书签

poi 版本:4.1.0

XML 复制代码
<properties>
	<java.version>1.8</java.version>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<maven.compiler.source>1.8</maven.compiler.source>
	<maven.compiler.target>1.8</maven.compiler.target>
	<poi.version>4.1.0</poi.version>
</properties>

<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi</artifactId>
	<version>${poi.version}</version>
	<scope>compile</scope>
	<optional>false</optional>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>${poi.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml-schemas</artifactId>
	<version>${poi.version}</version>
</dependency>

代码示例中是为类似如下所示的接口文档自动生成书签:

XML 复制代码
			人员接口文档
1.新增人员
	1.1.请求url:http://127.0.0.1/addUser
	1.2.请求方式:POST
	1.3.请求参数说明:xxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxx
	1.4.响应参数说明:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
2.删除人员
	2.1.请求url:http://127.0.0.1/removeUser
	2.2.请求方式:POST
	2.3.请求参数说明:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	2.4.响应参数说明:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
3.查看人员详情
	3.1.请求url:http://127.0.0.1/userDetail
	3.2.请求方式:POST
	3.3.请求参数说明:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
	3.4.响应参数说明:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					Xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
					xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

即读取文档的每一行内容,检测到该行文本以 "http://127.0.0.1" 开头则将其上一行设置为书签,请结合文档具体内容以及需求自行修改使用

例如原始文档如下所示:

输出文档如下所示:

java 复制代码
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.math.BigInteger;

public class WordBookmarkCreater {

    public static void main(String[] args) throws Exception {
        String inputFilePath = "D:\\xxx\\input.docx";
        String outputFilePath = "D:\\xxx\\output.docx";
        XWPFDocument doc = new XWPFDocument(new FileInputStream(inputFilePath));

        // 删除原本书签
        deleteAllBookmarks( doc );

        // 重新生成书签
        markHeadings(doc);

        // 保存文档
        FileOutputStream out = new FileOutputStream(outputFilePath);
        doc.write(out);
        out.close();
    }

    // 删除文档中的书签
    private static void deleteAllBookmarks(XWPFDocument doc) {
        // 普通段落
        for (XWPFParagraph p : doc.getParagraphs()) {
            clearBookmarks(p.getCTP());
        }

        // 表格中的段落
        for (XWPFTable table : doc.getTables()) {
            for (XWPFTableRow row : table.getRows()) {
                for (XWPFTableCell cell : row.getTableCells()) {
                    for (XWPFParagraph p : cell.getParagraphs()) {
                        clearBookmarks(p.getCTP());
                    }
                }
            }
        }
    }

    private static void clearBookmarks(CTP ctp) {
        ctp.getBookmarkStartList().clear();
        ctp.getBookmarkEndList().clear();
    }


    private static void markHeadings(XWPFDocument doc) {
        XWPFParagraph paragraph_prev = null;
        int num = 1;
        for (XWPFParagraph paragraph : doc.getParagraphs()) {
            String text = paragraph.getText();
            if( text.toLowerCase().contains( "请求" ) &&
                text.toLowerCase().contains( "url" ) &&
                text.toLowerCase().contains( "http://127.0.0.1" )){
                System.out.println( text );
                if( paragraph_prev == null ){
                    // 可选:添加书签锚点
                    addBookmark( paragraph, num + ". " + text );
                }else {
                    // 可选:添加书签锚点
                    addBookmark( paragraph_prev, num + ". " + paragraph_prev.getText() );
                }
                num++;
            }
            paragraph_prev = paragraph;
        }
    }

    private static void addBookmark(XWPFParagraph paragraph,String bookmarkName) {
        CTP ctp = paragraph.getCTP();
        CTBookmark bookmark = ctp.addNewBookmarkStart();
        bookmark.setId(BigInteger.valueOf( ctp.sizeOfBookmarkStartArray() ));
        bookmark.setName(bookmarkName);
        ctp.addNewBookmarkEnd().setId(bookmark.getId());
    }
}
相关推荐
Jiaberrr11 分钟前
uniapp 实现低功耗蓝牙连接并读写数据实战指南
java·前端·javascript·vue.js·struts·uni-app
家乡的落日13 分钟前
一、I/O的相关概念
java
码熔burning14 分钟前
【MQ篇】RabbitMQ之死信交换机!
java·分布式·rabbitmq·mq
黄雪超1 小时前
JVM——Java的基本类型的实现
java·开发语言·jvm
工业互联网专业1 小时前
基于web的可追溯果蔬生产过程的管理系统
java·vue.js·spring boot·毕业设计·源码·课程设计·可追溯果蔬生产过程的管理系统
程序猿大波2 小时前
基于Java,SpringBoot,HTML水文水质监测预警系统设计
java·开发语言·spring boot
海鸥813 小时前
在K8S迁移节点kubelet数据存储目录
java·kubernetes·kubelet
jackson凌3 小时前
【Java学习笔记】递归
java·笔记·学习
鑫—萍3 小时前
C++——入门基础(2)
java·开发语言·jvm·数据结构·c++·算法